From: Florian Forster Date: Fri, 29 Sep 2017 14:24:47 +0000 (+0200) Subject: Merge branch 'pr/2454' X-Git-Tag: collectd-5.8.0~62 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=da9559cff40c0c7e1f0a7b309487eb133cb2b0a8;hp=c0e8b0392fed8ee776db4942af52be4d4b83069d Merge branch 'pr/2454' --- diff --git a/contrib/curl_json/php-fpm.conf b/contrib/curl_json/php-fpm.conf new file mode 100644 index 00000000..34b8b67d --- /dev/null +++ b/contrib/curl_json/php-fpm.conf @@ -0,0 +1,27 @@ +# Example configuration for PHP-FPM + + + Plugin "phpfpm" + Instance "main" + + Type "total_requests" + Instance "accepted" + + + Type "total_requests" + Instance "slow" + + + Type "queue_length" + Instance "listen" + + + Type "vs_processes" + Instance "active" + + + Type "vs_processes" + Instance "total" + + + diff --git a/contrib/redhat/collectd.spec b/contrib/redhat/collectd.spec index 23cac9a0..b21c7a21 100644 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@ -16,7 +16,7 @@ # # - fetch the desired collectd release file from https://collectd.org/files/ # and save it in your ~/rpmbuild/SOURCES/ directory (or build your own out of -# the git repository: ./build.sh && ./configure && make-dist-bz2) +# the git repository: ./build.sh && ./configure && make dist-bzip2) # # - copy this file in your ~/rpmbuild/SPECS/ directory. Make sure the # "Version:" tag matches the version from the tarball. diff --git a/src/collectd.conf.in b/src/collectd.conf.in index c2b3598e..655910d9 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -495,6 +495,7 @@ # # # +# #Plugin "mycompany" # Driver "mysql" # DriverOption "host" "localhost" # DriverOption "username" "collectd" @@ -1045,6 +1046,7 @@ # # # +# #Plugin "warehouse" # ConnectID "db01" # Username "oracle" # Password "secret" @@ -1131,6 +1133,7 @@ # StoreRates true # # +# #Plugin "kingdom" # Host "hostname" # Port "5432" # User "username" diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index b392baa3..44ecd361 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -1624,6 +1624,7 @@ finance page and dispatch the value to collectd. + Plugin "quotes" URL "http://finance.google.com/finance?q=NYSE%3AAMD" User "foo" Password "bar" @@ -1655,6 +1656,11 @@ The following options are valid within B blocks: =over 4 +=item B I + +Use I as the plugin name when submitting values. +Defaults to C. + =item B I URL of the web site to retrieve. Since a regular expression will be used to @@ -1815,6 +1821,11 @@ The following options are valid within B blocks: Use I as the host name when submitting values. Defaults to the global host name setting. +=item B I + +Use I as the plugin name when submitting values. +Defaults to C. + =item B I Sets the plugin instance to I. @@ -2030,6 +2041,7 @@ than those of other plugins. It usually looks something like this: + #Plugin "warehouse" Driver "mysql" Interval 120 DriverOption "host" "localhost" @@ -2211,6 +2223,11 @@ the daemon. Other than that, that name is not used. =over 4 +=item B I + +Use I as the plugin name when submitting query results from +this B. Defaults to C. + =item B I Sets the interval (in seconds) in which the values will be collected from this @@ -3673,6 +3690,7 @@ Synopsis of the configuration: Server "localhost" Key "page_key" + Plugin "plugin_name" Regex "(\\d+) bytes sent" DSType CounterAdd @@ -3700,6 +3718,11 @@ B block. When connected to the memcached server, asks for the page I. +=item B I + +Use I as the plugin name when submitting values. +Defaults to C. + =item EBE Match blocks define which strings to look for and how matches substrings are @@ -5748,6 +5771,7 @@ plugin's documentation above for details. + #Plugin "warehouse" ConnectID "db01" Username "oracle" Password "secret" @@ -5770,6 +5794,11 @@ values submitted to the daemon. Other than that, that name is not used. =over 4 +=item B I + +Use I as the plugin name when submitting query results from +this B. Defaults to C. + =item B I Defines the "database alias" or "service name" to connect to. Usually, these @@ -5825,7 +5854,7 @@ The address of the OVS DB server JSON-RPC interface used by the plugin. To enable the interface, OVS DB daemon should be running with C<--remote=ptcp:> option. See L for more details. The option may be either network hostname, IPv4 numbers-and-dots notation or IPv6 hexadecimal string -format. Defaults to B<'localhost'>. +format. Defaults to C. =item B I @@ -5891,7 +5920,7 @@ The address of the OVS DB server JSON-RPC interface used by the plugin. To enable the interface, OVS DB daemon should be running with C<--remote=ptcp:> option. See L for more details. The option may be either network hostname, IPv4 numbers-and-dots notation or IPv6 hexadecimal string -format. Defaults to B<'localhost'>. +format. Defaults to C. =item B I @@ -6123,6 +6152,7 @@ L. + Plugin "kingdom" Host "hostname" Port "5432" User "username" @@ -6444,6 +6474,11 @@ activating this option. The draw-back is, that data covering the specified amount of time will be lost, for example, if a single statement within the transaction fails or if the database server crashes. +=item B I + +Use I as the plugin name when submitting query results from +this B. Defaults to C. + =item B I Specify the plugin instance name that should be used instead of the database @@ -7710,6 +7745,7 @@ user using (extended) regular expressions, as described in L. + Plugin "mail" Instance "exim" Interval 60 @@ -7742,11 +7778,13 @@ The config consists of one or more B blocks, each of which configures one logfile to parse. Within each B block, there are one or more B blocks, which configure a regular expression to search for. -The B option in the B block may be used to set the plugin -instance. So in the above example the plugin name C would be used. -This plugin instance is for all B blocks that B it, until the -next B option. This way you can extract several plugin instances from -one logfile, handy when parsing syslog and the like. +The B and B options in the B block may be used to set +the plugin name and instance respectively. So in the above example the plugin name +C would be used. + +These options are applied for all B blocks that B it, until the +next B or B option. This way you can extract several plugin +instances from one logfile, handy when parsing syslog and the like. The B option allows you to define the length of time between reads. If this is not set, the default Interval will be used. @@ -7934,7 +7972,8 @@ B Index 1 - Instance "snort-eth0" + Plugin "snortstats" + Instance "eth0" Interval 600 Collect "snort-dropped" @@ -7986,6 +8025,11 @@ I block but there can be multiple if you have multiple CSV files. =over 4 +=item B I + +Use I as the plugin name when submitting values. +Defaults to C. + =item B I Sets the I used when dispatching the values. @@ -9330,6 +9374,7 @@ Synopsis: Prefix "collectd/" Database 1 MaxSetSize -1 + MaxSetDuration -1 StoreRates true @@ -9392,6 +9437,12 @@ to C<0>. The B option limits the number of items that the I can hold. Negative values for I sets no limit, which is the default behavior. +=item B I + +The B option limits the duration of items that the +I can hold. Negative values for I sets no duration, which +is the default behavior. + =item B B|B If set to B (the default), convert counter values to rates. If set to diff --git a/src/curl.c b/src/curl.c index 288c974e..35ec1f83 100644 --- a/src/curl.c +++ b/src/curl.c @@ -53,6 +53,7 @@ struct web_page_s; typedef struct web_page_s web_page_t; struct web_page_s /* {{{ */ { + char *plugin_name; char *instance; char *url; @@ -146,6 +147,7 @@ static void cc_web_page_free(web_page_t *wp) /* {{{ */ curl_easy_cleanup(wp->curl); wp->curl = NULL; + sfree(wp->plugin_name); sfree(wp->instance); sfree(wp->url); @@ -412,6 +414,7 @@ static int cc_config_add_page(oconfig_item_t *ci) /* {{{ */ ERROR("curl plugin: calloc failed."); return -1; } + page->plugin_name = NULL; page->url = NULL; page->user = NULL; page->pass = NULL; @@ -435,7 +438,9 @@ static int cc_config_add_page(oconfig_item_t *ci) /* {{{ */ for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp("URL", child->key) == 0) + if (strcasecmp("Plugin", child->key) == 0) + status = cf_util_get_string(child, &page->plugin_name); + else if (strcasecmp("URL", child->key) == 0) status = cf_util_get_string(child, &page->url); else if (strcasecmp("User", child->key) == 0) status = cf_util_get_string(child, &page->user); @@ -566,7 +571,8 @@ static void cc_submit(const web_page_t *wp, const web_match_t *wm, /* {{{ */ vl.values = &value; vl.values_len = 1; - sstrncpy(vl.plugin, "curl", sizeof(vl.plugin)); + sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "curl", + sizeof(vl.plugin)); sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, wm->type, sizeof(vl.type)); if (wm->instance != NULL) @@ -581,7 +587,8 @@ static void cc_submit_response_code(const web_page_t *wp, long code) /* {{{ */ vl.values = &(value_t){.gauge = (gauge_t)code}; vl.values_len = 1; - sstrncpy(vl.plugin, "curl", sizeof(vl.plugin)); + sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "curl", + sizeof(vl.plugin)); sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, "response_code", sizeof(vl.type)); @@ -594,7 +601,8 @@ static void cc_submit_response_time(const web_page_t *wp, /* {{{ */ vl.values = &(value_t){.gauge = response_time}; vl.values_len = 1; - sstrncpy(vl.plugin, "curl", sizeof(vl.plugin)); + sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "curl", + sizeof(vl.plugin)); sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, "response_time", sizeof(vl.type)); diff --git a/src/curl_json.c b/src/curl_json.c index 35b11c02..756f24f3 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -82,6 +82,7 @@ typedef struct { struct cj_s /* {{{ */ { char *instance; + char *plugin_name; char *host; char *sock; @@ -396,6 +397,7 @@ static void cj_free(void *arg) /* {{{ */ db->tree = NULL; sfree(db->instance); + sfree(db->plugin_name); sfree(db->host); sfree(db->sock); @@ -672,6 +674,8 @@ static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */ if (strcasecmp("Instance", child->key) == 0) status = cf_util_get_string(child, &db->instance); + else if (strcasecmp("Plugin", child->key) == 0) + status = cf_util_get_string(child, &db->plugin_name); else if (strcasecmp("Host", child->key) == 0) status = cf_util_get_string(child, &db->host); else if (db->url && strcasecmp("User", child->key) == 0) @@ -805,7 +809,8 @@ static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */ sstrncpy(vl.type_instance, key->instance, sizeof(vl.type_instance)); sstrncpy(vl.host, cj_host(db), sizeof(vl.host)); - sstrncpy(vl.plugin, "curl_json", sizeof(vl.plugin)); + sstrncpy(vl.plugin, (db->plugin_name != NULL) ? db->plugin_name : "curl_json", + sizeof(vl.plugin)); sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, key->type, sizeof(vl.type)); diff --git a/src/dbi.c b/src/dbi.c index a577aefc..62ef1dc4 100644 --- a/src/dbi.c +++ b/src/dbi.c @@ -62,6 +62,7 @@ struct cdbi_database_s /* {{{ */ { char *name; char *select_db; + char *plugin_name; cdtime_t interval; @@ -172,7 +173,10 @@ static void cdbi_database_free(cdbi_database_t *db) /* {{{ */ return; sfree(db->name); + sfree(db->select_db); + sfree(db->plugin_name); sfree(db->driver); + sfree(db->host); for (size_t i = 0; i < db->driver_options_num; i++) { sfree(db->driver_options[i].key); @@ -184,7 +188,10 @@ static void cdbi_database_free(cdbi_database_t *db) /* {{{ */ if (db->q_prep_areas) for (size_t i = 0; i < db->queries_num; ++i) udb_query_delete_preparation_area(db->q_prep_areas[i]); - free(db->q_prep_areas); + sfree(db->q_prep_areas); + /* N.B.: db->queries references objects "owned" by the global queries + * variable. Free the array here, but not the content. */ + sfree(db->queries); sfree(db); } /* }}} void cdbi_database_free */ @@ -298,6 +305,8 @@ static int cdbi_config_add_database(oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string(child, &db->host); else if (strcasecmp("Interval", child->key) == 0) status = cf_util_get_cdtime(child, &db->interval); + else if (strcasecmp("Plugin", child->key) == 0) + status = cf_util_get_string(child, &db->plugin_name); else { WARNING("dbi plugin: Option `%s' not allowed here.", child->key); status = -1; @@ -540,7 +549,8 @@ static int cdbi_read_database_query(cdbi_database_t *db, /* {{{ */ udb_query_prepare_result( q, prep_area, (db->host ? db->host : hostname_g), - /* plugin = */ "dbi", db->name, column_names, column_num, + /* plugin = */ (db->plugin_name != NULL) ? db->plugin_name : "dbi", + db->name, column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0); /* 0 = error; 1 = success; */ diff --git a/src/email.c b/src/email.c index e5f015b2..00e7413d 100644 --- a/src/email.c +++ b/src/email.c @@ -402,9 +402,15 @@ static void *open_connection(void __attribute__((unused)) * arg) { { struct group sg; struct group *grp; - char grbuf[4096]; int status; + long int grbuf_size = sysconf(_SC_GETGR_R_SIZE_MAX); + if (grbuf_size <= 0) + grbuf_size = sysconf(_SC_PAGESIZE); + if (grbuf_size <= 0) + grbuf_size = 4096; + char grbuf[grbuf_size]; + grp = NULL; status = getgrnam_r(group, &sg, grbuf, sizeof(grbuf), &grp); if (status != 0) { diff --git a/src/exec.c b/src/exec.c index 22da3160..a9f7be5c 100644 --- a/src/exec.c +++ b/src/exec.c @@ -368,11 +368,17 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, struct passwd *sp_ptr; struct passwd sp; - char nambuf[4096]; if (pl->pid != 0) return -1; + long int nambuf_size = sysconf(_SC_GETPW_R_SIZE_MAX); + if (nambuf_size <= 0) + nambuf_size = sysconf(_SC_PAGESIZE); + if (nambuf_size <= 0) + nambuf_size = 4096; + char nambuf[nambuf_size]; + if ((create_pipe(fd_pipe_in) == -1) || (create_pipe(fd_pipe_out) == -1) || (create_pipe(fd_pipe_err) == -1)) goto failed; @@ -405,7 +411,14 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, struct group *gr_ptr = NULL; struct group gr; - status = getgrnam_r(pl->group, &gr, nambuf, sizeof(nambuf), &gr_ptr); + long int grbuf_size = sysconf(_SC_GETGR_R_SIZE_MAX); + if (grbuf_size <= 0) + grbuf_size = sysconf(_SC_PAGESIZE); + if (grbuf_size <= 0) + grbuf_size = 4096; + char grbuf[grbuf_size]; + + status = getgrnam_r(pl->group, &gr, grbuf, sizeof(grbuf), &gr_ptr); if (status != 0) { ERROR("exec plugin: Failed to get group information " "for group ``%s'': %s", diff --git a/src/memcachec.c b/src/memcachec.c index c2147fd5..bd088ecd 100644 --- a/src/memcachec.c +++ b/src/memcachec.c @@ -51,6 +51,7 @@ struct web_page_s; typedef struct web_page_s web_page_t; struct web_page_s /* {{{ */ { + char *plugin_name; char *instance; char *server; @@ -94,6 +95,7 @@ static void cmc_web_page_free(web_page_t *wp) /* {{{ */ memcached_free(wp->memc); wp->memc = NULL; + sfree(wp->plugin_name); sfree(wp->instance); sfree(wp->server); sfree(wp->key); @@ -302,6 +304,8 @@ static int cmc_config_add_page(oconfig_item_t *ci) /* {{{ */ status = cmc_config_add_string("Server", &page->server, child); else if (strcasecmp("Key", child->key) == 0) status = cmc_config_add_string("Key", &page->key, child); + else if (strcasecmp("Plugin", child->key) == 0) + status = cmc_config_add_string("Plugin", &page->plugin_name, child); else if (strcasecmp("Match", child->key) == 0) /* Be liberal with failing matches => don't set `status'. */ cmc_config_add_match(page, child); @@ -407,7 +411,8 @@ static void cmc_submit(const web_page_t *wp, const web_match_t *wm, /* {{{ */ vl.values = &value; vl.values_len = 1; - sstrncpy(vl.plugin, "memcachec", sizeof(vl.plugin)); + sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "memcachec", + sizeof (vl.plugin)); sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, wm->type, sizeof(vl.type)); sstrncpy(vl.type_instance, wm->instance, sizeof(vl.type_instance)); diff --git a/src/oracle.c b/src/oracle.c index 44bd5648..099013e3 100644 --- a/src/oracle.c +++ b/src/oracle.c @@ -62,6 +62,7 @@ struct o_database_s { char *connect_id; char *username; char *password; + char *plugin_name; udb_query_preparation_area_t **q_prep_areas; udb_query_t **queries; @@ -141,6 +142,7 @@ static void o_database_free(o_database_t *db) /* {{{ */ sfree(db->username); sfree(db->password); sfree(db->queries); + sfree(db->plugin_name); if (db->q_prep_areas != NULL) for (size_t i = 0; i < db->queries_num; ++i) @@ -192,6 +194,7 @@ static int o_config_add_database(oconfig_item_t *ci) /* {{{ */ db->connect_id = NULL; db->username = NULL; db->password = NULL; + db->plugin_name = NULL; status = cf_util_get_string(ci, &db->name); if (status != 0) { @@ -211,6 +214,8 @@ static int o_config_add_database(oconfig_item_t *ci) /* {{{ */ status = cf_util_get_string(child, &db->username); else if (strcasecmp("Password", child->key) == 0) status = cf_util_get_string(child, &db->password); + else if (strcasecmp("Plugin", child->key) == 0) + status = cf_util_get_string(child, &db->plugin_name); else if (strcasecmp("Query", child->key) == 0) status = udb_query_pick_from_list(child, queries, queries_num, &db->queries, &db->queries_num); @@ -544,7 +549,8 @@ static int o_read_database_query(o_database_t *db, /* {{{ */ status = udb_query_prepare_result( q, prep_area, (db->host != NULL) ? db->host : hostname_g, - /* plugin = */ "oracle", db->name, column_names, column_num, + /* plugin = */ (db->plugin_name != NULL) ? db->plugin_name : "oracle", + db->name, column_names, column_num, /* interval = */ 0); if (status != 0) { ERROR("oracle plugin: o_read_database_query (%s, %s): " diff --git a/src/postgresql.c b/src/postgresql.c index 56730b47..3b702aee 100644 --- a/src/postgresql.c +++ b/src/postgresql.c @@ -139,6 +139,7 @@ typedef struct { char *password; char *instance; + char *plugin_name; char *sslmode; @@ -250,6 +251,8 @@ static c_psql_database_t *c_psql_database_new(const char *name) { db->instance = sstrdup(name); + db->plugin_name = NULL; + db->sslmode = NULL; db->krbsrvname = NULL; @@ -300,6 +303,8 @@ static void c_psql_database_delete(void *data) { sfree(db->instance); + sfree(db->plugin_name); + sfree(db->sslmode); sfree(db->krbsrvname); @@ -539,9 +544,11 @@ static int c_psql_exec_query(c_psql_database_t *db, udb_query_t *q, else host = db->host; - status = - udb_query_prepare_result(q, prep_area, host, "postgresql", db->instance, - column_names, (size_t)column_num, db->interval); + status = udb_query_prepare_result( + q, prep_area, host, + (db->plugin_name != NULL) ? db->plugin_name : "postgresql", + db->instance, column_names, (size_t)column_num, db->interval); + if (0 != status) { log_err("udb_query_prepare_result failed with status %i.", status); BAIL_OUT(-1); @@ -1139,6 +1146,8 @@ static int c_psql_config_database(oconfig_item_t *ci) { cf_util_get_string(c, &db->password); else if (0 == strcasecmp(c->key, "Instance")) cf_util_get_string(c, &db->instance); + else if (0 == strcasecmp (c->key, "Plugin")) + cf_util_get_string (c, &db->plugin_name); else if (0 == strcasecmp(c->key, "SSLMode")) cf_util_get_string(c, &db->sslmode); else if (0 == strcasecmp(c->key, "KRBSrvName")) diff --git a/src/snmp.c b/src/snmp.c index aa3c9dda..1ac65c8e 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -1327,8 +1327,6 @@ static int csnmp_read_table(host_definition_t *host, data_definition_t *data) { status = 0; while (status == 0) { - int oid_list_todo_num; - req = snmp_pdu_create(SNMP_MSG_GETNEXT); if (req == NULL) { ERROR("snmp plugin: snmp_pdu_create failed."); @@ -1336,24 +1334,33 @@ static int csnmp_read_table(host_definition_t *host, data_definition_t *data) { break; } - oid_list_todo_num = 0; + size_t oid_list_todo_num = 0; + size_t var_idx[oid_list_len]; + memset(var_idx, 0, sizeof(var_idx)); + for (i = 0; i < oid_list_len; i++) { /* Do not rerequest already finished OIDs */ if (!oid_list_todo[i]) continue; - oid_list_todo_num++; snmp_add_null_var(req, oid_list[i].oid, oid_list[i].oid_len); + var_idx[oid_list_todo_num] = i; + oid_list_todo_num++; } if (oid_list_todo_num == 0) { /* The request is still empty - so we are finished */ DEBUG("snmp plugin: all variables have left their subtree"); + snmp_free_pdu(req); status = 0; break; } res = NULL; status = snmp_sess_synch_response(host->sess_handle, req, &res); + + /* snmp_sess_synch_response always frees our req PDU */ + req = NULL; + if ((status != STAT_SUCCESS) || (res == NULL)) { char *errstr = NULL; @@ -1367,8 +1374,6 @@ static int csnmp_read_table(host_definition_t *host, data_definition_t *data) { snmp_free_pdu(res); res = NULL; - /* snmp_synch_response already freed our PDU */ - req = NULL; sfree(errstr); csnmp_host_close_session(host); @@ -1388,6 +1393,39 @@ static int csnmp_read_table(host_definition_t *host, data_definition_t *data) { break; } + if (res->errstat != SNMP_ERR_NOERROR) { + if (res->errindex != 0) { + /* Find the OID which caused error */ + for (i = 1, vb = res->variables; vb != NULL && i != res->errindex; + vb = vb->next_variable, i++) + /* do nothing */; + } + + if ((res->errindex == 0) || (vb == NULL)) { + ERROR("snmp plugin: host %s; data %s: response error: %s (%li) ", + host->name, data->name, snmp_errstring(res->errstat), + res->errstat); + status = -1; + break; + } + + char oid_buffer[1024] = {0}; + snprint_objid(oid_buffer, sizeof(oid_buffer) - 1, vb->name, + vb->name_length); + NOTICE("snmp plugin: host %s; data %s: OID `%s` failed: %s", host->name, + data->name, oid_buffer, snmp_errstring(res->errstat)); + + /* Get value index from todo list and skip OID found */ + assert(res->errindex <= oid_list_todo_num); + i = var_idx[res->errindex - 1]; + assert(i < oid_list_len); + oid_list_todo[i] = 0; + + snmp_free_pdu(res); + res = NULL; + continue; + } + for (vb = res->variables, i = 0; (vb != NULL); vb = vb->next_variable, i++) { /* Calculate value index from todo list */ @@ -1483,9 +1521,6 @@ static int csnmp_read_table(host_definition_t *host, data_definition_t *data) { snmp_free_pdu(res); res = NULL; - if (req != NULL) - snmp_free_pdu(req); - req = NULL; if (status == 0) csnmp_dispatch_table(host, data, instance_list_head, value_list_head); diff --git a/src/tail.c b/src/tail.c index 407970ae..fbba4788 100644 --- a/src/tail.c +++ b/src/tail.c @@ -34,7 +34,8 @@ /* * * - * Instance "exim" + * Plugin "mail" + * Instance "exim" * Interval 60 * * Regex "S=([1-9][0-9]*)" @@ -134,6 +135,7 @@ static int ctail_config_add_match_dstype(ctail_config_match_t *cm, } /* int ctail_config_add_match_dstype */ static int ctail_config_add_match(cu_tail_match_t *tm, + const char *plugin_name, const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval) { ctail_config_match_t cm = {0}; @@ -191,7 +193,8 @@ static int ctail_config_add_match(cu_tail_match_t *tm, if (status == 0) { // TODO(octo): there's nothing "simple" about the latency stuff … status = tail_match_add_match_simple( - tm, cm.regex, cm.excluderegex, cm.flags, "tail", plugin_instance, + tm, cm.regex, cm.excluderegex, cm.flags, + (plugin_name != NULL) ? plugin_name : "tail", plugin_instance, cm.type, cm.type_instance, cm.latency, interval); if (status != 0) @@ -210,6 +213,7 @@ static int ctail_config_add_match(cu_tail_match_t *tm, static int ctail_config_add_file(oconfig_item_t *ci) { cu_tail_match_t *tm; cdtime_t interval = 0; + char *plugin_name = NULL; char *plugin_instance = NULL; int num_matches = 0; @@ -229,12 +233,15 @@ static int ctail_config_add_file(oconfig_item_t *ci) { oconfig_item_t *option = ci->children + i; int status = 0; - if (strcasecmp("Instance", option->key) == 0) + if (strcasecmp("Plugin", option->key) == 0) + status = cf_util_get_string (option, &plugin_name); + else if (strcasecmp("Instance", option->key) == 0) status = cf_util_get_string(option, &plugin_instance); else if (strcasecmp("Interval", option->key) == 0) cf_util_get_cdtime(option, &interval); else if (strcasecmp("Match", option->key) == 0) { - status = ctail_config_add_match(tm, plugin_instance, option, interval); + status = ctail_config_add_match(tm, plugin_name, plugin_instance, option, + interval); if (status == 0) num_matches++; /* Be mild with failed matches.. */ @@ -247,6 +254,7 @@ static int ctail_config_add_file(oconfig_item_t *ci) { break; } /* for (i = 0; i < ci->children_num; i++) */ + sfree(plugin_name); sfree(plugin_instance); if (num_matches == 0) { diff --git a/src/tail_csv.c b/src/tail_csv.c index a9ce5d19..2e3ac5f0 100644 --- a/src/tail_csv.c +++ b/src/tail_csv.c @@ -44,6 +44,7 @@ struct metric_definition_s { typedef struct metric_definition_s metric_definition_t; struct instance_definition_s { + char *plugin_name; char *instance; char *path; cu_tail_t *tail; @@ -67,7 +68,8 @@ static int tcsv_submit(instance_definition_t *id, metric_definition_t *md, vl.values_len = 1; vl.values = &v; - sstrncpy(vl.plugin, "tail_csv", sizeof(vl.plugin)); + sstrncpy(vl.plugin, (id->plugin_name != NULL) ? id->plugin_name : "tail_csv", + sizeof(vl.plugin)); if (id->instance != NULL) sstrncpy(vl.plugin_instance, id->instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, md->type, sizeof(vl.type)); @@ -358,6 +360,7 @@ static void tcsv_instance_definition_destroy(void *arg) { cu_tail_destroy(id->tail); id->tail = NULL; + sfree(id->plugin_name); sfree(id->instance); sfree(id->path); sfree(id->metric_list); @@ -420,6 +423,7 @@ static int tcsv_config_add_file(oconfig_item_t *ci) { id = calloc(1, sizeof(*id)); if (id == NULL) return -1; + id->plugin_name = NULL; id->instance = NULL; id->path = NULL; id->metric_list = NULL; @@ -447,6 +451,8 @@ static int tcsv_config_add_file(oconfig_item_t *ci) { cf_util_get_cdtime(option, &id->interval); else if (strcasecmp("TimeFrom", option->key) == 0) status = tcsv_config_get_index(option, &id->time_from); + else if (strcasecmp("Plugin", option->key) == 0) + status = cf_util_get_string(option, &id->plugin_name); else { WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); status = -1; diff --git a/src/unixsock.c b/src/unixsock.c index 00b930e6..99e39eee 100644 --- a/src/unixsock.c +++ b/src/unixsock.c @@ -134,7 +134,13 @@ static int us_open_socket(void) { const char *grpname; struct group *g; struct group sg; - char grbuf[4096]; + + long int grbuf_size = sysconf(_SC_GETGR_R_SIZE_MAX); + if (grbuf_size <= 0) + grbuf_size = sysconf(_SC_PAGESIZE); + if (grbuf_size <= 0) + grbuf_size = 4096; + char grbuf[grbuf_size]; grpname = (sock_group != NULL) ? sock_group : COLLECTD_GRP_NAME; g = NULL;