static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */ { user_config_t *conf; user_data_t ud; char callback_name[DATA_MAX_NAME_LEN]; int i; conf = malloc (sizeof (*conf)); if (conf == NULL) return (ENOMEM); memset (conf, 0, sizeof (*conf)); conf->instance = NULL; varnish_config_apply_default (conf); if (ci->values_num == 1) { int status; status = cf_util_get_string (ci, &conf->instance); if (status != 0) { sfree (conf); return (status); } assert (conf->instance != NULL); if (strcmp ("localhost", conf->instance) == 0) { sfree (conf->instance); conf->instance = NULL; } } else if (ci->values_num > 1) { WARNING ("Varnish plugin: \"Instance\" blocks accept only " "one argument."); return (EINVAL); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("CollectCache", child->key) == 0) cf_util_get_boolean (child, &conf->collect_cache); else if (strcasecmp ("CollectConnections", child->key) == 0) cf_util_get_boolean (child, &conf->collect_connections); else if (strcasecmp ("CollectESI", child->key) == 0) cf_util_get_boolean (child, &conf->collect_esi); #ifdef HAVE_VARNISH_V3 else if (strcasecmp ("CollectDirectorDNS", child->key) == 0) cf_util_get_boolean (child, &conf->collect_dirdns); #endif else if (strcasecmp ("CollectBackend", child->key) == 0) cf_util_get_boolean (child, &conf->collect_backend); else if (strcasecmp ("CollectFetch", child->key) == 0) cf_util_get_boolean (child, &conf->collect_fetch); else if (strcasecmp ("CollectHCB", child->key) == 0) cf_util_get_boolean (child, &conf->collect_hcb); else if (strcasecmp ("CollectObjects", child->key) == 0) cf_util_get_boolean (child, &conf->collect_objects); #if HAVE_VARNISH_V2 else if (strcasecmp ("CollectPurge", child->key) == 0) cf_util_get_boolean (child, &conf->collect_purge); #else else if (strcasecmp ("CollectBan", child->key) == 0) cf_util_get_boolean (child, &conf->collect_ban); #endif else if (strcasecmp ("CollectSession", child->key) == 0) cf_util_get_boolean (child, &conf->collect_session); else if (strcasecmp ("CollectSHM", child->key) == 0) cf_util_get_boolean (child, &conf->collect_shm); else if (strcasecmp ("CollectSMS", child->key) == 0) cf_util_get_boolean (child, &conf->collect_sms); #if HAVE_VARNISH_V2 else if (strcasecmp ("CollectSMA", child->key) == 0) cf_util_get_boolean (child, &conf->collect_sma); else if (strcasecmp ("CollectSM", child->key) == 0) cf_util_get_boolean (child, &conf->collect_sm); #endif else if (strcasecmp ("CollectStruct", child->key) == 0) cf_util_get_boolean (child, &conf->collect_struct); else if (strcasecmp ("CollectTotals", child->key) == 0) cf_util_get_boolean (child, &conf->collect_totals); #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 else if (strcasecmp ("CollectUptime", child->key) == 0) cf_util_get_boolean (child, &conf->collect_uptime); #endif else if (strcasecmp ("CollectVCL", child->key) == 0) cf_util_get_boolean (child, &conf->collect_vcl); else if (strcasecmp ("CollectWorkers", child->key) == 0) cf_util_get_boolean (child, &conf->collect_workers); #if HAVE_VARNISH_V4 else if (strcasecmp ("CollectVSM", child->key) == 0) cf_util_get_boolean (child, &conf->collect_vsm); #endif else { WARNING ("Varnish plugin: Ignoring unknown " "configuration option: \"%s\". Did " "you forget to add an <Instance /> " "block around the configuration?", child->key); } } if (!conf->collect_cache && !conf->collect_connections && !conf->collect_esi && !conf->collect_backend #ifdef HAVE_VARNISH_V3 && !conf->collect_dirdns #endif && !conf->collect_fetch && !conf->collect_hcb && !conf->collect_objects #if HAVE_VARNISH_V2 && !conf->collect_purge #else && !conf->collect_ban #endif && !conf->collect_session && !conf->collect_shm && !conf->collect_sms #if HAVE_VARNISH_V2 && !conf->collect_sma && !conf->collect_sm #endif && !conf->collect_struct && !conf->collect_totals #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 && !conf->collect_uptime #endif && !conf->collect_vcl && !conf->collect_workers #if HAVE_VARNISH_V4 && !conf->collect_vsm #endif ) { WARNING ("Varnish plugin: No metric has been configured for " "instance \"%s\". Disabling this instance.", (conf->instance == NULL) ? "localhost" : conf->instance); return (EINVAL); } ssnprintf (callback_name, sizeof (callback_name), "varnish/%s", (conf->instance == NULL) ? "localhost" : conf->instance); ud.data = conf; ud.free_func = varnish_config_free; plugin_register_complex_read (/* group = */ "varnish", /* name = */ callback_name, /* callback = */ varnish_read, /* interval = */ 0, /* user data = */ &ud); have_instance = 1; return (0); } /* }}} int varnish_config_instance */
static int gr_format_name (char *ret, int ret_len, value_list_t const *vl, char const *ds_name, char const *prefix, char const *postfix, char const escape_char, unsigned int flags) { char n_host[DATA_MAX_NAME_LEN]; char n_plugin[DATA_MAX_NAME_LEN]; char n_plugin_instance[DATA_MAX_NAME_LEN]; char n_type[DATA_MAX_NAME_LEN]; char n_type_instance[DATA_MAX_NAME_LEN]; char tmp_plugin[2 * DATA_MAX_NAME_LEN + 1]; char tmp_type[2 * DATA_MAX_NAME_LEN + 1]; if (prefix == NULL) prefix = ""; if (postfix == NULL) postfix = ""; gr_copy_escape_part (n_host, vl->host, sizeof (n_host), escape_char); gr_copy_escape_part (n_plugin, vl->plugin, sizeof (n_plugin), escape_char); gr_copy_escape_part (n_plugin_instance, vl->plugin_instance, sizeof (n_plugin_instance), escape_char); gr_copy_escape_part (n_type, vl->type, sizeof (n_type), escape_char); gr_copy_escape_part (n_type_instance, vl->type_instance, sizeof (n_type_instance), escape_char); if (n_plugin_instance[0] != '\0') ssnprintf (tmp_plugin, sizeof (tmp_plugin), "%s%c%s", n_plugin, (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-', n_plugin_instance); else sstrncpy (tmp_plugin, n_plugin, sizeof (tmp_plugin)); if (n_type_instance[0] != '\0') { if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0) sstrncpy (tmp_type, n_type_instance, sizeof (tmp_type)); else ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s", n_type, (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-', n_type_instance); } else sstrncpy (tmp_type, n_type, sizeof (tmp_type)); /* Assert always_append_ds -> ds_name */ assert (!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL)); if (ds_name != NULL) { if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(tmp_plugin, tmp_type) == 0) ssnprintf (ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin, ds_name); else ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name); } else ssnprintf (ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin, tmp_type); return (0); }
static int config_add (oconfig_item_t *ci) { apache_t *st; int i; int status; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("apache plugin: The `%s' config option " "needs exactly one string argument.", ci->key); return (-1); } st = (apache_t *) malloc (sizeof (*st)); if (st == NULL) { ERROR ("apache plugin: malloc failed."); return (-1); } memset (st, 0, sizeof (*st)); status = config_set_string (&st->name, ci); if (status != 0) { sfree (st); return (status); } assert (st->name != NULL); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("URL", child->key) == 0) status = config_set_string (&st->url, child); else if (strcasecmp ("Host", child->key) == 0) status = config_set_string (&st->host, child); else if (strcasecmp ("User", child->key) == 0) status = config_set_string (&st->user, child); else if (strcasecmp ("Password", child->key) == 0) status = config_set_string (&st->pass, child); else if (strcasecmp ("VerifyPeer", child->key) == 0) status = config_set_boolean (&st->verify_peer, child); else if (strcasecmp ("VerifyHost", child->key) == 0) status = config_set_boolean (&st->verify_host, child); else if (strcasecmp ("CACert", child->key) == 0) status = config_set_string (&st->cacert, child); else if (strcasecmp ("Server", child->key) == 0) status = config_set_string (&st->server, child); else { WARNING ("apache plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* Check if struct is complete.. */ if ((status == 0) && (st->url == NULL)) { ERROR ("apache plugin: Instance `%s': " "No URL has been configured.", st->name); status = -1; } if (status == 0) { user_data_t ud; char callback_name[3*DATA_MAX_NAME_LEN]; memset (&ud, 0, sizeof (ud)); ud.data = st; ud.free_func = (void *) apache_free; memset (callback_name, 0, sizeof (callback_name)); ssnprintf (callback_name, sizeof (callback_name), "apache/%s/%s", (st->host != NULL) ? st->host : hostname_g, (st->name != NULL) ? st->name : "default"), status = plugin_register_complex_read (/* group = */ NULL, /* name = */ callback_name, /* callback = */ apache_read_host, /* interval = */ NULL, /* user_data = */ &ud); } if (status != 0) { apache_free(st); return (-1); } return (0); } /* int config_add */
void CFieldPrinter::PrintField(_nbExtractedFieldsDescriptor &FieldDescriptor, _nbExtractFieldInfo &FieldInfo, _nbExtractFieldInfo AllFieldsInfo[], int FieldNumber, const unsigned char *PktData) { _nbExtractedFieldsDescriptor *FieldsDescriptorVector= FieldDescriptor.DVct; int RetVal; switch (FieldInfo.FieldType) { case PDL_FIELD_TYPE_ALLFIELDS: { if (FieldDescriptor.Valid) { for (int i=0; i < FieldDescriptor.num_entries; i++) PrintField(FieldsDescriptorVector[i], AllFieldsInfo[i], AllFieldsInfo, FieldNumber, PktData); } }; break; case PDL_FIELD_TYPE_BIT: { if (FieldDescriptor.Valid) { if (FieldsDescriptorVector != NULL) { for (int i=0; i < FieldDescriptor.num_entries; i++) PrintField(FieldsDescriptorVector[i], FieldInfo, AllFieldsInfo, FieldNumber, PktData); return; } switch (m_PrintingMode) { case DEFAULT: fprintf(m_OutputFile, "\t%s.%s : value=%u\n", FieldInfo.Proto, FieldInfo.Name, (unsigned int) FieldDescriptor.BitField_Value); break; #ifdef ENABLE_REDIS case REDIS: ssnprintf(m_FormattedField, sizeof(m_FormattedField), "%u, ", (unsigned int) FieldDescriptor.BitField_Value); break; #endif #ifdef ENABLE_SQLITE3 case SQLITE3: ssnprintf(m_FormattedField, sizeof(m_FormattedField), "%u, ", (unsigned int) FieldDescriptor.BitField_Value); break; #endif default: fprintf(m_OutputFile, "%u, ", (unsigned int) FieldDescriptor.BitField_Value); break; } } else { switch (m_PrintingMode) { case DEFAULT: fprintf(m_OutputFile, "\t%s.%s : value=*\n", FieldInfo.Proto, FieldInfo.Name); break; #ifdef ENABLE_REDIS case REDIS: ssnprintf(m_FormattedField, sizeof(m_FormattedField), "-"); break; #endif #ifdef ENABLE_SQLITE3 case SQLITE3: ssnprintf(m_FormattedField, sizeof(m_FormattedField), "-"); break; #endif default: fprintf(m_OutputFile, " , "); break; } } }; break; default: { if (FieldDescriptor.Valid) { if (FieldsDescriptorVector != NULL) { for (int i=0; i < FieldDescriptor.num_entries; i++) PrintField(FieldsDescriptorVector[i], FieldInfo, AllFieldsInfo, FieldNumber, PktData); return; } if (FieldDescriptor.Length > MAX_FIELD_SIZE) { fprintf(stderr, "The size of field '%s' is larger than the max value allowed in this program. ",FieldInfo.Name); fprintf(stderr, "Max allowed: %d - Current: %d\n", MAX_FIELD_SIZE, FieldDescriptor.Length); return; } #ifdef PROFILING int64_t StartTime, EndTime; StartTime= nbProfilerGetTime(); #endif // Here we use the 'UserExtension' member in order to store the 'fast printing' function code, if available. if (FieldDescriptor.UserExtension) { RetVal= m_NetPDLUtils->FormatNetPDLField((long) FieldDescriptor.UserExtension, PktData + FieldDescriptor.Offset, FieldDescriptor.Length, m_FormattedField, sizeof(m_FormattedField)); } else { // If the raw packet dump is enough for you, you can get rid of this function RetVal= m_NetPDLUtils->FormatNetPDLField(FieldInfo.Proto, FieldInfo.Name, PktData + FieldDescriptor.Offset, FieldDescriptor.Length, m_FormattedField, sizeof(m_FormattedField)); } #ifdef PROFILING EndTime= nbProfilerGetTime(); ProfilerFormatFields->StoreSample(StartTime, EndTime); #endif if (RetVal == nbSUCCESS) { // Perform anonymization if needed // If this fields is found in the anonymization table, let's replace it with the correspondent anonimized value if (m_AnonymizationIPArgumentList.count(FieldNumber+1) > 0) { if (!m_AnonymizationIPTable[m_FormattedField].empty()) // There may be a bug here... if the field contains '0' in it, the strncpy may fail to copy the entire data strncpy(m_FormattedField, m_AnonymizationIPTable[m_FormattedField].c_str(), sizeof(m_FormattedField)); } switch (m_PrintingMode) { case DEFAULT: fprintf(m_OutputFile, "\t%s.%s: offset=%d len=%d value=%s\n", FieldInfo.Proto,FieldInfo.Name, FieldDescriptor.Offset, FieldDescriptor.Length, m_FormattedField); break; #ifdef ENABLE_REDIS case REDIS: // Do nothing; the field is already in the m_FormattedField field break; #endif #ifdef ENABLE_SQLITE3 case SQLITE3: // Do nothing; the field is already in the m_FormattedField field break; #endif default: fprintf(m_OutputFile, "%s, ", m_FormattedField); break; } } } else { switch (m_PrintingMode) { case DEFAULT: fprintf(m_OutputFile, "\t%s.%s: offset= * len= * value= *\n", FieldInfo.Proto, FieldInfo.Name); break; #ifdef ENABLE_REDIS case REDIS: ssnprintf(m_FormattedField, sizeof(m_FormattedField), "\0"); break; #endif #ifdef ENABLE_SQLITE3 case SQLITE3: ssnprintf(m_FormattedField, sizeof(m_FormattedField), "\0"); break; #endif default: fprintf(m_OutputFile, " , "); break; } } } } }
static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ _Bool publish) { camqp_config_t *conf; int status; int i; conf = malloc (sizeof (*conf)); if (conf == NULL) { ERROR ("amqp plugin: malloc failed."); return (ENOMEM); } /* Initialize "conf" {{{ */ memset (conf, 0, sizeof (*conf)); conf->publish = publish; conf->name = NULL; conf->format = CAMQP_FORMAT_COMMAND; conf->host = NULL; conf->port = 5672; conf->vhost = NULL; conf->user = NULL; conf->password = NULL; conf->exchange = NULL; conf->routing_key = NULL; conf->connection_retry_delay = 0; /* publish only */ conf->delivery_mode = CAMQP_DM_VOLATILE; conf->store_rates = 0; conf->graphite_flags = 0; /* publish & graphite only */ conf->prefix = NULL; conf->postfix = NULL; conf->escape_char = '_'; /* subscribe only */ conf->exchange_type = NULL; conf->queue = NULL; conf->queue_durable = 0; conf->queue_auto_delete = 1; /* general */ conf->connection = NULL; pthread_mutex_init (&conf->lock, /* attr = */ NULL); /* }}} */ status = cf_util_get_string (ci, &conf->name); if (status != 0) { sfree (conf); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &conf->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { conf->port = status; status = 0; } } else if (strcasecmp ("VHost", child->key) == 0) status = cf_util_get_string (child, &conf->vhost); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &conf->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &conf->password); else if (strcasecmp ("Exchange", child->key) == 0) status = cf_util_get_string (child, &conf->exchange); else if ((strcasecmp ("ExchangeType", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->exchange_type); else if ((strcasecmp ("Queue", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->queue); else if ((strcasecmp ("QueueDurable", child->key) == 0) && !publish) status = cf_util_get_boolean (child, &conf->queue_durable); else if ((strcasecmp ("QueueAutoDelete", child->key) == 0) && !publish) status = cf_util_get_boolean (child, &conf->queue_auto_delete); else if (strcasecmp ("RoutingKey", child->key) == 0) status = cf_util_get_string (child, &conf->routing_key); else if ((strcasecmp ("Persistent", child->key) == 0) && publish) { _Bool tmp = 0; status = cf_util_get_boolean (child, &tmp); if (tmp) conf->delivery_mode = CAMQP_DM_PERSISTENT; else conf->delivery_mode = CAMQP_DM_VOLATILE; } else if ((strcasecmp ("StoreRates", child->key) == 0) && publish) { status = cf_util_get_boolean (child, &conf->store_rates); (void) cf_util_get_flag (child, &conf->graphite_flags, GRAPHITE_STORE_RATES); } else if ((strcasecmp ("Format", child->key) == 0) && publish) status = camqp_config_set_format (child, conf); else if ((strcasecmp ("GraphiteSeparateInstances", child->key) == 0) && publish) status = cf_util_get_flag (child, &conf->graphite_flags, GRAPHITE_SEPARATE_INSTANCES); else if ((strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) && publish) status = cf_util_get_flag (child, &conf->graphite_flags, GRAPHITE_ALWAYS_APPEND_DS); else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish) status = cf_util_get_string (child, &conf->prefix); else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish) status = cf_util_get_string (child, &conf->postfix); else if ((strcasecmp ("GraphiteEscapeChar", child->key) == 0) && publish) { char *tmp_buff = NULL; status = cf_util_get_string (child, &tmp_buff); if (strlen (tmp_buff) > 1) WARNING ("amqp plugin: The option \"GraphiteEscapeChar\" handles " "only one character. Others will be ignored."); conf->escape_char = tmp_buff[0]; sfree (tmp_buff); } else if (strcasecmp ("ConnectionRetryDelay", child->key) == 0) status = cf_util_get_int (child, &conf->connection_retry_delay); else WARNING ("amqp plugin: Ignoring unknown " "configuration option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if ((status == 0) && (conf->exchange == NULL)) { if (conf->exchange_type != NULL) WARNING ("amqp plugin: The option \"ExchangeType\" was given " "without the \"Exchange\" option. It will be ignored."); if (!publish && (conf->routing_key != NULL)) WARNING ("amqp plugin: The option \"RoutingKey\" was given " "without the \"Exchange\" option. It will be ignored."); } if (status != 0) { camqp_config_free (conf); return (status); } if (conf->exchange != NULL) { DEBUG ("amqp plugin: camqp_config_connection: exchange = %s;", conf->exchange); } if (publish) { char cbname[128]; user_data_t ud = { conf, camqp_config_free }; ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name); status = plugin_register_write (cbname, camqp_write, &ud); if (status != 0) { camqp_config_free (conf); return (status); } } else { status = camqp_subscribe_init (conf); if (status != 0) { camqp_config_free (conf); return (status); } } return (0); } /* }}} int camqp_config_connection */
static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ cx_xpath_t *xpath, value_list_t *vl, _Bool is_table) { xmlXPathObjectPtr instance_node_obj = NULL; xmlNodeSetPtr instance_node = NULL; memset (vl->type_instance, 0, sizeof (vl->type_instance)); /* If the base xpath returns more than one block, the result is assumed to be * a table. The `Instance' option is not optional in this case. Check for the * condition and inform the user. */ if (is_table && (xpath->instance == NULL)) { WARNING ("curl_xml plugin: " "Base-XPath %s is a table (more than one result was returned), " "but no instance-XPath has been defined.", xpath->path); return (-1); } /* instance has to be an xpath expression */ if (xpath->instance != NULL) { int tmp_size; instance_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST xpath->instance); if (instance_node_obj == NULL) return (-1); /* error is logged already */ instance_node = instance_node_obj->nodesetval; tmp_size = (instance_node) ? instance_node->nodeNr : 0; if (tmp_size <= 0) { WARNING ("curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match " "any of the nodes. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } if (tmp_size > 1) { WARNING ("curl_xml plugin: " "relative xpath expression for 'InstanceFrom' \"%s\" is expected " "to return only one text node. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } /* ignoring the element if other than textnode/attribute */ if (cx_if_not_text_node(instance_node->nodeTab[0])) { WARNING ("curl_xml plugin: " "relative xpath expression \"%s\" is expected to return only text node " "which is not the case. Skipping the node.", xpath->instance); xmlXPathFreeObject (instance_node_obj); return (-1); } } /* if (xpath->instance != NULL) */ if (xpath->instance_prefix != NULL) { if (instance_node != NULL) { char *node_value = (char *) xmlNodeGetContent(instance_node->nodeTab[0]); ssnprintf (vl->type_instance, sizeof (vl->type_instance),"%s%s", xpath->instance_prefix, node_value); sfree (node_value); } else sstrncpy (vl->type_instance, xpath->instance_prefix, sizeof (vl->type_instance)); } else { /* If instance_prefix and instance_node are NULL, then * don't set the type_instance */ if (instance_node != NULL) { char *node_value = (char *) xmlNodeGetContent(instance_node->nodeTab[0]); sstrncpy (vl->type_instance, node_value, sizeof (vl->type_instance)); sfree (node_value); } } /* Free `instance_node_obj' this late, because `instance_node' points to * somewhere inside this structure. */ xmlXPathFreeObject (instance_node_obj); return (0); } /* }}} int cx_handle_instance_xpath */
static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{ */ { int status; int i; struct kafka_topic_context *tctx; char *key; char *val; char callback_name[DATA_MAX_NAME_LEN]; char errbuf[1024]; user_data_t ud; oconfig_item_t *child; rd_kafka_conf_res_t ret; if ((tctx = calloc(1, sizeof (*tctx))) == NULL) { ERROR ("write_kafka plugin: calloc failed."); return; } tctx->escape_char = '.'; tctx->store_rates = 1; rd_kafka_conf_set_log_cb(conf, kafka_log); if ((tctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errbuf, sizeof(errbuf))) == NULL) { sfree(tctx); ERROR("write_kafka plugin: cannot create kafka handle."); return; } conf = NULL; if ((tctx->conf = rd_kafka_topic_conf_new()) == NULL) { rd_kafka_destroy(tctx->kafka); sfree(tctx); ERROR ("write_kafka plugin: cannot create topic configuration."); return; } if (ci->values_num != 1) { WARNING("kafka topic name needed."); goto errout; } if (ci->values[0].type != OCONFIG_TYPE_STRING) { WARNING("kafka topic needs a string argument."); goto errout; } if ((tctx->topic_name = strdup(ci->values[0].value.string)) == NULL) { ERROR("write_kafka plugin: cannot copy topic name."); goto errout; } for (i = 0; i < ci->children_num; i++) { /* * The code here could be simplified but makes room * for easy adding of new options later on. */ child = &ci->children[i]; status = 0; if (strcasecmp ("Property", child->key) == 0) { if (child->values_num != 2) { WARNING("kafka properties need both a key and a value."); goto errout; } if (child->values[0].type != OCONFIG_TYPE_STRING || child->values[1].type != OCONFIG_TYPE_STRING) { WARNING("kafka properties needs string arguments."); goto errout; } key = child->values[0].value.string; val = child->values[0].value.string; ret = rd_kafka_topic_conf_set(tctx->conf,key, val, errbuf, sizeof(errbuf)); if (ret != RD_KAFKA_CONF_OK) { WARNING("cannot set kafka topic property %s to %s: %s.", key, val, errbuf); goto errout; } } else if (strcasecmp ("Key", child->key) == 0) { char *tmp_buf = NULL; status = cf_util_get_string(child, &tmp_buf); if (status != 0) { WARNING("write_kafka plugin: invalid key supplied"); break; } if (strcasecmp(tmp_buf, "Random") != 0) { tctx->has_key = 1; tctx->key = crc32_buffer((u_char *)tmp_buf, strlen(tmp_buf)); } sfree(tmp_buf); } else if (strcasecmp ("Format", child->key) == 0) { status = cf_util_get_string(child, &key); if (status != 0) goto errout; assert(key != NULL); if (strcasecmp(key, "Command") == 0) { tctx->format = KAFKA_FORMAT_COMMAND; } else if (strcasecmp(key, "Graphite") == 0) { tctx->format = KAFKA_FORMAT_GRAPHITE; } else if (strcasecmp(key, "Json") == 0) { tctx->format = KAFKA_FORMAT_JSON; } else { WARNING ("write_kafka plugin: Invalid format string: %s", key); } sfree(key); } else if (strcasecmp ("StoreRates", child->key) == 0) { status = cf_util_get_boolean (child, &tctx->store_rates); (void) cf_util_get_flag (child, &tctx->graphite_flags, GRAPHITE_STORE_RATES); } else if (strcasecmp ("GraphiteSeparateInstances", child->key) == 0) { status = cf_util_get_flag (child, &tctx->graphite_flags, GRAPHITE_SEPARATE_INSTANCES); } else if (strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) { status = cf_util_get_flag (child, &tctx->graphite_flags, GRAPHITE_ALWAYS_APPEND_DS); } else if (strcasecmp ("GraphitePrefix", child->key) == 0) { status = cf_util_get_string (child, &tctx->prefix); } else if (strcasecmp ("GraphitePostfix", child->key) == 0) { status = cf_util_get_string (child, &tctx->postfix); } else if (strcasecmp ("GraphiteEscapeChar", child->key) == 0) { char *tmp_buff = NULL; status = cf_util_get_string (child, &tmp_buff); if (strlen (tmp_buff) > 1) WARNING ("write_kafka plugin: The option \"GraphiteEscapeChar\" handles " "only one character. Others will be ignored."); tctx->escape_char = tmp_buff[0]; sfree (tmp_buff); } else { WARNING ("write_kafka plugin: Invalid directive: %s.", child->key); } if (status != 0) break; } rd_kafka_topic_conf_set_partitioner_cb(tctx->conf, kafka_partition); rd_kafka_topic_conf_set_opaque(tctx->conf, tctx); if ((tctx->topic = rd_kafka_topic_new(tctx->kafka, tctx->topic_name, tctx->conf)) == NULL) { ERROR("write_kafka plugin: cannot create topic."); goto errout; } tctx->conf = NULL; ssnprintf(callback_name, sizeof(callback_name), "write_kafka/%s", tctx->topic_name); ud.data = tctx; ud.free_func = kafka_topic_context_free; status = plugin_register_write (callback_name, kafka_write, &ud); if (status != 0) { WARNING ("write_kafka plugin: plugin_register_write (\"%s\") " "failed with status %i.", callback_name, status); goto errout; } return; errout: if (conf != NULL) rd_kafka_conf_destroy(conf); if (tctx->kafka != NULL) rd_kafka_destroy(tctx->kafka); if (tctx->topic != NULL) rd_kafka_topic_destroy(tctx->topic); if (tctx->topic_name != NULL) free(tctx->topic_name); if (tctx->conf != NULL) rd_kafka_topic_conf_destroy(tctx->conf); sfree(tctx); } /* }}} int kafka_config_topic */
static int uc_send_notification (const char *name) { cache_entry_t *ce = NULL; int status; char *name_copy; char *host; char *plugin; char *plugin_instance; char *type; char *type_instance; notification_t n; name_copy = strdup (name); if (name_copy == NULL) { ERROR ("uc_send_notification: strdup failed."); return (-1); } status = parse_identifier (name_copy, &host, &plugin, &plugin_instance, &type, &type_instance); if (status != 0) { ERROR ("uc_send_notification: Cannot parse name `%s'", name); return (-1); } /* Copy the associative members */ notification_init (&n, NOTIF_FAILURE, /* host = */ NULL, host, plugin, plugin_instance, type, type_instance); sfree (name_copy); name_copy = host = plugin = plugin_instance = type = type_instance = NULL; pthread_mutex_lock (&cache_lock); /* * Set the time _after_ getting the lock because we don't know how long * acquiring the lock takes and we will use this time later to decide * whether or not the state is OKAY. */ n.time = time (NULL); status = c_avl_get (cache_tree, name, (void *) &ce); if (status != 0) { pthread_mutex_unlock (&cache_lock); sfree (name_copy); return (-1); } /* Check if the entry has been updated in the meantime */ if ((n.time - ce->last_update) < (2 * ce->interval)) { ce->state = STATE_OKAY; pthread_mutex_unlock (&cache_lock); sfree (name_copy); return (-1); } ssnprintf (n.message, sizeof (n.message), "%s has not been updated for %i seconds.", name, (int) (n.time - ce->last_update)); pthread_mutex_unlock (&cache_lock); plugin_dispatch_notification (&n); return (0); } /* int uc_send_notification */
int uc_update (const data_set_t *ds, const value_list_t *vl) { char name[6 * DATA_MAX_NAME_LEN]; cache_entry_t *ce = NULL; int send_okay_notification = 0; time_t update_delay = 0; notification_t n; int status; int i; if (FORMAT_VL (name, sizeof (name), vl) != 0) { ERROR ("uc_update: FORMAT_VL failed."); return (-1); } pthread_mutex_lock (&cache_lock); status = c_avl_get (cache_tree, name, (void *) &ce); if (status != 0) /* entry does not yet exist */ { status = uc_insert (ds, vl, name); pthread_mutex_unlock (&cache_lock); return (status); } assert (ce != NULL); assert (ce->values_num == ds->ds_num); if (ce->last_time >= vl->time) { pthread_mutex_unlock (&cache_lock); NOTICE ("uc_update: Value too old: name = %s; value time = %u; " "last cache update = %u;", name, (unsigned int) vl->time, (unsigned int) ce->last_time); return (-1); } /* Send a notification (after the lock has been released) if we switch the * state from something else to `okay'. */ if (ce->state == STATE_MISSING) { send_okay_notification = 1; ce->state = STATE_OKAY; update_delay = time (NULL) - ce->last_update; } for (i = 0; i < ds->ds_num; i++) { switch (ds->ds[i].type) { case DS_TYPE_COUNTER: { counter_t diff; /* check if the counter has wrapped around */ if (vl->values[i].counter < ce->values_raw[i].counter) { if (ce->values_raw[i].counter <= 4294967295U) diff = (4294967295U - ce->values_raw[i].counter) + vl->values[i].counter; else diff = (18446744073709551615ULL - ce->values_raw[i].counter) + vl->values[i].counter; } else /* counter has NOT wrapped around */ { diff = vl->values[i].counter - ce->values_raw[i].counter; } ce->values_gauge[i] = ((double) diff) / ((double) (vl->time - ce->last_time)); ce->values_raw[i].counter = vl->values[i].counter; } break; case DS_TYPE_GAUGE: ce->values_raw[i].gauge = vl->values[i].gauge; ce->values_gauge[i] = vl->values[i].gauge; break; case DS_TYPE_DERIVE: { derive_t diff; diff = vl->values[i].derive - ce->values_raw[i].derive; ce->values_gauge[i] = ((double) diff) / ((double) (vl->time - ce->last_time)); ce->values_raw[i].derive = vl->values[i].derive; } break; case DS_TYPE_ABSOLUTE: ce->values_gauge[i] = ((double) vl->values[i].absolute) / ((double) (vl->time - ce->last_time)); ce->values_raw[i].absolute = vl->values[i].absolute; break; default: /* This shouldn't happen. */ pthread_mutex_unlock (&cache_lock); ERROR ("uc_update: Don't know how to handle data source type %i.", ds->ds[i].type); return (-1); } /* switch (ds->ds[i].type) */ DEBUG ("uc_update: %s: ds[%i] = %lf", name, i, ce->values_gauge[i]); } /* for (i) */ /* Update the history if it exists. */ if (ce->history != NULL) { assert (ce->history_index < ce->history_length); for (i = 0; i < ce->values_num; i++) { size_t hist_idx = (ce->values_num * ce->history_index) + i; ce->history[hist_idx] = ce->values_gauge[i]; } assert (ce->history_length > 0); ce->history_index = (ce->history_index + 1) % ce->history_length; } /* Prune invalid gauge data */ uc_check_range (ds, ce); ce->last_time = vl->time; ce->last_update = time (NULL); ce->interval = vl->interval; pthread_mutex_unlock (&cache_lock); if (send_okay_notification == 0) return (0); /* Do not send okay notifications for uninteresting values, i. e. values for * which no threshold is configured. */ status = ut_check_interesting (name); if (status <= 0) return (0); /* Initialize the notification */ memset (&n, '\0', sizeof (n)); NOTIFICATION_INIT_VL (&n, vl, ds); n.severity = NOTIF_OKAY; n.time = vl->time; ssnprintf (n.message, sizeof (n.message), "Received a value for %s. It was missing for %u seconds.", name, (unsigned int) update_delay); plugin_dispatch_notification (&n); return (0); } /* int uc_update */
static int notify_email_notification (const notification_t *n) { smtp_recipient_t recipient; struct tm timestamp_tm; char timestamp_str[64]; char severity[32]; char subject[MAXSTRING]; char buf[4096] = ""; int buf_len = sizeof (buf); int i; ssnprintf (severity, sizeof (severity), "%s", (n->severity == NOTIF_FAILURE) ? "FAILURE" : ((n->severity == NOTIF_WARNING) ? "WARNING" : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN"))); ssnprintf (subject, sizeof (subject), (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject, severity, n->host); localtime_r (&n->time, ×tamp_tm); strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S", ×tamp_tm); timestamp_str[sizeof (timestamp_str) - 1] = '\0'; /* Let's make RFC822 message text with \r\n EOLs */ ssnprintf (buf, buf_len, "MIME-Version: 1.0\r\n" "Content-Type: text/plain;\r\n" "Content-Transfer-Encoding: 8bit\r\n" "Subject: %s\r\n" "\r\n" "%s - %s@%s\r\n" "\r\n" "Message: %s", subject, timestamp_str, severity, n->host, n->message); if (!(message = smtp_add_message (session))) { ERROR ("notify_email plugin: cannot set SMTP message"); return (-1); } smtp_set_reverse_path (message, email_from); smtp_set_header (message, "To", NULL, NULL); smtp_set_message_str (message, buf); for (i = 0; i < recipients_len; i++) recipient = smtp_add_recipient (message, recipients[i]); /* Initiate a connection to the SMTP server and transfer the message. */ if (!smtp_start_session (session)) { char buf[MAXSTRING]; ERROR ("notify_email plugin: SMTP server problem: %s", smtp_strerror (smtp_errno (), buf, sizeof buf)); return (-1); } else { const smtp_status_t *status; /* Report on the success or otherwise of the mail transfer. */ status = smtp_message_transfer_status (message); DEBUG ("notify_email plugin: SMTP server report: %d %s", status->code, (status->text != NULL) ? status->text : "\n"); smtp_enumerate_recipients (message, print_recipient_status, NULL); } return (0); } /* int notify_email_notification */
static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ { cj_t *db; int status = 0; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("curl_json plugin: The `URL' block " "needs exactly one string argument."); return (-1); } db = (cj_t *) malloc (sizeof (*db)); if (db == NULL) { ERROR ("curl_json plugin: malloc failed."); return (-1); } memset (db, 0, sizeof (*db)); if (strcasecmp ("URL", ci->key) == 0) status = cf_util_get_string (ci, &db->url); else if (strcasecmp ("Sock", ci->key) == 0) status = cf_util_get_string (ci, &db->sock); else { ERROR ("curl_json plugin: cj_config: " "Invalid key: %s", ci->key); return (-1); } if (status != 0) { sfree (db); return (status); } /* Fill the `cj_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Instance", child->key) == 0) status = cf_util_get_string (child, &db->instance); else if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &db->host); else if (db->url && strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &db->user); else if (db->url && strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); else if (strcasecmp ("Digest", child->key) == 0) status = cf_util_get_boolean (child, &db->digest); else if (db->url && strcasecmp ("VerifyPeer", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_peer); else if (db->url && strcasecmp ("VerifyHost", child->key) == 0) status = cf_util_get_boolean (child, &db->verify_host); else if (db->url && strcasecmp ("CACert", child->key) == 0) status = cf_util_get_string (child, &db->cacert); else if (db->url && strcasecmp ("Header", child->key) == 0) status = cj_config_append_string ("Header", &db->headers, child); else if (db->url && strcasecmp ("Post", child->key) == 0) status = cf_util_get_string (child, &db->post_body); else if (strcasecmp ("Key", child->key) == 0) status = cj_config_add_key (db, child); else if (strcasecmp ("Interval", child->key) == 0) status = cf_util_get_cdtime(child, &db->interval); else { WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } if (status == 0) { if (db->tree == NULL) { WARNING ("curl_json plugin: No (valid) `Key' block within `%s' \"`%s'\".", db->url ? "URL" : "Sock", db->url ? db->url : db->sock); status = -1; } if (status == 0 && db->url) status = cj_init_curl (db); } /* If all went well, register this database for reading */ if (status == 0) { user_data_t ud; char cb_name[DATA_MAX_NAME_LEN]; struct timespec interval = { 0, 0 }; CDTIME_T_TO_TIMESPEC (db->interval, &interval); if (db->instance == NULL) db->instance = strdup("default"); DEBUG ("curl_json plugin: Registering new read callback: %s", db->instance); memset (&ud, 0, sizeof (ud)); ud.data = (void *) db; ud.free_func = cj_free; ssnprintf (cb_name, sizeof (cb_name), "curl_json-%s-%s", db->instance, db->url ? db->url : db->sock); plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read, /* interval = */ (db->interval > 0) ? &interval : NULL, &ud); } else { cj_free (db); return (-1); } return (0); }
/* * * * * * * * * * * WARNING: Magic * * * * * * * * * * */ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */ const rrdcreate_config_t *cfg) { char **rra_def; int rra_num; int *rts; int rts_num; int rra_max; int span; int cdp_num; int cdp_len; int i, j; char buffer[128]; /* The stepsize we use here: If it is user-set, use it. If not, use the * interval of the value-list. */ int ss; if (cfg->rrarows <= 0) { *ret = NULL; return (-1); } if ((cfg->xff < 0) || (cfg->xff >= 1.0)) { *ret = NULL; return (-1); } if (cfg->stepsize > 0) ss = cfg->stepsize; else ss = (int) CDTIME_T_TO_TIME_T (vl->interval); if (ss <= 0) { *ret = NULL; return (-1); } /* Use the configured timespans or fall back to the built-in defaults */ if (cfg->timespans_num != 0) { rts = cfg->timespans; rts_num = cfg->timespans_num; } else { rts = rra_timespans; rts_num = rra_timespans_num; } rra_max = rts_num * rra_types_num; if ((rra_def = (char **) malloc ((rra_max + 1) * sizeof (char *))) == NULL) return (-1); memset (rra_def, '\0', (rra_max + 1) * sizeof (char *)); rra_num = 0; cdp_len = 0; for (i = 0; i < rts_num; i++) { span = rts[i]; if ((span / ss) < cfg->rrarows) span = ss * cfg->rrarows; if (cdp_len == 0) cdp_len = 1; else cdp_len = (int) floor (((double) span) / ((double) (cfg->rrarows * ss))); cdp_num = (int) ceil (((double) span) / ((double) (cdp_len * ss))); for (j = 0; j < rra_types_num; j++) { int status; if (rra_num >= rra_max) break; status = ssnprintf (buffer, sizeof (buffer), "RRA:%s:%.10f:%u:%u", rra_types[j], cfg->xff, cdp_len, cdp_num); if ((status < 0) || ((size_t) status >= sizeof (buffer))) { ERROR ("rra_get: Buffer would have been truncated."); continue; } rra_def[rra_num++] = sstrdup (buffer); } } *ret = rra_def; return (rra_num); } /* }}} int rra_get */
static int ds_get (char ***ret, /* {{{ */ const data_set_t *ds, const value_list_t *vl, const rrdcreate_config_t *cfg) { char **ds_def; int ds_num; char min[32]; char max[32]; char buffer[128]; ds_def = (char **) malloc (ds->ds_num * sizeof (char *)); if (ds_def == NULL) { char errbuf[1024]; ERROR ("rrdtool plugin: malloc failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } memset (ds_def, '\0', ds->ds_num * sizeof (char *)); for (ds_num = 0; ds_num < ds->ds_num; ds_num++) { data_source_t *d = ds->ds + ds_num; char *type; int status; ds_def[ds_num] = NULL; if (d->type == DS_TYPE_COUNTER) type = "COUNTER"; else if (d->type == DS_TYPE_GAUGE) type = "GAUGE"; else if (d->type == DS_TYPE_DERIVE) type = "DERIVE"; else if (d->type == DS_TYPE_ABSOLUTE) type = "ABSOLUTE"; else { ERROR ("rrdtool plugin: Unknown DS type: %i", d->type); break; } if (isnan (d->min)) { sstrncpy (min, "U", sizeof (min)); } else ssnprintf (min, sizeof (min), "%f", d->min); if (isnan (d->max)) { sstrncpy (max, "U", sizeof (max)); } else ssnprintf (max, sizeof (max), "%f", d->max); status = ssnprintf (buffer, sizeof (buffer), "DS:%s:%s:%i:%s:%s", d->name, type, (cfg->heartbeat > 0) ? cfg->heartbeat : (int) CDTIME_T_TO_TIME_T (2 * vl->interval), min, max); if ((status < 1) || ((size_t) status >= sizeof (buffer))) break; ds_def[ds_num] = sstrdup (buffer); } /* for ds_num = 0 .. ds->ds_num */ if (ds_num != ds->ds_num) { ds_free (ds_num, ds_def); return (-1); } *ret = ds_def; return (ds_num); } /* }}} int ds_get */
static int wh_callback_init (wh_callback_t *cb) /* {{{ */ { struct curl_slist *headers; if (cb->curl != NULL) return (0); cb->curl = curl_easy_init (); if (cb->curl == NULL) { ERROR ("curl plugin: curl_easy_init failed."); return (-1); } curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); headers = NULL; headers = curl_slist_append (headers, "Accept: */*"); if (cb->format == WH_FORMAT_JSON) headers = curl_slist_append (headers, "Content-Type: application/json"); else headers = curl_slist_append (headers, "Content-Type: text/plain"); headers = curl_slist_append (headers, "Expect:"); curl_easy_setopt (cb->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt (cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf); curl_easy_setopt (cb->curl, CURLOPT_URL, cb->location); if (cb->user != NULL) { size_t credentials_size; credentials_size = strlen (cb->user) + 2; if (cb->pass != NULL) credentials_size += strlen (cb->pass); cb->credentials = (char *) malloc (credentials_size); if (cb->credentials == NULL) { ERROR ("curl plugin: malloc failed."); return (-1); } ssnprintf (cb->credentials, credentials_size, "%s:%s", cb->user, (cb->pass == NULL) ? "" : cb->pass); curl_easy_setopt (cb->curl, CURLOPT_USERPWD, cb->credentials); curl_easy_setopt (cb->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); } curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYPEER, (long) cb->verify_peer); curl_easy_setopt (cb->curl, CURLOPT_SSL_VERIFYHOST, cb->verify_host ? 2L : 0L); curl_easy_setopt (cb->curl, CURLOPT_SSLVERSION, cb->sslversion); if (cb->cacert != NULL) curl_easy_setopt (cb->curl, CURLOPT_CAINFO, cb->cacert); if (cb->capath != NULL) curl_easy_setopt (cb->curl, CURLOPT_CAPATH, cb->capath); if (cb->clientkey != NULL && cb->clientcert != NULL) { curl_easy_setopt (cb->curl, CURLOPT_SSLKEY, cb->clientkey); curl_easy_setopt (cb->curl, CURLOPT_SSLCERT, cb->clientcert); if (cb->clientkeypass != NULL) curl_easy_setopt (cb->curl, CURLOPT_SSLKEYPASSWD, cb->clientkeypass); } wh_reset_buffer (cb); return (0); } /* }}} int wh_callback_init */
void nbGetLastErrorEx(char *File, char *Function, int Line, const char *CallerString, char *ErrBuf, int ErrBufSize) { #ifdef WIN32 int RetVal; int ErrorCode; TCHAR Message[2048]; // It will be char (if we're using ascii) or wchar_t (if we're using unicode) DWORD FormatFlags; HMODULE ModuleHandle = NULL; // default to system source ErrorCode= GetLastError(); FormatFlags= FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK; // Let's check if ErrorCode is in the network range, load the message source. // This will help printing error messages related to network services if (ErrorCode >= NERR_BASE && ErrorCode <= MAX_NERR) { ModuleHandle = LoadLibraryEx(TEXT("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE); if (ModuleHandle != NULL) FormatFlags |= FORMAT_MESSAGE_FROM_HMODULE; } // Call FormatMessage() to allow for message text to be acquired from the system // or from the supplied module handle. RetVal= FormatMessage(FormatFlags, ModuleHandle, // module to get message from (NULL == system) ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Message, sizeof(Message) / sizeof(TCHAR), NULL); // If we loaded a message source, unload it. if (ModuleHandle != NULL) FreeLibrary(ModuleHandle); if (RetVal == 0) { if (ErrBuf) { #ifdef _DEBUG if ( (CallerString) && (*CallerString) ) ssnprintf(ErrBuf, ErrBufSize, "%s:%d (%s()): %sUnable to get the exact error message", File, Line, Function, CallerString); else ssnprintf(ErrBuf, ErrBufSize, "%s:%d (%s()): %s Unable to get the exact error message", File, Line, Function); #else if ( (CallerString) && (*CallerString) ) ssnprintf(ErrBuf, ErrBufSize, "%sUnable to get the exact error message", CallerString); else ssnprintf(ErrBuf, ErrBufSize, "Unable to get the exact error message"); #endif ErrBuf[ErrBufSize - 1]= 0; } return; } if (ErrBuf) { #ifdef _DEBUG if ( (CallerString) && (*CallerString) ) ssnprintf(ErrBuf, ErrBufSize, "%s:%d (%s()): %s%s (code %d)", File, Line, Function, CallerString, Message, ErrorCode); else ssnprintf(ErrBuf, ErrBufSize, "%s:%d (%s()): %s (code %d)", File, Line, Function, Message, ErrorCode); #else if ( (CallerString) && (*CallerString) ) ssnprintf(ErrBuf, ErrBufSize, "%s%s (code %d)", CallerString, Message, ErrorCode); else ssnprintf(ErrBuf, ErrBufSize, "%s (code %d)", Message, ErrorCode); #endif ErrBuf[ErrBufSize - 1]= 0; } #else char *Message; Message= strerror(errno); if (ErrBuf) { #ifdef _DEBUG if ( (CallerString) && (*CallerString) ) ssnprintf(ErrBuf, ErrBufSize, "%s:%d (%s()): %s%s (code %d)", File, Line, Function, CallerString, Message, errno); else ssnprintf(ErrBuf, ErrBufSize, "%s:%d (%s()): %s (code %d)", File, Line, Function, Message, errno); #else if ( (CallerString) && (*CallerString) ) ssnprintf(ErrBuf, ErrBufSize, "%s%s (code %d)", CallerString, Message, errno); else ssnprintf(ErrBuf, ErrBufSize, "%s (code %d)", Message, errno); #endif ErrBuf[ErrBufSize - 1]= 0; } #endif }
static int olsrd_cb_links (int lineno, /* {{{ */ size_t fields_num, char **fields) { /* Fields: * 0 = Local IP * 1 = Remote IP * 2 = Hyst. * 3 = LQ * 4 = NLQ * 5 = Cost */ static uint32_t links_num; static double lq_sum; static uint32_t lq_num; static double nlq_sum; static uint32_t nlq_num; double lq; double nlq; char *endptr; if (config_want_links == OLSRD_WANT_NOT) return (0); /* Special handling of the first line. */ if (lineno <= 0) { links_num = 0; lq_sum = 0.0; lq_num = 0; nlq_sum = 0.0; nlq_num = 0; return (0); } /* Special handling of the last line. */ if (fields_num == 0) { DEBUG ("olsrd plugin: Number of links: %"PRIu32, links_num); olsrd_submit (/* p.-inst = */ "links", /* type = */ "links", /* t.-inst = */ NULL, (gauge_t) links_num); lq = NAN; if (lq_num > 0) lq = lq_sum / ((double) lq_num); DEBUG ("olsrd plugin: Average LQ: %g", lq); olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", "average-lq", lq); nlq = NAN; if (nlq_num > 0) nlq = nlq_sum / ((double) nlq_num); DEBUG ("olsrd plugin: Average NLQ: %g", nlq); olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", "average-nlq", nlq); return (0); } if (fields_num != 6) return (-1); links_num++; errno = 0; endptr = NULL; lq = strtod (fields[3], &endptr); if ((errno != 0) || (endptr == fields[3])) { ERROR ("olsrd plugin: Cannot parse link quality: %s", fields[3]); } else { if (!isnan (lq)) { lq_sum += lq; lq_num++; } if (config_want_links == OLSRD_WANT_DETAIL) { char type_instance[DATA_MAX_NAME_LEN]; ssnprintf (type_instance, sizeof (type_instance), "%s-%s-lq", fields[0], fields[1]); DEBUG ("olsrd plugin: links: type_instance = %s; lq = %g;", type_instance, lq); olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", type_instance, lq); } } errno = 0; endptr = NULL; nlq = strtod (fields[4], &endptr); if ((errno != 0) || (endptr == fields[4])) { ERROR ("olsrd plugin: Cannot parse neighbor link quality: %s", fields[4]); } else { if (!isnan (nlq)) { nlq_sum += nlq; nlq_num++; } if (config_want_links == OLSRD_WANT_DETAIL) { char type_instance[DATA_MAX_NAME_LEN]; ssnprintf (type_instance, sizeof (type_instance), "%s-%s-rx", fields[0], fields[1]); DEBUG ("olsrd plugin: links: type_instance = %s; nlq = %g;", type_instance, lq); olsrd_submit (/* p.-inst = */ "links", /* type = */ "signal_quality", type_instance, nlq); } } return (0); } /* }}} int olsrd_cb_links */
static int o_read_database (o_database_t *db) /* {{{ */ { size_t i; int status; if (db->oci_service_context != NULL) { OCIServer *server_handle; ub4 connection_status; server_handle = NULL; status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX, (void *) &server_handle, /* size pointer = */ NULL, OCI_ATTR_SERVER, oci_error); if (status != OCI_SUCCESS) { o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet", oci_error); return (-1); } if (server_handle == NULL) { connection_status = OCI_SERVER_NOT_CONNECTED; } else /* if (server_handle != NULL) */ { connection_status = 0; status = OCIAttrGet ((void *) server_handle, OCI_HTYPE_SERVER, (void *) &connection_status, /* size pointer = */ NULL, OCI_ATTR_SERVER_STATUS, oci_error); if (status != OCI_SUCCESS) { o_report_error ("o_read_database", db->name, NULL, "OCIAttrGet", oci_error); return (-1); } } if (connection_status != OCI_SERVER_NORMAL) { INFO ("oracle plugin: Connection to %s lost. Trying to reconnect.", db->name); OCIHandleFree (db->oci_service_context, OCI_HTYPE_SVCCTX); db->oci_service_context = NULL; } } /* if (db->oci_service_context != NULL) */ if (db->oci_service_context == NULL) { status = OCILogon (oci_env, oci_error, &db->oci_service_context, (OraText *) db->username, (ub4) strlen (db->username), (OraText *) db->password, (ub4) strlen (db->password), (OraText *) db->connect_id, (ub4) strlen (db->connect_id)); if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) { char errfunc[256]; ssnprintf (errfunc, sizeof (errfunc), "OCILogon(\"%s\")", db->connect_id); o_report_error ("o_read_database", db->name, NULL, errfunc, oci_error); DEBUG ("oracle plugin: OCILogon (%s): db->oci_service_context = %p;", db->connect_id, db->oci_service_context); db->oci_service_context = NULL; return (-1); } else if (status == OCI_SUCCESS_WITH_INFO) { /* TODO: Print NOTIFY message. */ } assert (db->oci_service_context != NULL); } DEBUG ("oracle plugin: o_read_database: db->connect_id = %s; db->oci_service_context = %p;", db->connect_id, db->oci_service_context); for (i = 0; i < db->queries_num; i++) o_read_database_query (db, db->queries[i], db->q_prep_areas[i]); return (0); } /* }}} int o_read_database */
static int olsrd_cb_topology (int lineno, /* {{{ */ size_t fields_num, char **fields) { /* Fields: * 0 = Dest. IP * 1 = Last hop IP * 2 = LQ * 3 = NLQ * 4 = Cost */ static double lq_sum; static uint32_t lq_num; static uint32_t links_num; double lq; char *endptr; if (config_want_topology == OLSRD_WANT_NOT) return (0); /* Special handling of the first line */ if (lineno <= 0) { lq_sum = 0.0; lq_num = 0; links_num = 0; return (0); } /* Special handling after the last line */ if (fields_num == 0) { DEBUG ("olsrd plugin: topology: Number of links: %"PRIu32, links_num); olsrd_submit (/* p.-inst = */ "topology", /* type = */ "links", /* t.-inst = */ NULL, (gauge_t) links_num); lq = NAN; if (lq_num > 0) lq = lq_sum / ((double) lq_sum); DEBUG ("olsrd plugin: topology: Average link quality: %g", lq); olsrd_submit (/* p.-inst = */ "topology", /* type = */ "signal_quality", /* t.-inst = */ "average", lq); return (0); } if (fields_num != 5) return (-1); links_num++; errno = 0; endptr = NULL; lq = strtod (fields[2], &endptr); if ((errno != 0) || (endptr == fields[2])) { ERROR ("olsrd plugin: Unable to parse LQ: %s", fields[2]); } else { if (!isnan (lq)) { lq_sum += lq; lq_num++; } if (config_want_topology == OLSRD_WANT_DETAIL) { char type_instance[DATA_MAX_NAME_LEN]; memset (type_instance, 0, sizeof (type_instance)); ssnprintf (type_instance, sizeof (type_instance), "%s-%s-lq", fields[0], fields[1]); DEBUG ("olsrd plugin: type_instance = %s; lq = %g;", type_instance, lq); olsrd_submit (/* p.-inst = */ "topology", /* type = */ "signal_quality", type_instance, lq); } } if (config_want_topology == OLSRD_WANT_DETAIL) { double nlq; errno = 0; endptr = NULL; nlq = strtod (fields[3], &endptr); if ((errno != 0) || (endptr == fields[3])) { ERROR ("olsrd plugin: Unable to parse NLQ: %s", fields[3]); } else { char type_instance[DATA_MAX_NAME_LEN]; memset (type_instance, 0, sizeof (type_instance)); ssnprintf (type_instance, sizeof (type_instance), "%s-%s-nlq", fields[0], fields[1]); DEBUG ("olsrd plugin: type_instance = %s; nlq = %g;", type_instance, nlq); olsrd_submit (/* p.-inst = */ "topology", /* type = */ "signal_quality", type_instance, nlq); } } return (0); } /* }}} int olsrd_cb_topology */
/* Initialize db->curl */ static int cx_init_curl (cx_t *db) /* {{{ */ { db->curl = curl_easy_init (); if (db->curl == NULL) { ERROR ("curl_xml plugin: curl_easy_init failed."); return (-1); } curl_easy_setopt (db->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (db->curl, CURLOPT_WRITEFUNCTION, cx_curl_callback); curl_easy_setopt (db->curl, CURLOPT_WRITEDATA, db); curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt (db->curl, CURLOPT_URL, db->url); curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L); if (db->user != NULL) { #ifdef HAVE_CURLOPT_USERNAME curl_easy_setopt (db->curl, CURLOPT_USERNAME, db->user); curl_easy_setopt (db->curl, CURLOPT_PASSWORD, (db->pass == NULL) ? "" : db->pass); #else size_t credentials_size; credentials_size = strlen (db->user) + 2; if (db->pass != NULL) credentials_size += strlen (db->pass); db->credentials = (char *) malloc (credentials_size); if (db->credentials == NULL) { ERROR ("curl_xml plugin: malloc failed."); return (-1); } ssnprintf (db->credentials, credentials_size, "%s:%s", db->user, (db->pass == NULL) ? "" : db->pass); curl_easy_setopt (db->curl, CURLOPT_USERPWD, db->credentials); #endif if (db->digest) curl_easy_setopt (db->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); } curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYPEER, db->verify_peer ? 1L : 0L); curl_easy_setopt (db->curl, CURLOPT_SSL_VERIFYHOST, db->verify_host ? 2L : 0L); if (db->cacert != NULL) curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert); if (db->headers != NULL) curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers); if (db->post_body != NULL) curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body); #ifdef HAVE_CURLOPT_TIMEOUT_MS if (db->timeout >= 0) curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); else curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval())); #endif return (0); } /* }}} int cx_init_curl */
/* <File /> block */ static int tcsv_config_add_file(oconfig_item_t *ci) { instance_definition_t* id; int status = 0; /* Registration variables */ char cb_name[DATA_MAX_NAME_LEN]; id = calloc(1, sizeof(*id)); if (id == NULL) return (-1); id->instance = NULL; id->path = NULL; id->metric_list = NULL; id->time_from = -1; id->next = NULL; status = cf_util_get_string (ci, &id->path); if (status != 0) { sfree (id); return (status); } /* Use default interval. */ id->interval = plugin_get_interval(); for (int i = 0; i < ci->children_num; ++i){ oconfig_item_t *option = ci->children + i; status = 0; if (strcasecmp("Instance", option->key) == 0) status = cf_util_get_string(option, &id->instance); else if (strcasecmp("Collect", option->key) == 0) status = tcsv_config_add_instance_collect(id, option); else if (strcasecmp("Interval", option->key) == 0) cf_util_get_cdtime(option, &id->interval); else if (strcasecmp("TimeFrom", option->key) == 0) status = tcsv_config_get_index (option, &id->time_from); else { WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); status = -1; } if (status != 0) break; } if (status != 0){ tcsv_instance_definition_destroy(id); return (-1); } /* Verify all necessary options have been set. */ if (id->path == NULL){ WARNING("tail_csv plugin: Option `Path' must be set."); status = -1; } else if (id->metric_list == NULL){ WARNING("tail_csv plugin: Option `Collect' must be set."); status = -1; } if (status != 0){ tcsv_instance_definition_destroy(id); return (-1); } ssnprintf (cb_name, sizeof (cb_name), "tail_csv/%s", id->path); status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, &(user_data_t) { .data = id, .free_func = tcsv_instance_definition_destroy, });
/* Must hold metrics_lock when calling this function. */ static int statsd_metric_submit_unsafe (char const *name, /* {{{ */ statsd_metric_t const *metric) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "statsd", sizeof (vl.plugin)); if (metric->type == STATSD_GAUGE) sstrncpy (vl.type, "gauge", sizeof (vl.type)); else if (metric->type == STATSD_TIMER) sstrncpy (vl.type, "latency", sizeof (vl.type)); else if (metric->type == STATSD_SET) sstrncpy (vl.type, "objects", sizeof (vl.type)); else /* if (metric->type == STATSD_COUNTER) */ sstrncpy (vl.type, "derive", sizeof (vl.type)); sstrncpy (vl.type_instance, name, sizeof (vl.type_instance)); if (metric->type == STATSD_GAUGE) values[0].gauge = (gauge_t) metric->value; else if (metric->type == STATSD_TIMER) { size_t i; _Bool have_events = (metric->updates_num > 0); /* Make sure all timer metrics share the *same* timestamp. */ vl.time = cdtime (); ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-average", name); values[0].gauge = have_events ? CDTIME_T_TO_DOUBLE (latency_counter_get_average (metric->latency)) : NAN; plugin_dispatch_values (&vl); if (conf_timer_lower) { ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-lower", name); values[0].gauge = have_events ? CDTIME_T_TO_DOUBLE (latency_counter_get_min (metric->latency)) : NAN; plugin_dispatch_values (&vl); } if (conf_timer_upper) { ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-upper", name); values[0].gauge = have_events ? CDTIME_T_TO_DOUBLE (latency_counter_get_max (metric->latency)) : NAN; plugin_dispatch_values (&vl); } if (conf_timer_sum) { ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-sum", name); values[0].gauge = have_events ? CDTIME_T_TO_DOUBLE (latency_counter_get_sum (metric->latency)) : NAN; plugin_dispatch_values (&vl); } for (i = 0; i < conf_timer_percentile_num; i++) { ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-percentile-%.0f", name, conf_timer_percentile[i]); values[0].gauge = have_events ? CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (metric->latency, conf_timer_percentile[i])) : NAN; plugin_dispatch_values (&vl); } /* Keep this at the end, since vl.type is set to "gauge" here. The * vl.type's above are implicitly set to "latency". */ if (conf_timer_count) { sstrncpy (vl.type, "gauge", sizeof (vl.type)); ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s-count", name); values[0].gauge = latency_counter_get_num (metric->latency); plugin_dispatch_values (&vl); } latency_counter_reset (metric->latency); return (0); } else if (metric->type == STATSD_SET) { if (metric->set == NULL) values[0].gauge = 0.0; else values[0].gauge = (gauge_t) c_avl_size (metric->set); } else values[0].derive = (derive_t) metric->value; return (plugin_dispatch_values (&vl)); } /* }}} int statsd_metric_submit_unsafe */
static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */ oconfig_item_t *ci) { fc_rule_t *rule; char rule_name[2*DATA_MAX_NAME_LEN] = "Unnamed rule"; int status = 0; int i; if (ci->values_num > 1) { WARNING ("Filter subsystem: `Rule' blocks have at most one argument."); return (-1); } else if ((ci->values_num == 1) && (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("Filter subsystem: `Rule' blocks expect one string argument " "or no argument at all."); return (-1); } rule = (fc_rule_t *) malloc (sizeof (*rule)); if (rule == NULL) { ERROR ("fc_config_add_rule: malloc failed."); return (-1); } memset (rule, 0, sizeof (*rule)); rule->next = NULL; if (ci->values_num == 1) { sstrncpy (rule->name, ci->values[0].value.string, sizeof (rule->name)); ssnprintf (rule_name, sizeof (rule_name), "Rule \"%s\"", ci->values[0].value.string); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; status = 0; if (strcasecmp ("Match", option->key) == 0) status = fc_config_add_match (&rule->matches, option); else if (strcasecmp ("Target", option->key) == 0) status = fc_config_add_target (&rule->targets, option); else { WARNING ("Filter subsystem: %s: Option `%s' not allowed " "inside a <Rule> block.", rule_name, option->key); status = -1; } if (status != 0) break; } /* for (ci->children) */ /* Additional sanity checking. */ while (status == 0) { if (rule->targets == NULL) { WARNING ("Filter subsystem: %s: No target has been specified.", rule_name); status = -1; break; } break; } /* while (status == 0) */ if (status != 0) { fc_free_rules (rule); return (-1); } if (chain->rules != NULL) { fc_rule_t *ptr; ptr = chain->rules; while (ptr->next != NULL) ptr = ptr->next; ptr->next = rule; } else { chain->rules = rule; } return (0); } /* }}} int fc_config_add_rule */
static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ user_data_t *user_data) { camqp_config_t *conf = user_data->data; char routing_key[6 * DATA_MAX_NAME_LEN]; char buffer[8192]; int status; if ((ds == NULL) || (vl == NULL) || (conf == NULL)) return (EINVAL); memset (buffer, 0, sizeof (buffer)); if (conf->routing_key != NULL) { sstrncpy (routing_key, conf->routing_key, sizeof (routing_key)); } else { size_t i; ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s", vl->host, vl->plugin, vl->plugin_instance, vl->type, vl->type_instance); /* Switch slashes (the only character forbidden by collectd) and dots * (the separation character used by AMQP). */ for (i = 0; routing_key[i] != 0; i++) { if (routing_key[i] == '.') routing_key[i] = '/'; else if (routing_key[i] == '/') routing_key[i] = '.'; } } if (conf->format == CAMQP_FORMAT_COMMAND) { status = create_putval (buffer, sizeof (buffer), ds, vl); if (status != 0) { ERROR ("amqp plugin: create_putval failed with status %i.", status); return (status); } } else if (conf->format == CAMQP_FORMAT_JSON) { size_t bfree = sizeof (buffer); size_t bfill = 0; format_json_initialize (buffer, &bfill, &bfree); format_json_value_list (buffer, &bfill, &bfree, ds, vl, conf->store_rates); format_json_finalize (buffer, &bfill, &bfree); } else if (conf->format == CAMQP_FORMAT_GRAPHITE) { status = format_graphite (buffer, sizeof (buffer), ds, vl, conf->prefix, conf->postfix, conf->escape_char, conf->graphite_flags); if (status != 0) { ERROR ("amqp plugin: format_graphite failed with status %i.", status); return (status); } } else { ERROR ("amqp plugin: Invalid format (%i).", conf->format); return (-1); } pthread_mutex_lock (&conf->lock); status = camqp_write_locked (conf, buffer, routing_key); pthread_mutex_unlock (&conf->lock); return (status); } /* }}} int camqp_write */
static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl, char *string, size_t string_len, _Bool store_rates) { char *str_ptr; size_t str_len; gauge_t *rates = NULL; size_t i; str_ptr = string; str_len = string_len; for (i = 0; i < vl->values_len; ++i) { int status = 0; if ((ds->ds[i].type != DS_TYPE_GAUGE) && (ds->ds[i].type != DS_TYPE_COUNTER) && (ds->ds[i].type != DS_TYPE_DERIVE) && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) { log_err ("c_psql_write: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return NULL; } if (ds->ds[i].type == DS_TYPE_GAUGE) status = ssnprintf (str_ptr, str_len, ","GAUGE_FORMAT, vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { log_err ("c_psql_write: Failed to determine rate"); return NULL; } status = ssnprintf (str_ptr, str_len, ",%lf", rates[i]); } else if (ds->ds[i].type == DS_TYPE_COUNTER) status = ssnprintf (str_ptr, str_len, ",%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) status = ssnprintf (str_ptr, str_len, ",%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) status = ssnprintf (str_ptr, str_len, ",%"PRIu64, vl->values[i].absolute); if (status < 1) { str_len = 0; break; } else if ((size_t)status >= str_len) { str_len = 0; break; } else { str_ptr += status; str_len -= (size_t)status; } } sfree (rates); if (str_len <= 2) { log_err ("c_psql_write: Failed to stringify value list"); return NULL; } /* overwrite the first comma */ string[0] = '{'; str_ptr[0] = '}'; str_ptr[1] = '\0'; return string; } /* values_to_sqlarray */
static int tss2_read_vserver (vserver_list_t *vserver) { /* * Poll information for the given vserver and submit it to collect. * If vserver is NULL the global server information will be queried. */ int status; gauge_t users = NAN; gauge_t channels = NAN; gauge_t servers = NAN; counter_t rx_octets = 0; counter_t tx_octets = 0; counter_t rx_packets = 0; counter_t tx_packets = 0; gauge_t packet_loss = NAN; int valid = 0; char plugin_instance[DATA_MAX_NAME_LEN]; FILE *read_fh; FILE *write_fh; /* Get the send/receive sockets */ status = tss2_get_socket (&read_fh, &write_fh); if (status != 0) { ERROR ("teamspeak2 plugin: tss2_get_socket failed."); return (-1); } if (vserver == NULL) { /* Request global information */ memset (plugin_instance, 0, sizeof (plugin_instance)); status = tss2_send_request (write_fh, "gi\r\n"); } else { /* Request server information */ ssnprintf (plugin_instance, sizeof (plugin_instance), "vserver%i", vserver->port); /* Select the server */ status = tss2_select_vserver (read_fh, write_fh, vserver); if (status != 0) return (status); status = tss2_send_request (write_fh, "si\r\n"); } if (status != 0) { ERROR ("teamspeak2 plugin: tss2_send_request failed."); return (-1); } /* Loop until break */ while (42) { char buffer[4096]; char *key; char *value; char *endptr = NULL; /* Read one line of the server's answer */ status = tss2_receive_line (read_fh, buffer, sizeof (buffer)); if (status != 0) { /* Set to NULL just to make sure noone uses these FHs anymore. */ read_fh = NULL; write_fh = NULL; ERROR ("teamspeak2 plugin: tss2_receive_line failed."); break; } if (strncasecmp ("ERROR", buffer, 5) == 0) { ERROR ("teamspeak2 plugin: Server returned an error: %s", buffer); break; } else if (strncasecmp ("OK", buffer, 2) == 0) { break; } /* Split line into key and value */ key = strchr (buffer, '_'); if (key == NULL) { DEBUG ("teamspeak2 plugin: Cannot parse line: %s", buffer); continue; } key++; /* Evaluate assignment */ value = strchr (key, '='); if (value == NULL) { DEBUG ("teamspeak2 plugin: Cannot parse line: %s", buffer); continue; } *value = 0; value++; /* Check for known key and save the given value */ /* global info: users_online, * server info: currentusers. */ if ((strcmp ("currentusers", key) == 0) || (strcmp ("users_online", key) == 0)) { users = strtod (value, &endptr); if (value != endptr) valid |= 0x01; } /* global info: channels, * server info: currentchannels. */ else if ((strcmp ("currentchannels", key) == 0) || (strcmp ("channels", key) == 0)) { channels = strtod (value, &endptr); if (value != endptr) valid |= 0x40; } /* global only */ else if (strcmp ("servers", key) == 0) { servers = strtod (value, &endptr); if (value != endptr) valid |= 0x80; } else if (strcmp ("bytesreceived", key) == 0) { rx_octets = strtoll (value, &endptr, 0); if (value != endptr) valid |= 0x02; } else if (strcmp ("bytessend", key) == 0) { tx_octets = strtoll (value, &endptr, 0); if (value != endptr) valid |= 0x04; } else if (strcmp ("packetsreceived", key) == 0) { rx_packets = strtoll (value, &endptr, 0); if (value != endptr) valid |= 0x08; } else if (strcmp ("packetssend", key) == 0) { tx_packets = strtoll (value, &endptr, 0); if (value != endptr) valid |= 0x10; } else if ((strncmp ("allow_codec_", key, strlen ("allow_codec_")) == 0) || (strncmp ("bwinlast", key, strlen ("bwinlast")) == 0) || (strncmp ("bwoutlast", key, strlen ("bwoutlast")) == 0) || (strncmp ("webpost_", key, strlen ("webpost_")) == 0) || (strcmp ("adminemail", key) == 0) || (strcmp ("clan_server", key) == 0) || (strcmp ("countrynumber", key) == 0) || (strcmp ("id", key) == 0) || (strcmp ("ispname", key) == 0) || (strcmp ("linkurl", key) == 0) || (strcmp ("maxusers", key) == 0) || (strcmp ("name", key) == 0) || (strcmp ("password", key) == 0) || (strcmp ("platform", key) == 0) || (strcmp ("server_platform", key) == 0) || (strcmp ("server_uptime", key) == 0) || (strcmp ("server_version", key) == 0) || (strcmp ("udpport", key) == 0) || (strcmp ("uptime", key) == 0) || (strcmp ("users_maximal", key) == 0) || (strcmp ("welcomemessage", key) == 0)) /* ignore */; else { INFO ("teamspeak2 plugin: Unknown key-value-pair: " "key = %s; value = %s;", key, value); } } /* while (42) */ /* Collect vserver packet loss rates only if the loop above did not exit * with an error. */ if ((status == 0) && (vserver != NULL)) { status = tss2_vserver_gapl (read_fh, write_fh, &packet_loss); if (status == 0) { valid |= 0x20; } else { WARNING ("teamspeak2 plugin: Reading package loss " "for vserver %i failed.", vserver->port); } } if ((valid & 0x01) == 0x01) tss2_submit_gauge (plugin_instance, "users", NULL, users); if ((valid & 0x06) == 0x06) tss2_submit_io (plugin_instance, "io_octets", rx_octets, tx_octets); if ((valid & 0x18) == 0x18) tss2_submit_io (plugin_instance, "io_packets", rx_packets, tx_packets); if ((valid & 0x20) == 0x20) tss2_submit_gauge (plugin_instance, "percent", "packet_loss", packet_loss); if ((valid & 0x40) == 0x40) tss2_submit_gauge (plugin_instance, "gauge", "channels", channels); if ((valid & 0x80) == 0x80) tss2_submit_gauge (plugin_instance, "gauge", "servers", servers); if (valid == 0) return (-1); return (0); } /* int tss2_read_vserver */
static Event *riemann_value_to_protobuf (struct riemann_host const *host, /* {{{ */ data_set_t const *ds, value_list_t const *vl, size_t index, gauge_t const *rates) { Event *event; char name_buffer[5 * DATA_MAX_NAME_LEN]; char service_buffer[6 * DATA_MAX_NAME_LEN]; int i; event = malloc (sizeof (*event)); if (event == NULL) { ERROR ("write_riemann plugin: malloc failed."); return (NULL); } memset (event, 0, sizeof (*event)); event__init (event); event->host = strdup (vl->host); event->time = CDTIME_T_TO_TIME_T (vl->time); event->has_time = 1; event->ttl = CDTIME_T_TO_TIME_T (2 * vl->interval); event->has_ttl = 1; riemann_event_add_attribute (event, "plugin", vl->plugin); if (vl->plugin_instance[0] != 0) riemann_event_add_attribute (event, "plugin_instance", vl->plugin_instance); riemann_event_add_attribute (event, "type", vl->type); if (vl->type_instance[0] != 0) riemann_event_add_attribute (event, "type_instance", vl->type_instance); if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) { char ds_type[DATA_MAX_NAME_LEN]; ssnprintf (ds_type, sizeof (ds_type), "%s:rate", DS_TYPE_TO_STRING(ds->ds[index].type)); riemann_event_add_attribute (event, "ds_type", ds_type); } else { riemann_event_add_attribute (event, "ds_type", DS_TYPE_TO_STRING(ds->ds[index].type)); } riemann_event_add_attribute (event, "ds_name", ds->ds[index].name); { char ds_index[DATA_MAX_NAME_LEN]; ssnprintf (ds_index, sizeof (ds_index), "%zu", index); riemann_event_add_attribute (event, "ds_index", ds_index); } for (i = 0; i < riemann_tags_num; i++) riemann_event_add_tag (event, riemann_tags[i]); if (ds->ds[index].type == DS_TYPE_GAUGE) { event->has_metric_d = 1; event->metric_d = (double) vl->values[index].gauge; } else if (rates != NULL) { event->has_metric_d = 1; event->metric_d = (double) rates[index]; } else { event->has_metric_sint64 = 1; if (ds->ds[index].type == DS_TYPE_DERIVE) event->metric_sint64 = (int64_t) vl->values[index].derive; else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) event->metric_sint64 = (int64_t) vl->values[index].absolute; else event->metric_sint64 = (int64_t) vl->values[index].counter; } format_name (name_buffer, sizeof (name_buffer), /* host = */ "", vl->plugin, vl->plugin_instance, vl->type, vl->type_instance); if (host->always_append_ds || (ds->ds_num > 1)) ssnprintf (service_buffer, sizeof (service_buffer), "%s/%s", &name_buffer[1], ds->ds[index].name); else sstrncpy (service_buffer, &name_buffer[1], sizeof (service_buffer)); event->service = strdup (service_buffer); DEBUG ("write_riemann plugin: Successfully created protobuf for metric: " "host = \"%s\", service = \"%s\"", event->host, event->service); return (event); } /* }}} Event *riemann_value_to_protobuf */
int format_graphite (char *buffer, size_t buffer_size, data_set_t const *ds, value_list_t const *vl, char const *prefix, char const *postfix, char const escape_char, unsigned int flags) { int status = 0; int buffer_pos = 0; gauge_t *rates = NULL; if (flags & GRAPHITE_STORE_RATES) rates = uc_get_rate (ds, vl); for (size_t i = 0; i < ds->ds_num; i++) { char const *ds_name = NULL; char key[10*DATA_MAX_NAME_LEN]; char values[512]; size_t message_len; char message[1024]; if ((flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds->ds_num > 1)) ds_name = ds->ds[i].name; /* Copy the identifier to `key' and escape it. */ status = gr_format_name (key, sizeof (key), vl, ds_name, prefix, postfix, escape_char, flags); if (status != 0) { ERROR ("format_graphite: error with gr_format_name"); sfree (rates); return (status); } escape_graphite_string (key, escape_char); /* Convert the values to an ASCII representation and put that into * `values'. */ status = gr_format_values (values, sizeof (values), i, ds, vl, rates); if (status != 0) { ERROR ("format_graphite: error with gr_format_values"); sfree (rates); return (status); } /* Compute the graphite command */ message_len = (size_t) ssnprintf (message, sizeof (message), "%s %s %u\r\n", key, values, (unsigned int) CDTIME_T_TO_TIME_T (vl->time)); if (message_len >= sizeof (message)) { ERROR ("format_graphite: message buffer too small: " "Need %zu bytes.", message_len + 1); sfree (rates); return (-ENOMEM); } /* Append it in case we got multiple data set */ if ((buffer_pos + message_len) >= buffer_size) { ERROR ("format_graphite: target buffer too small"); sfree (rates); return (-ENOMEM); } memcpy((void *) (buffer + buffer_pos), message, message_len); buffer_pos += message_len; buffer[buffer_pos] = '\0'; } sfree (rates); return (status); } /* int format_graphite */
static int riemann_config_node(oconfig_item_t *ci) { struct riemann_host *host = NULL; int status = 0; int i; oconfig_item_t *child; char callback_name[DATA_MAX_NAME_LEN]; user_data_t ud; if ((host = calloc(1, sizeof (*host))) == NULL) { ERROR ("write_riemann plugin: calloc failed."); return ENOMEM; } pthread_mutex_init (&host->lock, NULL); host->reference_count = 1; host->node = NULL; host->service = NULL; host->store_rates = 1; host->always_append_ds = 0; host->use_tcp = 0; status = cf_util_get_string (ci, &host->name); if (status != 0) { WARNING("write_riemann plugin: Required host name is missing."); riemann_free (host); return -1; } for (i = 0; i < ci->children_num; i++) { /* * The code here could be simplified but makes room * for easy adding of new options later on. */ child = &ci->children[i]; status = 0; if (strcasecmp ("Host", child->key) == 0) { status = cf_util_get_string (child, &host->node); if (status != 0) break; } else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_service (child, &host->service); if (status != 0) { ERROR ("write_riemann plugin: Invalid argument " "configured for the \"Port\" " "option."); break; } } else if (strcasecmp ("Protocol", child->key) == 0) { char tmp[16]; status = cf_util_get_string_buffer (child, tmp, sizeof (tmp)); if (status != 0) { ERROR ("write_riemann plugin: cf_util_get_" "string_buffer failed with " "status %i.", status); break; } if (strcasecmp ("UDP", tmp) == 0) host->use_tcp = 0; else if (strcasecmp ("TCP", tmp) == 0) host->use_tcp = 1; else WARNING ("write_riemann plugin: The value " "\"%s\" is not valid for the " "\"Protocol\" option. Use " "either \"UDP\" or \"TCP\".", tmp); } else if (strcasecmp ("StoreRates", child->key) == 0) { status = cf_util_get_boolean (child, &host->store_rates); if (status != 0) break; } else if (strcasecmp ("AlwaysAppendDS", child->key) == 0) { status = cf_util_get_boolean (child, &host->always_append_ds); if (status != 0) break; } else { WARNING("write_riemann plugin: ignoring unknown config " "option: \"%s\"", child->key); } } if (status != 0) { riemann_free (host); return status; } ssnprintf (callback_name, sizeof (callback_name), "write_riemann/%s", host->name); ud.data = host; ud.free_func = riemann_free; pthread_mutex_lock (&host->lock); status = plugin_register_write (callback_name, riemann_write, &ud); if (status != 0) WARNING ("write_riemann plugin: plugin_register_write (\"%s\") " "failed with status %i.", callback_name, status); else /* success */ host->reference_count++; status = plugin_register_notification (callback_name, riemann_notification, &ud); if (status != 0) WARNING ("write_riemann plugin: plugin_register_notification (\"%s\") " "failed with status %i.", callback_name, status); else /* success */ host->reference_count++; if (host->reference_count <= 1) { /* Both callbacks failed => free memory. * We need to unlock here, because riemann_free() will lock. * This is not a race condition, because we're the only one * holding a reference. */ pthread_mutex_unlock (&host->lock); riemann_free (host); return (-1); } host->reference_count--; pthread_mutex_unlock (&host->lock); return status; }
/* initialize curl for each host */ static int init_host (apache_t *st) /* {{{ */ { static char credentials[1024]; assert (st->url != NULL); /* (Assured by `config_add') */ if (st->curl != NULL) { curl_easy_cleanup (st->curl); st->curl = NULL; } if ((st->curl = curl_easy_init ()) == NULL) { ERROR ("apache plugin: init_host: `curl_easy_init' failed."); return (-1); } curl_easy_setopt (st->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback); curl_easy_setopt (st->curl, CURLOPT_WRITEDATA, st); /* not set as yet if the user specified string doesn't match apache or * lighttpd, then ignore it. Headers will be parsed to find out the * server type */ st->server_type = -1; if (st->server != NULL) { if (strcasecmp(st->server, "apache") == 0) st->server_type = APACHE; else if (strcasecmp(st->server, "lighttpd") == 0) st->server_type = LIGHTTPD; else if (strcasecmp(st->server, "ibm_http_server") == 0) st->server_type = APACHE; else WARNING ("apache plugin: Unknown `Server' setting: %s", st->server); } /* if not found register a header callback to determine the server_type */ if (st->server_type == -1) { curl_easy_setopt (st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback); curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st); } curl_easy_setopt (st->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); if (st->user != NULL) { int status; status = ssnprintf (credentials, sizeof (credentials), "%s:%s", st->user, (st->pass == NULL) ? "" : st->pass); if ((status < 0) || ((size_t) status >= sizeof (credentials))) { ERROR ("apache plugin: init_host: Returning an error " "because the credentials have been " "truncated."); curl_easy_cleanup (st->curl); st->curl = NULL; return (-1); } curl_easy_setopt (st->curl, CURLOPT_USERPWD, credentials); } curl_easy_setopt (st->curl, CURLOPT_URL, st->url); curl_easy_setopt (st->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt (st->curl, CURLOPT_MAXREDIRS, 50L); if (st->verify_peer != 0) { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 1L); } else { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 0L); } if (st->verify_host != 0) { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 2L); } else { curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 0L); } if (st->cacert != NULL) { curl_easy_setopt (st->curl, CURLOPT_CAINFO, st->cacert); } return (0); } /* }}} int init_host */
static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ { mb_host_t *host; int status; int i; host = malloc (sizeof (*host)); if (host == NULL) return (ENOMEM); memset (host, 0, sizeof (*host)); host->slaves = NULL; status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host)); if (status != 0) return (status); if (host->host[0] == 0) return (EINVAL); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; status = 0; if (strcasecmp ("Address", child->key) == 0) { char buffer[NI_MAXHOST]; status = cf_util_get_string_buffer (child, buffer, sizeof (buffer)); if (status == 0) status = mb_config_set_host_address (host, buffer); } else if (strcasecmp ("Port", child->key) == 0) { host->port = cf_util_get_port_number (child); if (host->port <= 0) status = -1; } else if (strcasecmp ("Interval", child->key) == 0) status = cf_util_get_cdtime (child, &host->interval); else if (strcasecmp ("Slave", child->key) == 0) /* Don't set status: Gracefully continue if a slave fails. */ mb_config_add_slave (host, child); else { ERROR ("Modbus plugin: Unknown configuration option: %s", child->key); status = -1; } if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ assert (host->host[0] != 0); if (host->host[0] == 0) { ERROR ("Modbus plugin: Data block \"%s\": No type has been specified.", host->host); status = -1; } if (status == 0) { user_data_t ud; char name[1024]; struct timespec interval = { 0, 0 }; ud.data = host; ud.free_func = host_free; ssnprintf (name, sizeof (name), "modbus-%s", host->host); CDTIME_T_TO_TIMESPEC (host->interval, &interval); plugin_register_complex_read (/* group = */ NULL, name, /* callback = */ mb_read, /* interval = */ (host->interval > 0) ? &interval : NULL, &ud); } else { host_free (host); } return (status); } /* }}} int mb_config_add_host */