static int dstypes_to_json(char *buffer, size_t buffer_size, /* {{{ */ const data_set_t *ds) { size_t offset = 0; memset(buffer, 0, buffer_size); #define BUFFER_ADD(...) \ do { \ int status; \ status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \ if (status < 1) \ return (-1); \ else if (((size_t)status) >= (buffer_size - offset)) \ return (-ENOMEM); \ else \ offset += ((size_t)status); \ } while (0) BUFFER_ADD("["); for (size_t i = 0; i < ds->ds_num; i++) { if (i > 0) BUFFER_ADD(","); BUFFER_ADD("\"%s\"", DS_TYPE_TO_STRING(ds->ds[i].type)); } /* for ds->ds_num */ BUFFER_ADD("]"); #undef BUFFER_ADD DEBUG("format_json: dstypes_to_json: buffer = %s;", buffer); return (0); } /* }}} int dstypes_to_json */
static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ mb_data_t *data) { uint16_t values[2] = { 0 }; int values_num; const data_set_t *ds; int status = 0; if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); ds = plugin_get_ds (data->type); if (ds == NULL) { ERROR ("Modbus plugin: Type \"%s\" is not defined.", data->type); return (-1); } if (ds->ds_num != 1) { ERROR ("Modbus plugin: The type \"%s\" has %zu data sources. " "I can only handle data sets with only one data source.", data->type, ds->ds_num); return (-1); } if ((ds->ds[0].type != DS_TYPE_GAUGE) && (data->register_type != REG_TYPE_INT32) && (data->register_type != REG_TYPE_UINT32)) { NOTICE ("Modbus plugin: The data source of type \"%s\" is %s, not gauge. " "This will most likely result in problems, because the register type " "is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type)); } if ((data->register_type == REG_TYPE_INT32) || (data->register_type == REG_TYPE_UINT32) || (data->register_type == REG_TYPE_FLOAT)) values_num = 2; else values_num = 1; if (host->connection == NULL) { status = EBADF; } else if (host->conntype == MBCONN_TCP) { /* getpeername() is used only to determine if the socket is connected, not * because we're really interested in the peer's IP address. */ status = getpeername (modbus_get_socket (host->connection), (struct sockaddr *) &(struct sockaddr_storage) { 0 }, &(socklen_t) { sizeof (struct sockaddr_storage) }); if (status != 0) status = errno; }
static char *values_type_to_sqlarray (const data_set_t *ds, char *string, size_t string_len, _Bool store_rates) { char *str_ptr; size_t str_len; int i; str_ptr = string; str_len = string_len; for (i = 0; i < ds->ds_num; ++i) { int status; if (store_rates) status = ssnprintf(str_ptr, str_len, ",'gauge'"); else status = ssnprintf(str_ptr, str_len, ",'%s'", DS_TYPE_TO_STRING (ds->ds[i].type)); 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; } } if (str_len <= 2) { log_err ("c_psql_write: Failed to stringify value types"); return NULL; } /* overwrite the first comma */ string[0] = '{'; str_ptr[0] = '}'; str_ptr[1] = '\0'; return string; } /* values_type_to_sqlarray */
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 */
static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ mb_data_t *data) { uint16_t values[2]; int values_num; const data_set_t *ds; int status; int i; if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); ds = plugin_get_ds (data->type); if (ds == NULL) { ERROR ("Modbus plugin: Type \"%s\" is not defined.", data->type); return (-1); } if (ds->ds_num != 1) { ERROR ("Modbus plugin: The type \"%s\" has %i data sources. " "I can only handle data sets with only one data source.", data->type, ds->ds_num); return (-1); } if ((ds->ds[0].type != DS_TYPE_GAUGE) && (data->register_type != REG_TYPE_UINT32)) { NOTICE ("Modbus plugin: The data source of type \"%s\" is %s, not gauge. " "This will most likely result in problems, because the register type " "is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type)); } memset (values, 0, sizeof (values)); if ((data->register_type == REG_TYPE_UINT32) || (data->register_type == REG_TYPE_FLOAT)) values_num = 2; else values_num = 1; #if LEGACY_LIBMODBUS /* Version 2.0.3: Pass the connection struct as a pointer and pass the slave * id to each call of "read_holding_registers". */ # define modbus_read_registers(ctx, addr, nb, dest) \ read_holding_registers (&(ctx), slave->id, (addr), (nb), (dest)) #else /* if !LEGACY_LIBMODBUS */ /* Version 2.9.2: Set the slave id once before querying the registers. */ status = modbus_set_slave (host->connection, slave->id); if (status != 0) { ERROR ("Modbus plugin: modbus_set_slave (%i) failed with status %i.", slave->id, status); return (-1); } #endif for (i = 0; i < 2; i++) { status = modbus_read_registers (host->connection, /* start_addr = */ data->register_base, /* num_registers = */ values_num, /* buffer = */ values); if (status > 0) break; if (host->is_connected) { #if LEGACY_LIBMODBUS modbus_close (&host->connection); host->is_connected = 0; #else modbus_close (host->connection); modbus_free (host->connection); host->connection = NULL; #endif } /* If we already tried reconnecting this round, give up. */ if (host->have_reconnected) { ERROR ("Modbus plugin: modbus_read_registers (%s) failed. " "Reconnecting has already been tried. Giving up.", host->host); return (-1); } /* Maybe the device closed the connection during the waiting interval. * Try re-establishing the connection. */ status = mb_init_connection (host); if (status != 0) { ERROR ("Modbus plugin: modbus_read_registers (%s) failed. " "While trying to reconnect, connecting to \"%s\" failed. " "Giving up.", host->host, host->node); return (-1); } DEBUG ("Modbus plugin: Re-established connection to %s", host->host); /* try again */ continue; } /* for (i = 0, 1) */ DEBUG ("Modbus plugin: mb_read_data: Success! " "modbus_read_registers returned with status %i.", status); if (data->register_type == REG_TYPE_FLOAT) { float float_value; value_t vt; float_value = mb_register_to_float (values[0], values[1]); DEBUG ("Modbus plugin: mb_read_data: " "Returned float value is %g", (double) float_value); CAST_TO_VALUE_T (ds, vt, float_value); mb_submit (host, slave, data, vt); } else if (data->register_type == REG_TYPE_UINT32) { uint32_t v32; value_t vt; v32 = (values[0] << 16) | values[1]; DEBUG ("Modbus plugin: mb_read_data: " "Returned uint32 value is %"PRIu32, v32); CAST_TO_VALUE_T (ds, vt, v32); mb_submit (host, slave, data, vt); } else /* if (data->register_type == REG_TYPE_UINT16) */ { value_t vt; DEBUG ("Modbus plugin: mb_read_data: " "Returned uint16 value is %"PRIu16, values[0]); CAST_TO_VALUE_T (ds, vt, values[0]); mb_submit (host, slave, data, vt); } return (0); } /* }}} int mb_read_data */
/* * Result private functions */ static int udb_result_submit (udb_result_t *r, /* {{{ */ udb_result_preparation_area_t *r_area, udb_query_t const *q, udb_query_preparation_area_t *q_area) { value_list_t vl = VALUE_LIST_INIT; size_t i; int status; assert (r != NULL); assert (r_area->ds != NULL); assert (((size_t) r_area->ds->ds_num) == r->values_num); assert (r->values_num > 0); vl.values = calloc (r->values_num, sizeof (*vl.values)); if (vl.values == NULL) { ERROR ("db query utils: calloc failed."); return (-1); } vl.values_len = r_area->ds->ds_num; for (i = 0; i < r->values_num; i++) { char *value_str = r_area->values_buffer[i]; if (0 != parse_value (value_str, &vl.values[i], r_area->ds->ds[i].type)) { ERROR ("db query utils: udb_result_submit: Parsing `%s' as %s failed.", value_str, DS_TYPE_TO_STRING (r_area->ds->ds[i].type)); errno = EINVAL; free (vl.values); return (-1); } } if (q_area->interval > 0) vl.interval = q_area->interval; sstrncpy (vl.host, q_area->host, sizeof (vl.host)); sstrncpy (vl.plugin, q_area->plugin, sizeof (vl.plugin)); sstrncpy (vl.type, r->type, sizeof (vl.type)); /* Set vl.plugin_instance */ if (q->plugin_instance_from != NULL) { sstrncpy (vl.plugin_instance, r_area->plugin_instance, sizeof (vl.plugin_instance)); } else { sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance)); } /* Set vl.type_instance {{{ */ if (r->instances_num == 0) { if (r->instance_prefix == NULL) vl.type_instance[0] = 0; else sstrncpy (vl.type_instance, r->instance_prefix, sizeof (vl.type_instance)); } else /* if ((r->instances_num > 0) */ { if (r->instance_prefix == NULL) { strjoin (vl.type_instance, sizeof (vl.type_instance), r_area->instances_buffer, r->instances_num, "-"); } else { char tmp[DATA_MAX_NAME_LEN]; strjoin (tmp, sizeof (tmp), r_area->instances_buffer, r->instances_num, "-"); tmp[sizeof (tmp) - 1] = 0; snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s", r->instance_prefix, tmp); } } vl.type_instance[sizeof (vl.type_instance) - 1] = 0; /* }}} */ /* Annotate meta data. {{{ */ if (r->metadata_num > 0) { vl.meta = meta_data_create (); if (vl.meta == NULL) { ERROR ("db query utils:: meta_data_create failed."); return (-ENOMEM); } for (i = 0; i < r->metadata_num; i++) { status = meta_data_add_string (vl.meta, r->metadata[i], r_area->metadata_buffer[i]); if (status != 0) { ERROR ("db query utils:: meta_data_add_string failed."); meta_data_destroy (vl.meta); vl.meta = NULL; return (status); } } } /* }}} */ plugin_dispatch_values (&vl); if (r->metadata_num > 0) { meta_data_destroy (vl.meta); vl.meta = NULL; } sfree (vl.values); return (0); } /* }}} void udb_result_submit */
static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ data_set_t const *ds, value_list_t const *vl, size_t index, gauge_t const *rates, int status) { char name_buffer[5 * DATA_MAX_NAME_LEN]; char service_buffer[6 * DATA_MAX_NAME_LEN]; size_t i; char *ret_str; char *temp_str; char *value_str; int res; // First part of the JSON string const char *part1 = "{\"name\": \"collectd\", \"type\": \"metric\""; char *handlers_str = build_json_str_list("handlers", &(host->metric_handlers)); if (handlers_str == NULL) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } // incorporate the handlers if (strlen(handlers_str) == 0) { free(handlers_str); ret_str = strdup(part1); if (ret_str == NULL) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else { res = asprintf(&ret_str, "%s, %s", part1, handlers_str); free(handlers_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } // incorporate the plugin name information res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; // incorporate the plugin type res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; // incorporate the plugin instance if any if (vl->plugin_instance[0] != 0) { res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } // incorporate the plugin type instance if any if (vl->type_instance[0] != 0) { res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } // incorporate the data source type 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)); res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } else { res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type)); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } // incorporate the data source name res = asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; // incorporate the data source index { char ds_index[DATA_MAX_NAME_LEN]; ssnprintf (ds_index, sizeof (ds_index), "%zu", index); res = asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } // add key value attributes from config if any for (i = 0; i < sensu_attrs_num; i += 2) { res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } // incorporate sensu tags from config if any if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) { res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags); free(ret_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; } // calculate the value and set to a string if (ds->ds[index].type == DS_TYPE_GAUGE) { res = asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else if (rates != NULL) { res = asprintf(&value_str, GAUGE_FORMAT, rates[index]); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else { if (ds->ds[index].type == DS_TYPE_DERIVE) { res = asprintf(&value_str, "%"PRIi64, vl->values[index].derive); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) { res = asprintf(&value_str, "%"PRIu64, vl->values[index].absolute); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else { res = asprintf(&value_str, "%llu", vl->values[index].counter); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } } // Generate the full service name sensu_format_name2(name_buffer, sizeof(name_buffer), vl->host, vl->plugin, vl->plugin_instance, vl->type, vl->type_instance, host->separator); if (host->always_append_ds || (ds->ds_num > 1)) { if (host->event_service_prefix == NULL) ssnprintf(service_buffer, sizeof(service_buffer), "%s.%s", name_buffer, ds->ds[index].name); else ssnprintf(service_buffer, sizeof(service_buffer), "%s%s.%s", host->event_service_prefix, name_buffer, ds->ds[index].name); } else { if (host->event_service_prefix == NULL) sstrncpy(service_buffer, name_buffer, sizeof(service_buffer)); else ssnprintf(service_buffer, sizeof(service_buffer), "%s%s", host->event_service_prefix, name_buffer); } // Replace collectd sensor name reserved characters so that time series DB is happy in_place_replace_sensu_name_reserved(service_buffer); // finalize the buffer by setting the output and closing curly bracket res = asprintf(&temp_str, "%s, \"output\": \"%s %s %ld\"}\n", ret_str, service_buffer, value_str, CDTIME_T_TO_TIME_T(vl->time)); free(ret_str); free(value_str); if (res == -1) { ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } ret_str = temp_str; DEBUG("write_sensu plugin: Successfully created json for metric: " "host = \"%s\", service = \"%s\"", vl->host, service_buffer); return ret_str; } /* }}} char *sensu_value_to_json */
static riemann_event_t * wrr_value_to_event(struct riemann_host const *host, /* {{{ */ data_set_t const *ds, value_list_t const *vl, size_t index, gauge_t const *rates, int status) { riemann_event_t *event; char name_buffer[5 * DATA_MAX_NAME_LEN]; char service_buffer[6 * DATA_MAX_NAME_LEN]; size_t i; event = riemann_event_new(); if (event == NULL) { ERROR("write_riemann plugin: riemann_event_new() failed."); return NULL; } 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)) { if (host->event_service_prefix == NULL) snprintf(service_buffer, sizeof(service_buffer), "%s/%s", &name_buffer[1], ds->ds[index].name); else snprintf(service_buffer, sizeof(service_buffer), "%s%s/%s", host->event_service_prefix, &name_buffer[1], ds->ds[index].name); } else { if (host->event_service_prefix == NULL) sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer)); else snprintf(service_buffer, sizeof(service_buffer), "%s%s", host->event_service_prefix, &name_buffer[1]); } riemann_event_set( event, RIEMANN_EVENT_FIELD_HOST, vl->host, RIEMANN_EVENT_FIELD_TIME, (int64_t)CDTIME_T_TO_TIME_T(vl->time), RIEMANN_EVENT_FIELD_TTL, (float)CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor, RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES, "plugin", vl->plugin, "type", vl->type, "ds_name", ds->ds[index].name, NULL, RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE); #if RCC_VERSION_NUMBER >= 0x010A00 riemann_event_set(event, RIEMANN_EVENT_FIELD_TIME_MICROS, (int64_t)CDTIME_T_TO_US(vl->time)); #endif if (host->check_thresholds) { const char *state = NULL; switch (status) { case STATE_OKAY: state = "ok"; break; case STATE_ERROR: state = "critical"; break; case STATE_WARNING: state = "warning"; break; case STATE_MISSING: state = "unknown"; break; } if (state) riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state, RIEMANN_EVENT_FIELD_NONE); } if (vl->plugin_instance[0] != 0) riemann_event_string_attribute_add(event, "plugin_instance", vl->plugin_instance); if (vl->type_instance[0] != 0) riemann_event_string_attribute_add(event, "type_instance", vl->type_instance); if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) { char ds_type[DATA_MAX_NAME_LEN]; snprintf(ds_type, sizeof(ds_type), "%s:rate", DS_TYPE_TO_STRING(ds->ds[index].type)); riemann_event_string_attribute_add(event, "ds_type", ds_type); } else { riemann_event_string_attribute_add(event, "ds_type", DS_TYPE_TO_STRING(ds->ds[index].type)); } { char ds_index[DATA_MAX_NAME_LEN]; snprintf(ds_index, sizeof(ds_index), "%" PRIsz, index); riemann_event_string_attribute_add(event, "ds_index", ds_index); } for (i = 0; i < riemann_attrs_num; i += 2) riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i + 1]); for (i = 0; i < riemann_tags_num; i++) riemann_event_tag_add(event, riemann_tags[i]); if (ds->ds[index].type == DS_TYPE_GAUGE) { riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)vl->values[index].gauge, RIEMANN_EVENT_FIELD_NONE); } else if (rates != NULL) { riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)rates[index], RIEMANN_EVENT_FIELD_NONE); } else { int64_t metric; if (ds->ds[index].type == DS_TYPE_DERIVE) metric = (int64_t)vl->values[index].derive; else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) metric = (int64_t)vl->values[index].absolute; else metric = (int64_t)vl->values[index].counter; riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_S64, (int64_t)metric, RIEMANN_EVENT_FIELD_NONE); } DEBUG("write_riemann plugin: Successfully created message for metric: " "host = \"%s\", service = \"%s\"", event->host, event->service); return event; } /* }}} riemann_event_t *wrr_value_to_event */
/* TODO: Check if negative values wrap around. Problem: negative temperatures. */ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, double scale, double shift, const char *host_name, const char *data_name) { value_t ret; uint64_t tmp_unsigned = 0; int64_t tmp_signed = 0; _Bool defined = 1; /* Set to true when the original SNMP type appears to have been signed. */ _Bool prefer_signed = 0; if ((vl->type == ASN_INTEGER) || (vl->type == ASN_UINTEGER) || (vl->type == ASN_COUNTER) #ifdef ASN_TIMETICKS || (vl->type == ASN_TIMETICKS) #endif || (vl->type == ASN_GAUGE)) { tmp_unsigned = (uint32_t) *vl->val.integer; tmp_signed = (int32_t) *vl->val.integer; if (vl->type == ASN_INTEGER) prefer_signed = 1; DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned); } else if (vl->type == ASN_COUNTER64) { tmp_unsigned = (uint32_t) vl->val.counter64->high; tmp_unsigned = tmp_unsigned << 32; tmp_unsigned += (uint32_t) vl->val.counter64->low; tmp_signed = (int64_t) tmp_unsigned; DEBUG ("snmp plugin: Parsed int64 value is %"PRIu64".", tmp_unsigned); } else if (vl->type == ASN_OCTET_STR) { /* We'll handle this later.. */ } else { char oid_buffer[1024]; memset (oid_buffer, 0, sizeof (oid_buffer)); snprint_objid (oid_buffer, sizeof (oid_buffer) - 1, vl->name, vl->name_length); #ifdef ASN_NULL if (vl->type == ASN_NULL) INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)", oid_buffer); else #endif WARNING ("snmp plugin: I don't know the ASN type #%i " "(OID: \"%s\", data block \"%s\", host block \"%s\")", (int) vl->type, oid_buffer, (data_name != NULL) ? data_name : "UNKNOWN", (host_name != NULL) ? host_name : "UNKNOWN"); defined = 0; } if (vl->type == ASN_OCTET_STR) { int status = -1; if (vl->val.string != NULL) { char string[64]; size_t string_length; string_length = sizeof (string) - 1; if (vl->val_len < string_length) string_length = vl->val_len; /* The strings we get from the Net-SNMP library may not be null * terminated. That is why we're using `memcpy' here and not `strcpy'. * `string_length' is set to `vl->val_len' which holds the length of the * string. -octo */ memcpy (string, vl->val.string, string_length); string[string_length] = 0; status = parse_value (string, &ret, type); if (status != 0) { ERROR ("snmp plugin: host %s: csnmp_value_list_to_value: Parsing string as %s failed: %s", (host_name != NULL) ? host_name : "UNKNOWN", DS_TYPE_TO_STRING (type), string); } } if (status != 0) { switch (type) { case DS_TYPE_COUNTER: case DS_TYPE_DERIVE: case DS_TYPE_ABSOLUTE: memset (&ret, 0, sizeof (ret)); break; case DS_TYPE_GAUGE: ret.gauge = NAN; break; default: ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown " "data source type: %i.", type); ret.gauge = NAN; } } } /* if (vl->type == ASN_OCTET_STR) */ else if (type == DS_TYPE_COUNTER) { ret.counter = tmp_unsigned; } else if (type == DS_TYPE_GAUGE) { if (!defined) ret.gauge = NAN; else if (prefer_signed) ret.gauge = (scale * tmp_signed) + shift; else ret.gauge = (scale * tmp_unsigned) + shift; } else if (type == DS_TYPE_DERIVE) { if (prefer_signed) ret.derive = (derive_t) tmp_signed; else ret.derive = (derive_t) tmp_unsigned; } else if (type == DS_TYPE_ABSOLUTE) { ret.absolute = (absolute_t) tmp_unsigned; } else { ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source " "type: %i.", type); ret.gauge = NAN; } return (ret); } /* value_t csnmp_value_list_to_value */
/* * Functions */ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */ const value_list_t *vl, _Bool store_rates) { bson *ret; gauge_t *rates; ret = bson_alloc (); /* matched by bson_dealloc() */ if (ret == NULL) { ERROR ("write_mongodb plugin: bson_create failed."); return (NULL); } if (store_rates) { rates = uc_get_rate (ds, vl); if (rates == NULL) { ERROR ("write_mongodb plugin: uc_get_rate() failed."); return (NULL); } } else { rates = NULL; } bson_init (ret); /* matched by bson_destroy() */ bson_append_date (ret, "time", (bson_date_t) CDTIME_T_TO_MS (vl->time)); bson_append_string (ret, "host", vl->host); bson_append_string (ret, "plugin", vl->plugin); bson_append_string (ret, "plugin_instance", vl->plugin_instance); bson_append_string (ret, "type", vl->type); bson_append_string (ret, "type_instance", vl->type_instance); bson_append_start_array (ret, "values"); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); if (ds->ds[i].type == DS_TYPE_GAUGE) bson_append_double(ret, key, vl->values[i].gauge); else if (store_rates) bson_append_double(ret, key, (double) rates[i]); else if (ds->ds[i].type == DS_TYPE_COUNTER) bson_append_long(ret, key, vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_DERIVE) bson_append_long(ret, key, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) bson_append_long(ret, key, vl->values[i].absolute); else assert (23 == 42); } bson_append_finish_array (ret); /* }}} values */ bson_append_start_array (ret, "dstypes"); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); if (store_rates) bson_append_string (ret, key, "gauge"); else bson_append_string (ret, key, DS_TYPE_TO_STRING (ds->ds[i].type)); } bson_append_finish_array (ret); /* }}} dstypes */ bson_append_start_array (ret, "dsnames"); /* {{{ */ for (int i = 0; i < ds->ds_num; i++) { char key[16]; ssnprintf (key, sizeof (key), "%i", i); bson_append_string (ret, key, ds->ds[i].name); } bson_append_finish_array (ret); /* }}} dsnames */ bson_finish (ret); sfree (rates); return (ret); } /* }}} bson *wm_create_bson */
static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */ mb_data_t *data) { uint16_t values[2]; int values_num; const data_set_t *ds; int status; if ((host == NULL) || (slave == NULL) || (data == NULL)) return (EINVAL); ds = plugin_get_ds (data->type); if (ds == NULL) { ERROR ("Modbus plugin: Type \"%s\" is not defined.", data->type); return (-1); } if (ds->ds_num != 1) { ERROR ("Modbus plugin: The type \"%s\" has %i data sources. " "I can only handle data sets with only one data source.", data->type, ds->ds_num); return (-1); } if ((ds->ds[0].type != DS_TYPE_GAUGE) && (data->register_type != REG_TYPE_INT32) && (data->register_type != REG_TYPE_UINT32)) { NOTICE ("Modbus plugin: The data source of type \"%s\" is %s, not gauge. " "This will most likely result in problems, because the register type " "is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type)); } memset (values, 0, sizeof (values)); if ((data->register_type == REG_TYPE_INT32) || (data->register_type == REG_TYPE_UINT32) || (data->register_type == REG_TYPE_FLOAT)) values_num = 2; else values_num = 1; status = 0; if (host->connection == NULL) { status = EBADF; } else if (host->conntype == MBCONN_TCP) { struct sockaddr sockaddr; socklen_t saddrlen = sizeof (sockaddr); status = getpeername (modbus_get_socket (host->connection), &sockaddr, &saddrlen); if (status != 0) status = errno; } if ((status == EBADF) || (status == ENOTSOCK) || (status == ENOTCONN)) { status = mb_init_connection (host); if (status != 0) { ERROR ("Modbus plugin: mb_init_connection (%s/%s) failed. ", host->host, host->node); host->is_connected = 0; host->connection = NULL; return (-1); } } else if (status != 0) { #if LEGACY_LIBMODBUS modbus_close (&host->connection); #else modbus_close (host->connection); modbus_free (host->connection); #endif } #if LEGACY_LIBMODBUS /* Version 2.0.3: Pass the connection struct as a pointer and pass the slave * id to each call of "read_holding_registers". */ # define modbus_read_registers(ctx, addr, nb, dest) \ read_holding_registers (&(ctx), slave->id, (addr), (nb), (dest)) #else /* if !LEGACY_LIBMODBUS */ /* Version 2.9.2: Set the slave id once before querying the registers. */ status = modbus_set_slave (host->connection, slave->id); if (status != 0) { ERROR ("Modbus plugin: modbus_set_slave (%i) failed with status %i.", slave->id, status); return (-1); } #endif if (data->modbus_register_type == MREG_INPUT){ status = modbus_read_input_registers (host->connection, /* start_addr = */ data->register_base, /* num_registers = */ values_num, /* buffer = */ values); } else{ status = modbus_read_registers (host->connection, /* start_addr = */ data->register_base, /* num_registers = */ values_num, /* buffer = */ values); } if (status != values_num) { ERROR ("Modbus plugin: modbus read function (%s/%s) failed. " " status = %i, values_num = %i. Giving up.", host->host, host->node, status, values_num); #if LEGACY_LIBMODBUS modbus_close (&host->connection); #else modbus_close (host->connection); modbus_free (host->connection); #endif host->connection = NULL; return (-1); } DEBUG ("Modbus plugin: mb_read_data: Success! " "modbus_read_registers returned with status %i.", status); if (data->register_type == REG_TYPE_FLOAT) { float float_value; value_t vt; float_value = mb_register_to_float (values[0], values[1]); DEBUG ("Modbus plugin: mb_read_data: " "Returned float value is %g", (double) float_value); CAST_TO_VALUE_T (ds, vt, float_value); mb_submit (host, slave, data, vt); } else if (data->register_type == REG_TYPE_INT32) { union { uint32_t u32; int32_t i32; } v; value_t vt; v.u32 = (((uint32_t) values[0]) << 16) | ((uint32_t) values[1]); DEBUG ("Modbus plugin: mb_read_data: " "Returned int32 value is %"PRIi32, v.i32); CAST_TO_VALUE_T (ds, vt, v.i32); mb_submit (host, slave, data, vt); } else if (data->register_type == REG_TYPE_INT16) { union { uint16_t u16; int16_t i16; } v; value_t vt; v.u16 = values[0]; DEBUG ("Modbus plugin: mb_read_data: " "Returned int16 value is %"PRIi16, v.i16); CAST_TO_VALUE_T (ds, vt, v.i16); mb_submit (host, slave, data, vt); } else if (data->register_type == REG_TYPE_UINT32) { uint32_t v32; value_t vt; v32 = (((uint32_t) values[0]) << 16) | ((uint32_t) values[1]); DEBUG ("Modbus plugin: mb_read_data: " "Returned uint32 value is %"PRIu32, v32); CAST_TO_VALUE_T (ds, vt, v32); mb_submit (host, slave, data, vt); } else /* if (data->register_type == REG_TYPE_UINT16) */ { value_t vt; DEBUG ("Modbus plugin: mb_read_data: " "Returned uint16 value is %"PRIu16, values[0]); CAST_TO_VALUE_T (ds, vt, values[0]); mb_submit (host, slave, data, vt); } return (0); } /* }}} int mb_read_data */