int prev_process_info__compute_load(cdtime_t tm, pid_t pid, unsigned long stime, unsigned long utime, unsigned long *spercent, unsigned long *upercent) { /* {{{ */ /* Notes : * stime and utime are provided in machine unit (time or ticks) and will be converted in seconds here * tm is provided in cdtime_t (and will be converted into seconds here) * result values spercent and upercent are percent values * this function returns 0 if spercent and upercernt are meaningful. */ prev_process_info_t *info; if(NULL == (info = g_tree_lookup(prev_process_info, GINT_TO_POINTER(pid)))) { info = g_slice_alloc(sizeof(*info)); info->tm = tm; info->stime = stime; info->utime = utime; g_tree_insert(prev_process_info, GINT_TO_POINTER(pid), info); *spercent = 0; *upercent = 0; return(-1); } *spercent = TICKS_TO_SECONDS((100 * (stime - info->stime)) / CDTIME_T_TO_TIME_T(tm - info->tm)); *upercent = TICKS_TO_SECONDS((100 * (utime - info->utime)) / CDTIME_T_TO_TIME_T(tm - info->tm)); info->stime = stime; info->utime = utime; info->tm = tm; return(0); } /* }}} */
static int value_list_to_string (char *buffer, int buffer_len, const data_set_t *ds, const value_list_t *vl) { int offset; int status; size_t i; time_t t; assert (0 == strcmp (ds->type, vl->type)); memset (buffer, '\0', buffer_len); t = CDTIME_T_TO_TIME_T (vl->time); status = ssnprintf (buffer, buffer_len, "%lu", (unsigned long) t); if ((status < 1) || (status >= buffer_len)) return (-1); offset = status; for (i = 0; i < ds->ds_num; i++) { if ((ds->ds[i].type != DS_TYPE_COUNTER) && (ds->ds[i].type != DS_TYPE_GAUGE) && (ds->ds[i].type != DS_TYPE_DERIVE) && (ds->ds[i].type != DS_TYPE_ABSOLUTE)) return (-1); if (ds->ds[i].type == DS_TYPE_COUNTER) { status = ssnprintf (buffer + offset, buffer_len - offset, ":%llu", vl->values[i].counter); } else if (ds->ds[i].type == DS_TYPE_GAUGE) { status = ssnprintf (buffer + offset, buffer_len - offset, ":%f", vl->values[i].gauge); } else if (ds->ds[i].type == DS_TYPE_DERIVE) { status = ssnprintf (buffer + offset, buffer_len - offset, ":%"PRIi64, vl->values[i].derive); } else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ { status = ssnprintf (buffer + offset, buffer_len - offset, ":%"PRIu64, vl->values[i].absolute); } if ((status < 1) || (status >= (buffer_len - offset))) return (-1); offset += status; } /* for ds->ds_num */ return (0); } /* int value_list_to_string */
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; } sfree (rates); return (status); } /* int format_graphite */
static void log_logstash_print (yajl_gen g, int severity, cdtime_t timestamp_time) { FILE *fh; _Bool do_close = 0; struct tm timestamp_tm; char timestamp_str[64]; const unsigned char *buf; time_t tt; #if HAVE_YAJL_V2 size_t len; #else unsigned int len; #endif if (yajl_gen_string(g, (u_char *)"@level", strlen("@level")) != yajl_gen_status_ok) goto err; switch (severity) { case LOG_ERR: if (yajl_gen_string(g, (u_char *)"error", strlen("error")) != yajl_gen_status_ok) goto err; break; case LOG_WARNING: if (yajl_gen_string(g, (u_char *)"warning", strlen("warning")) != yajl_gen_status_ok) goto err; break; case LOG_NOTICE: if (yajl_gen_string(g, (u_char *)"notice", strlen("notice")) != yajl_gen_status_ok) goto err; break; case LOG_INFO: if (yajl_gen_string(g, (u_char *)"info", strlen("info")) != yajl_gen_status_ok) goto err; break; case LOG_DEBUG: if (yajl_gen_string(g, (u_char *)"debug", strlen("debug")) != yajl_gen_status_ok) goto err; break; default: if (yajl_gen_string(g, (u_char *)"unknown", strlen("unknown")) != yajl_gen_status_ok) goto err; break; } if (yajl_gen_string(g, (u_char *)"@timestamp", strlen("@timestamp")) != yajl_gen_status_ok) goto err; tt = CDTIME_T_TO_TIME_T (timestamp_time); gmtime_r (&tt, ×tamp_tm); /* * format time as a UTC ISO 8601 compliant string */ strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%SZ", ×tamp_tm); timestamp_str[sizeof (timestamp_str) - 1] = '\0'; if (yajl_gen_string(g, (u_char *)timestamp_str, strlen(timestamp_str)) != yajl_gen_status_ok) goto err; if (yajl_gen_map_close(g) != yajl_gen_status_ok) goto err; if (yajl_gen_get_buf(g, &buf, &len) != yajl_gen_status_ok) goto err; pthread_mutex_lock (&file_lock); if (log_file == NULL) { fh = fopen (DEFAULT_LOGFILE, "a"); do_close = 1; } else if (strcasecmp(log_file, "stdout") == 0) { fh = stdout; do_close = 0; } else if (strcasecmp(log_file, "stderr") == 0) { fh = stderr; do_close = 0; } else { fh = fopen (log_file, "a"); do_close = 1; } if (fh == NULL) { char errbuf[1024]; fprintf (stderr, "log_logstash plugin: fopen (%s) failed: %s\n", (log_file == NULL) ? DEFAULT_LOGFILE : log_file, sstrerror (errno, errbuf, sizeof (errbuf))); } else { fprintf(fh, "%s\n", buf); if (do_close) { fclose (fh); } else { fflush(fh); } } pthread_mutex_unlock (&file_lock); yajl_gen_free(g); return; err: yajl_gen_free(g); fprintf(stderr, "Could not correctly generate JSON message\n"); return; } /* void log_logstash_print */
static void logfile_print (const char *msg, int severity, cdtime_t timestamp_time) { FILE *fh; _Bool do_close = 0; struct tm timestamp_tm; char timestamp_str[64]; char level_str[16] = ""; if (print_severity) { switch (severity) { case LOG_ERR: snprintf(level_str, sizeof (level_str), "[error] "); break; case LOG_WARNING: snprintf(level_str, sizeof (level_str), "[warning] "); break; case LOG_NOTICE: snprintf(level_str, sizeof (level_str), "[notice] "); break; case LOG_INFO: snprintf(level_str, sizeof (level_str), "[info] "); break; case LOG_DEBUG: snprintf(level_str, sizeof (level_str), "[debug] "); break; default: break; } } if (print_timestamp) { time_t tt = CDTIME_T_TO_TIME_T (timestamp_time); localtime_r (&tt, ×tamp_tm); strftime (timestamp_str, sizeof (timestamp_str), "%Y-%m-%d %H:%M:%S", ×tamp_tm); timestamp_str[sizeof (timestamp_str) - 1] = '\0'; } pthread_mutex_lock (&file_lock); if (log_file == NULL) { fh = fopen (DEFAULT_LOGFILE, "a"); do_close = 1; } else if (strcasecmp (log_file, "stderr") == 0) fh = stderr; else if (strcasecmp (log_file, "stdout") == 0) fh = stdout; else { fh = fopen (log_file, "a"); do_close = 1; } if (fh == NULL) { char errbuf[1024]; fprintf (stderr, "logfile plugin: fopen (%s) failed: %s\n", (log_file == NULL) ? DEFAULT_LOGFILE : log_file, sstrerror (errno, errbuf, sizeof (errbuf))); } else { if (print_timestamp) fprintf (fh, "[%s] %s%s\n", timestamp_str, level_str, msg); else fprintf (fh, "%s%s\n", level_str, msg); if (do_close) { fclose (fh); } else { fflush(fh); } } pthread_mutex_unlock (&file_lock); return; } /* void logfile_print */
/* * * * * * * * * * * 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:%3.1f:%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 */
/* * Public functions */ int cu_rrd_create_file (const char *filename, /* {{{ */ const data_set_t *ds, const value_list_t *vl, const rrdcreate_config_t *cfg) { char **argv; int argc; char **rra_def; int rra_num; char **ds_def; int ds_num; int status = 0; time_t last_up; unsigned long stepsize; if (check_create_dir (filename)) return (-1); if ((rra_num = rra_get (&rra_def, vl, cfg)) < 1) { ERROR ("cu_rrd_create_file failed: Could not calculate RRAs"); return (-1); } if ((ds_num = ds_get (&ds_def, ds, vl, cfg)) < 1) { ERROR ("cu_rrd_create_file failed: Could not calculate DSes"); return (-1); } argc = ds_num + rra_num; if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL) { char errbuf[1024]; ERROR ("cu_rrd_create_file failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } memcpy (argv, ds_def, ds_num * sizeof (char *)); memcpy (argv + ds_num, rra_def, rra_num * sizeof (char *)); argv[ds_num + rra_num] = NULL; last_up = CDTIME_T_TO_TIME_T (vl->time); if (last_up <= 10) last_up = time (NULL); last_up -= 10; if (cfg->stepsize > 0) stepsize = cfg->stepsize; else stepsize = (unsigned long) CDTIME_T_TO_TIME_T (vl->interval); status = srrd_create (filename, stepsize, last_up, argc, (const char **) argv); free (argv); ds_free (ds_num, ds_def); rra_free (rra_num, rra_def); if (status != 0) { WARNING ("cu_rrd_create_file: srrd_create (%s) returned status %i.", filename, status); } else { DEBUG ("cu_rrd_create_file: Successfully created RRD file \"%s\".", filename); } return (status); } /* }}} int cu_rrd_create_file */
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 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 Msg *riemann_notification_to_protobuf (struct riemann_host *host, /* {{{ */ notification_t const *n) { Msg *msg; Event *event; char service_buffer[6 * DATA_MAX_NAME_LEN]; char const *severity; notification_meta_t *meta; int i; msg = malloc (sizeof (*msg)); if (msg == NULL) { ERROR ("write_riemann plugin: malloc failed."); return (NULL); } memset (msg, 0, sizeof (*msg)); msg__init (msg); msg->events = malloc (sizeof (*msg->events)); if (msg->events == NULL) { ERROR ("write_riemann plugin: malloc failed."); sfree (msg); return (NULL); } event = malloc (sizeof (*event)); if (event == NULL) { ERROR ("write_riemann plugin: malloc failed."); sfree (msg->events); sfree (msg); return (NULL); } memset (event, 0, sizeof (*event)); event__init (event); msg->events[0] = event; msg->n_events = 1; event->host = strdup (n->host); event->time = CDTIME_T_TO_TIME_T (n->time); event->has_time = 1; switch (n->severity) { case NOTIF_OKAY: severity = "ok"; break; case NOTIF_WARNING: severity = "warning"; break; case NOTIF_FAILURE: severity = "critical"; break; default: severity = "unknown"; } event->state = strdup (severity); riemann_event_add_tag (event, "notification"); if (n->host[0] != 0) riemann_event_add_attribute (event, "host", n->host); if (n->plugin[0] != 0) riemann_event_add_attribute (event, "plugin", n->plugin); if (n->plugin_instance[0] != 0) riemann_event_add_attribute (event, "plugin_instance", n->plugin_instance); if (n->type[0] != 0) riemann_event_add_attribute (event, "type", n->type); if (n->type_instance[0] != 0) riemann_event_add_attribute (event, "type_instance", n->type_instance); for (i = 0; i < riemann_tags_num; i++) riemann_event_add_tag (event, riemann_tags[i]); format_name (service_buffer, sizeof (service_buffer), /* host = */ "", n->plugin, n->plugin_instance, n->type, n->type_instance); event->service = strdup (&service_buffer[1]); /* Pull in values from threshold */ for (meta = n->meta; meta != NULL; meta = meta->next) { if (strcasecmp ("CurrentValue", meta->name) != 0) continue; event->metric_d = meta->nm_value.nm_double; event->has_metric_d = 1; break; } DEBUG ("write_riemann plugin: Successfully created protobuf for notification: " "host = \"%s\", service = \"%s\", state = \"%s\"", event->host, event->service, event->state); return (msg); } /* }}} Msg *riemann_notification_to_protobuf */
static int init (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE kern_return_t status; port_host = mach_host_self (); /* FIXME: Free `cpu_list' if it's not NULL */ if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: host_processors returned %i", (int) status); cpu_list_len = 0; return (-1); } DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors"); INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s"); cpu_temp_retry_max = 86400 / CDTIME_T_TO_TIME_T (plugin_get_interval ()); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(HAVE_LIBKSTAT) kstat_t *ksp_chain; numcpu = 0; if (kc == NULL) return (-1); /* Solaris doesn't count linear.. *sigh* */ for (numcpu = 0, ksp_chain = kc->kc_chain; (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); ksp_chain = ksp_chain->ks_next) if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0) ksp[numcpu++] = ksp_chain; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL size_t numcpu_size; int mib[2] = {CTL_HW, HW_NCPU}; int status; numcpu = 0; numcpu_size = sizeof (numcpu); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &numcpu, &numcpu_size, NULL, 0); if (status == -1) { char errbuf[1024]; WARNING ("cpu plugin: sysctl: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* #endif CAN_USE_SYSCTL */ #elif defined (HAVE_SYSCTLBYNAME) size_t numcpu_size; numcpu_size = sizeof (numcpu); if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #ifdef HAVE_SYSCTL_KERN_CP_TIMES numcpu_size = sizeof (maxcpu); if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #else if (numcpu != 1) NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu); #endif /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* nothing to initialize */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) /* nothing to initialize */ #endif /* HAVE_PERFSTAT */ return (0); } /* int init */
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 */
static riemann_message_t * wrr_notification_to_message(struct riemann_host *host, /* {{{ */ notification_t const *n) { riemann_message_t *msg; riemann_event_t *event; char service_buffer[6 * DATA_MAX_NAME_LEN]; char const *severity; switch (n->severity) { case NOTIF_OKAY: severity = "ok"; break; case NOTIF_WARNING: severity = "warning"; break; case NOTIF_FAILURE: severity = "critical"; break; default: severity = "unknown"; } format_name(service_buffer, sizeof(service_buffer), /* host = */ "", n->plugin, n->plugin_instance, n->type, n->type_instance); event = riemann_event_create( RIEMANN_EVENT_FIELD_HOST, n->host, RIEMANN_EVENT_FIELD_TIME, (int64_t)CDTIME_T_TO_TIME_T(n->time), RIEMANN_EVENT_FIELD_TAGS, "notification", NULL, RIEMANN_EVENT_FIELD_STATE, severity, RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1], RIEMANN_EVENT_FIELD_NONE); #if RCC_VERSION_NUMBER >= 0x010A00 riemann_event_set(event, RIEMANN_EVENT_FIELD_TIME_MICROS, (int64_t)CDTIME_T_TO_US(n->time)); #endif if (n->host[0] != 0) riemann_event_string_attribute_add(event, "host", n->host); if (n->plugin[0] != 0) riemann_event_string_attribute_add(event, "plugin", n->plugin); if (n->plugin_instance[0] != 0) riemann_event_string_attribute_add(event, "plugin_instance", n->plugin_instance); if (n->type[0] != 0) riemann_event_string_attribute_add(event, "type", n->type); if (n->type_instance[0] != 0) riemann_event_string_attribute_add(event, "type_instance", n->type_instance); for (size_t i = 0; i < riemann_attrs_num; i += 2) riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i + 1]); for (size_t i = 0; i < riemann_tags_num; i++) riemann_event_tag_add(event, riemann_tags[i]); if (n->message[0] != 0) riemann_event_string_attribute_add(event, "description", n->message); /* Pull in values from threshold and add extra attributes */ for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) { if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) { riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)meta->nm_value.nm_double, RIEMANN_EVENT_FIELD_NONE); continue; } if (meta->type == NM_TYPE_STRING) { riemann_event_string_attribute_add(event, meta->name, meta->nm_value.nm_string); continue; } } msg = riemann_message_create_with_events(event, NULL); if (msg == NULL) { ERROR("write_riemann plugin: riemann_message_create_with_events() failed."); riemann_event_free(event); return NULL; } DEBUG("write_riemann plugin: Successfully created message for notification: " "host = \"%s\", service = \"%s\", state = \"%s\"", event->host, event->service, event->state); return msg; } /* }}} riemann_message_t *wrr_notification_to_message */
/* * Public functions */ int cu_rrd_create_file(const char *filename, /* {{{ */ const data_set_t *ds, const value_list_t *vl, const rrdcreate_config_t *cfg) { char **argv; int argc; char **rra_def = NULL; int rra_num; char **ds_def = NULL; int ds_num; int status = 0; time_t last_up; unsigned long stepsize; if (check_create_dir(filename)) return -1; if ((rra_num = rra_get(&rra_def, vl, cfg)) < 1) { P_ERROR("cu_rrd_create_file failed: Could not calculate RRAs"); return -1; } if ((ds_num = ds_get(&ds_def, ds, vl, cfg)) < 1) { P_ERROR("cu_rrd_create_file failed: Could not calculate DSes"); rra_free(rra_num, rra_def); return -1; } argc = ds_num + rra_num; if ((argv = malloc(sizeof(*argv) * (argc + 1))) == NULL) { P_ERROR("cu_rrd_create_file failed: %s", STRERRNO); rra_free(rra_num, rra_def); ds_free(ds_num, ds_def); return -1; } memcpy(argv, ds_def, ds_num * sizeof(char *)); memcpy(argv + ds_num, rra_def, rra_num * sizeof(char *)); argv[ds_num + rra_num] = NULL; last_up = CDTIME_T_TO_TIME_T(vl->time); if (last_up <= 0) last_up = time(NULL); last_up -= 1; if (cfg->stepsize > 0) stepsize = cfg->stepsize; else stepsize = (unsigned long)CDTIME_T_TO_TIME_T(vl->interval); if (cfg->async) { status = srrd_create_async(filename, stepsize, last_up, argc, (const char **)argv); if (status != 0) P_WARNING("cu_rrd_create_file: srrd_create_async (%s) " "returned status %i.", filename, status); } else /* synchronous */ { status = lock_file(filename); if (status != 0) { if (status == EEXIST) P_NOTICE("cu_rrd_create_file: File \"%s\" is already being created.", filename); else P_ERROR("cu_rrd_create_file: Unable to lock file \"%s\".", filename); } else { status = srrd_create(filename, stepsize, last_up, argc, (const char **)argv); if (status != 0) { P_WARNING("cu_rrd_create_file: srrd_create (%s) returned status %i.", filename, status); } else { DEBUG("cu_rrd_create_file: Successfully created RRD file \"%s\".", filename); } unlock_file(filename); } } free(argv); ds_free(ds_num, ds_def); rra_free(rra_num, rra_def); return status; } /* }}} int cu_rrd_create_file */
static int ds_get(char ***ret, /* {{{ */ const data_set_t *ds, const value_list_t *vl, const rrdcreate_config_t *cfg) { char **ds_def; size_t ds_num; char min[32]; char max[32]; char buffer[128]; assert(ds->ds_num > 0); ds_def = calloc(ds->ds_num, sizeof(*ds_def)); if (ds_def == NULL) { P_ERROR("ds_get: calloc failed: %s", STRERRNO); return -1; } for (ds_num = 0; ds_num < ds->ds_num; ds_num++) { data_source_t *d = ds->ds + ds_num; const 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 { P_ERROR("ds_get: Unknown DS type: %i", d->type); break; } if (isnan(d->min)) { sstrncpy(min, "U", sizeof(min)); } else snprintf(min, sizeof(min), "%f", d->min); if (isnan(d->max)) { sstrncpy(max, "U", sizeof(max)); } else snprintf(max, sizeof(max), "%f", d->max); status = snprintf( 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; } if (ds_num == 0) { sfree(ds_def); return 0; } *ret = ds_def; return ds_num; } /* }}} int ds_get */