Merge branch 'sh/postgresql-writer'
authorFlorian Forster <octo@collectd.org>
Sat, 17 Nov 2012 08:39:33 +0000 (09:39 +0100)
committerFlorian Forster <octo@collectd.org>
Sat, 17 Nov 2012 08:39:33 +0000 (09:39 +0100)
Conflicts:
src/collectd.conf.pod
src/postgresql.c

1  2 
src/collectd.conf.pod
src/postgresql.c

@@@ -3838,23 -3674,84 +3856,101 @@@ This query collects the on-disk size o
  
  =back
  
 +In addition, the following detailed queries are available by default. Please
 +note that each of those queries collects information B<by table>, thus,
 +potentially producing B<a lot> of data. For details see the description of the
 +non-by_table queries above.
 +
 +=over 4
 +
 +=item B<queries_by_table>
 +
 +=item B<query_plans_by_table>
 +
 +=item B<table_states_by_table>
 +
 +=item B<disk_io_by_table>
 +
 +=back
 +
+ The B<Writer> block defines a PostgreSQL writer backend. It accepts a single
+ mandatory argument specifying the name of the writer. This will then be used
+ in the B<Database> specification in order to activate the writer instance. The
+ names of all writers have to be unique. The following options may be
+ specified:
+ =over 4
+ =item B<Statement> I<sql statement>
+ This mandatory option specifies the SQL statement that will be executed for
+ each submitted value. A single SQL statement is allowed only. Anything after
+ the first semicolon will be ignored.
+ Nine parameters will be passed to the statement and should be specified as
+ tokens B<$1>, B<$2>, through B<$9> in the statement string. The following
+ values are made available through those parameters:
+ =over 4
+ =item B<$1>
+ The timestamp of the queried value as a floating point number.
+ =item B<$2>
+ The hostname of the queried value.
+ =item B<$3>
+ The plugin name of the queried value.
+ =item B<$4>
+ The plugin instance of the queried value. This value may be B<NULL> if there
+ is no plugin instance.
+ =item B<$5>
+ The type of the queried value (cf. L<types.db(5)>).
+ =item B<$6>
+ The type instance of the queried value. This value may be B<NULL> if there is
+ no type instance.
+ =item B<$7>
+ An array of names for the submitted values (i.E<nbsp>e., the name of the data
+ sources of the submitted value-list).
+ =item B<$8>
+ An array of types for the submitted values (i.E<nbsp>e., the type of the data
+ sources of the submitted value-list; C<counter>, C<gauge>, ...). Note, that if
+ B<StoreRates> is enabled (which is the default, see below), all types will be
+ C<gauge>.
+ =item B<$9>
+ An array of the submitted values. The dimensions of the value name and value
+ arrays match.
+ =back
+ In general, it is advisable to create and call a custom function in the
+ PostgreSQL database for this purpose. Any procedural language supported by
+ PostgreSQL will do (see chapter "Server Programming" in the PostgreSQL manual
+ for details).
+ =item B<StoreRates> B<false>|B<true>
+ If set to B<true> (the default), convert counter values to rates. If set to
+ B<false> counter values are stored as is, i.E<nbsp>e. as an increasing integer
+ number.
+ =back
  The B<Database> block defines one PostgreSQL database for which to collect
  statistics. It accepts a single mandatory argument which specifies the
  database name. None of the other options are required. PostgreSQL will use
@@@ -500,10 -602,14 +615,15 @@@ static int c_psql_read (user_data_t *ud
        db = ud->data;
  
        assert (NULL != db->database);
 +      assert (NULL != db->instance);
+       assert (NULL != db->queries);
+       pthread_mutex_lock (&db->db_lock);
  
-       if (0 != c_psql_check_connection (db))
+       if (0 != c_psql_check_connection (db)) {
+               pthread_mutex_unlock (&db->db_lock);
                return -1;
+       }
  
        for (i = 0; i < db->queries_num; ++i)
        {
@@@ -683,13 -1247,36 +1265,36 @@@ static int c_psql_config_database (ocon
        ud.data = db;
        ud.free_func = c_psql_database_delete;
  
 -      ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->database);
 +      ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->instance);
  
-       CDTIME_T_TO_TIMESPEC (db->interval, &cb_interval);
+       if (db->queries_num > 0) {
+               CDTIME_T_TO_TIMESPEC (db->interval, &cb_interval);
  
-       plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
-                       /* interval = */ (db->interval > 0) ? &cb_interval : NULL,
-                       &ud);
+               ++db->ref_cnt;
+               plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
+                               /* interval = */ (db->interval > 0) ? &cb_interval : NULL,
+                               &ud);
+       }
+       if (db->writers_num > 0) {
+               ++db->ref_cnt;
+               plugin_register_write (cb_name, c_psql_write, &ud);
+               if (! have_flush) {
+                       /* flush all */
+                       plugin_register_flush ("postgresql",
+                                       c_psql_flush, /* user data = */ NULL);
+                       have_flush = 1;
+               }
+               /* flush this connection only */
+               ++db->ref_cnt;
+               plugin_register_flush (cb_name, c_psql_flush, &ud);
+       }
+       else if (db->commit_interval > 0) {
+               log_warn ("Database '%s': You do not have any writers assigned to "
+                               "this database connection. Setting 'CommitInterval' does "
+                               "not have any effect.", db->database);
+       }
        return 0;
  } /* c_psql_config_database */