static void sysconfig_notify(notification_t *notif, const char *type, const char *message) { memset (notif, '\0', sizeof (*notif)); notif->severity = NOTIF_OKAY; notif->time = cdtime (); sstrncpy(notif->host, hostname_g, sizeof(notif->host)); sstrncpy(notif->plugin, "sysconfig", sizeof(notif->plugin)); sstrncpy(notif->type, type, sizeof(notif->type)); sstrncpy(notif->message, message, sizeof(notif->message)); plugin_dispatch_notification(notif); }
static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedData *a, void* userdata) { const char *dev = userdata; value_t values[4]; value_list_t vl = VALUE_LIST_INIT; if (!a->current_value_valid || !a->worst_value_valid) return; values[0].gauge = a->current_value; values[1].gauge = a->worst_value; values[2].gauge = a->threshold_valid?a->threshold:0; values[3].gauge = a->pretty_value; vl.values = values; vl.values_len = 4; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "smart", sizeof (vl.plugin)); sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); sstrncpy (vl.type, "smart_attribute", sizeof (vl.type)); sstrncpy (vl.type_instance, a->name, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); if (a->threshold_valid && a->current_value <= a->threshold) { notification_t notif = { NOTIF_WARNING, cdtime (), "", "", "smart", "", "smart_attribute", "", NULL }; sstrncpy (notif.host, hostname_g, sizeof (notif.host)); sstrncpy (notif.plugin_instance, dev, sizeof (notif.plugin_instance)); sstrncpy (notif.type_instance, a->name, sizeof (notif.type_instance)); ssnprintf (notif.message, sizeof (notif.message), "attribute %s is below allowed threshold (%d < %d)", a->name, a->current_value, a->threshold); plugin_dispatch_notification (¬if); } }
/* * int ut_report_state * * Checks if the `state' differs from the old state and creates a notification * if appropriate. * Does not fail. */ static int ut_report_state(const data_set_t *ds, const value_list_t *vl, const threshold_t *th, const gauge_t *values, int ds_index, int state) { /* {{{ */ int state_old; notification_t n; char *buf; size_t bufsize; int status; /* Check if hits matched */ if ((th->hits != 0)) { int hits = uc_get_hits(ds, vl); /* STATE_OKAY resets hits unless PERSIST_OK flag is set. Hits resets if * threshold is hit. */ if (((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0)) || (hits > th->hits)) { DEBUG("ut_report_state: reset uc_get_hits = 0"); uc_set_hits(ds, vl, 0); /* reset hit counter and notify */ } else { DEBUG("ut_report_state: th->hits = %d, uc_get_hits = %d", th->hits, uc_get_hits(ds, vl)); (void)uc_inc_hits(ds, vl, 1); /* increase hit counter */ return 0; } } /* end check hits */ state_old = uc_get_state(ds, vl); /* If the state didn't change, report if `persistent' is specified. If the * state is `okay', then only report if `persist_ok` flag is set. */ if (state == state_old) { if ((th->flags & UT_FLAG_PERSIST) == 0) return 0; else if ((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0)) return 0; } if (state != state_old) uc_set_state(ds, vl, state); NOTIFICATION_INIT_VL(&n, vl); buf = n.message; bufsize = sizeof(n.message); if (state == STATE_OKAY) n.severity = NOTIF_OKAY; else if (state == STATE_WARNING) n.severity = NOTIF_WARNING; else n.severity = NOTIF_FAILURE; n.time = vl->time; status = snprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin); buf += status; bufsize -= status; if (vl->plugin_instance[0] != '\0') { status = snprintf(buf, bufsize, " (instance %s)", vl->plugin_instance); buf += status; bufsize -= status; } status = snprintf(buf, bufsize, " type %s", vl->type); buf += status; bufsize -= status; if (vl->type_instance[0] != '\0') { status = snprintf(buf, bufsize, " (instance %s)", vl->type_instance); buf += status; bufsize -= status; } plugin_notification_meta_add_string(&n, "DataSource", ds->ds[ds_index].name); plugin_notification_meta_add_double(&n, "CurrentValue", values[ds_index]); plugin_notification_meta_add_double(&n, "WarningMin", th->warning_min); plugin_notification_meta_add_double(&n, "WarningMax", th->warning_max); plugin_notification_meta_add_double(&n, "FailureMin", th->failure_min); plugin_notification_meta_add_double(&n, "FailureMax", th->failure_max); /* Send an okay notification */ if (state == STATE_OKAY) { if (state_old == STATE_MISSING) snprintf(buf, bufsize, ": Value is no longer missing."); else snprintf(buf, bufsize, ": All data sources are within range again. " "Current value of \"%s\" is %f.", ds->ds[ds_index].name, values[ds_index]); } else { double min; double max; min = (state == STATE_ERROR) ? th->failure_min : th->warning_min; max = (state == STATE_ERROR) ? th->failure_max : th->warning_max; if (th->flags & UT_FLAG_INVERT) { if (!isnan(min) && !isnan(max)) { snprintf(buf, bufsize, ": Data source \"%s\" is currently " "%f. That is within the %s region of %f%s and %f%s.", ds->ds[ds_index].name, values[ds_index], (state == STATE_ERROR) ? "failure" : "warning", min, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); } else { snprintf(buf, bufsize, ": Data source \"%s\" is currently " "%f. That is %s the %s threshold of %f%s.", ds->ds[ds_index].name, values[ds_index], isnan(min) ? "below" : "above", (state == STATE_ERROR) ? "failure" : "warning", isnan(min) ? max : min, ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : ""); } } else if (th->flags & UT_FLAG_PERCENTAGE) { gauge_t value; gauge_t sum; sum = 0.0; for (size_t i = 0; i < vl->values_len; i++) { if (isnan(values[i])) continue; sum += values[i]; } if (sum == 0.0) value = NAN; else value = 100.0 * values[ds_index] / sum; snprintf(buf, bufsize, ": Data source \"%s\" is currently " "%g (%.2f%%). That is %s the %s threshold of %.2f%%.", ds->ds[ds_index].name, values[ds_index], value, (value < min) ? "below" : "above", (state == STATE_ERROR) ? "failure" : "warning", (value < min) ? min : max); } else /* is not inverted */ { snprintf(buf, bufsize, ": Data source \"%s\" is currently " "%f. That is %s the %s threshold of %f.", ds->ds[ds_index].name, values[ds_index], (values[ds_index] < min) ? "below" : "above", (state == STATE_ERROR) ? "failure" : "warning", (values[ds_index] < min) ? min : max); } } plugin_dispatch_notification(&n); plugin_notification_meta_free(n.meta); return 0; } /* }}} int ut_report_state */
/* * int ut_report_state * * Checks if the `state' differs from the old state and creates a notification * if appropriate. * Does not fail. */ static int ut_report_state (const data_set_t *ds, const value_list_t *vl, const threshold_t *th, const gauge_t *values, int ds_index, int state) { /* {{{ */ int state_old; notification_t n; char *buf; size_t bufsize; int status; state_old = uc_get_state (ds, vl); /* If the state didn't change, only report if `persistent' is specified and * the state is not `okay'. */ if (state == state_old) { if ((th->flags & UT_FLAG_PERSIST) == 0) return (0); else if (state == STATE_OKAY) return (0); } if (state != state_old) uc_set_state (ds, vl, state); NOTIFICATION_INIT_VL (&n, vl, ds); buf = n.message; bufsize = sizeof (n.message); if (state == STATE_OKAY) n.severity = NOTIF_OKAY; else if (state == STATE_WARNING) n.severity = NOTIF_WARNING; else n.severity = NOTIF_FAILURE; n.time = vl->time; status = ssnprintf (buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin); buf += status; bufsize -= status; if (vl->plugin_instance[0] != '\0') { status = ssnprintf (buf, bufsize, " (instance %s)", vl->plugin_instance); buf += status; bufsize -= status; } status = ssnprintf (buf, bufsize, " type %s", vl->type); buf += status; bufsize -= status; if (vl->type_instance[0] != '\0') { status = ssnprintf (buf, bufsize, " (instance %s)", vl->type_instance); buf += status; bufsize -= status; } plugin_notification_meta_add_string (&n, "DataSource", ds->ds[ds_index].name); plugin_notification_meta_add_double (&n, "CurrentValue", values[ds_index]); plugin_notification_meta_add_double (&n, "WarningMin", th->warning_min); plugin_notification_meta_add_double (&n, "WarningMax", th->warning_max); plugin_notification_meta_add_double (&n, "FailureMin", th->failure_min); plugin_notification_meta_add_double (&n, "FailureMax", th->failure_max); /* Send an okay notification */ if (state == STATE_OKAY) { status = ssnprintf (buf, bufsize, ": All data sources are within range again."); buf += status; bufsize -= status; } else { double min; double max; min = (state == STATE_ERROR) ? th->failure_min : th->warning_min; max = (state == STATE_ERROR) ? th->failure_max : th->warning_max; if (th->flags & UT_FLAG_INVERT) { if (!isnan (min) && !isnan (max)) { status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " "%f. That is within the %s region of %f and %f.", ds->ds[ds_index].name, values[ds_index], (state == STATE_ERROR) ? "failure" : "warning", min, max); } else { status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " "%f. That is %s the %s threshold of %f.", ds->ds[ds_index].name, values[ds_index], isnan (min) ? "below" : "above", (state == STATE_ERROR) ? "failure" : "warning", isnan (min) ? max : min); } } else /* is not inverted */ { status = ssnprintf (buf, bufsize, ": Data source \"%s\" is currently " "%f. That is %s the %s threshold of %f.", ds->ds[ds_index].name, values[ds_index], (values[ds_index] < min) ? "below" : "above", (state == STATE_ERROR) ? "failure" : "warning", (values[ds_index] < min) ? min : max); } buf += status; bufsize -= status; } plugin_dispatch_notification (&n); plugin_notification_meta_free (n.meta); return (0); } /* }}} int ut_report_state */
static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con) { MYSQL_RES *res; MYSQL_ROW row; char *query; int field_num; /* WTF? libmysqlclient does not seem to provide any means to * translate a column name to a column index ... :-/ */ const int READ_MASTER_LOG_POS_IDX = 6; const int SLAVE_IO_RUNNING_IDX = 10; const int SLAVE_SQL_RUNNING_IDX = 11; const int EXEC_MASTER_LOG_POS_IDX = 21; const int SECONDS_BEHIND_MASTER_IDX = 32; query = "SHOW SLAVE STATUS"; res = exec_query (con, query); if (res == NULL) return (-1); row = mysql_fetch_row (res); if (row == NULL) { ERROR ("mysql plugin: Failed to get slave statistics: " "`%s' did not return any rows.", query); mysql_free_result (res); return (-1); } field_num = mysql_num_fields (res); if (field_num < 33) { ERROR ("mysql plugin: Failed to get slave statistics: " "`%s' returned less than 33 columns.", query); mysql_free_result (res); return (-1); } if (db->slave_stats) { unsigned long long counter; double gauge; counter = atoll (row[READ_MASTER_LOG_POS_IDX]); counter_submit ("mysql_log_position", "slave-read", counter, db); counter = atoll (row[EXEC_MASTER_LOG_POS_IDX]); counter_submit ("mysql_log_position", "slave-exec", counter, db); if (row[SECONDS_BEHIND_MASTER_IDX] != NULL) { gauge = atof (row[SECONDS_BEHIND_MASTER_IDX]); gauge_submit ("time_offset", NULL, gauge, db); } } if (db->slave_notif) { notification_t n = { 0, cdtime (), "", "", "mysql", "", "time_offset", "", NULL }; char *io, *sql; io = row[SLAVE_IO_RUNNING_IDX]; sql = row[SLAVE_SQL_RUNNING_IDX]; set_host (db, n.host, sizeof (n.host)); /* Assured by "mysql_config_database" */ assert (db->instance != NULL); sstrncpy (n.plugin_instance, db->instance, sizeof (n.plugin_instance)); if (((io == NULL) || (strcasecmp (io, "yes") != 0)) && (db->slave_io_running)) { n.severity = NOTIF_WARNING; ssnprintf (n.message, sizeof (n.message), "slave I/O thread not started or not connected to master"); plugin_dispatch_notification (&n); db->slave_io_running = 0; } else if (((io != NULL) && (strcasecmp (io, "yes") == 0)) && (! db->slave_io_running)) { n.severity = NOTIF_OKAY; ssnprintf (n.message, sizeof (n.message), "slave I/O thread started and connected to master"); plugin_dispatch_notification (&n); db->slave_io_running = 1; } if (((sql == NULL) || (strcasecmp (sql, "yes") != 0)) && (db->slave_sql_running)) { n.severity = NOTIF_WARNING; ssnprintf (n.message, sizeof (n.message), "slave SQL thread not started"); plugin_dispatch_notification (&n); db->slave_sql_running = 0; } else if (((sql != NULL) && (strcasecmp (sql, "yes") == 0)) && (! db->slave_sql_running)) { n.severity = NOTIF_OKAY; ssnprintf (n.message, sizeof (n.message), "slave SQL thread started"); plugin_dispatch_notification (&n); db->slave_sql_running = 0; } } row = mysql_fetch_row (res); if (row != NULL) WARNING ("mysql plugin: `%s' returned more than one row - " "ignoring further results.", query); mysql_free_result (res); return (0); } /* mysql_read_slave_stats */
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 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 handle_putnotif(FILE *fh, char *buffer) { char *command; notification_t n = {0}; int status; if ((fh == NULL) || (buffer == NULL)) return -1; DEBUG("utils_cmd_putnotif: handle_putnotif (fh = %p, buffer = %s);", (void *)fh, buffer); command = NULL; status = parse_string(&buffer, &command); if (status != 0) { print_to_socket(fh, "-1 Cannot parse command.\n"); return -1; } assert(command != NULL); if (strcasecmp("PUTNOTIF", command) != 0) { print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command); return -1; } status = 0; while (*buffer != 0) { char *key; char *value; status = parse_option(&buffer, &key, &value); if (status != 0) { print_to_socket(fh, "-1 Malformed option.\n"); break; } status = set_option(&n, key, value); if (status != 0) { print_to_socket(fh, "-1 Error parsing option `%s'\n", key); break; } } /* for (i) */ /* Check for required fields and complain if anything is missing. */ if ((status == 0) && (n.severity == 0)) { print_to_socket(fh, "-1 Option `severity' missing.\n"); status = -1; } if ((status == 0) && (n.time == 0)) { print_to_socket(fh, "-1 Option `time' missing.\n"); status = -1; } if ((status == 0) && (strlen(n.message) == 0)) { print_to_socket(fh, "-1 No message or message of length 0 given.\n"); status = -1; } /* If status is still zero the notification is fine and we can finally * dispatch it. */ if (status == 0) { plugin_dispatch_notification(&n); print_to_socket(fh, "0 Success\n"); } return 0; } /* int handle_putnotif */
static int parse_packet (void *se, /* {{{ */ void *buffer, size_t buffer_size, int flags, const char *username) { int status; value_list_t vl = VALUE_LIST_INIT; notification_t n; #if HAVE_LIBGCRYPT int packet_was_signed = (flags & PP_SIGNED); int packet_was_encrypted = (flags & PP_ENCRYPTED); int printed_ignore_warning = 0; #endif /* HAVE_LIBGCRYPT */ memset (&vl, '\0', sizeof (vl)); memset (&n, '\0', sizeof (n)); status = 0; while ((status == 0) && (0 < buffer_size) && ((unsigned int) buffer_size > sizeof (part_header_t))) { uint16_t pkg_length; uint16_t pkg_type; memcpy ((void *) &pkg_type, (void *) buffer, sizeof (pkg_type)); memcpy ((void *) &pkg_length, (void *) (buffer + sizeof (pkg_type)), sizeof (pkg_length)); pkg_length = ntohs (pkg_length); pkg_type = ntohs (pkg_type); if (pkg_length > buffer_size) break; /* Ensure that this loop terminates eventually */ if (pkg_length < (2 * sizeof (uint16_t))) break; if (pkg_type == TYPE_ENCR_AES256) { // status = parse_part_encr_aes256 (se, // &buffer, &buffer_size, flags); // if (status != 0) // { ERROR ("network plugin: Decrypting AES256 " "part failed " "with status %i.", status); break; // } } #if HAVE_LIBGCRYPT else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT) && (packet_was_encrypted == 0)) { if (printed_ignore_warning == 0) { INFO ("network plugin: Unencrypted packet or " "part has been ignored."); printed_ignore_warning = 1; } buffer = ((char *) buffer) + pkg_length; continue; } #endif /* HAVE_LIBGCRYPT */ else if (pkg_type == TYPE_SIGN_SHA256) { // status = parse_part_sign_sha256 (se, // &buffer, &buffer_size, flags); // if (status != 0) // { ERROR ("network plugin: Verifying HMAC-SHA-256 " "signature failed " "with status %i.", status); break; // } } #if HAVE_LIBGCRYPT else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN) && (packet_was_encrypted == 0) && (packet_was_signed == 0)) { if (printed_ignore_warning == 0) { INFO ("network plugin: Unsigned packet or " "part has been ignored."); printed_ignore_warning = 1; } buffer = ((char *) buffer) + pkg_length; continue; } #endif /* HAVE_LIBGCRYPT */ else if (pkg_type == TYPE_VALUES) { status = parse_part_values (&buffer, &buffer_size, &vl.values, &vl.values_len); if (status != 0) break; network_dispatch_values (&vl, username); sfree (vl.values); } else if (pkg_type == TYPE_TIME) { uint64_t tmp = 0; status = parse_part_number (&buffer, &buffer_size, &tmp); if (status == 0) { vl.time = (time_t) tmp; n.time = (time_t) tmp; } } else if (pkg_type == TYPE_INTERVAL) { uint64_t tmp = 0; status = parse_part_number (&buffer, &buffer_size, &tmp); if (status == 0) vl.interval = (int) tmp; } else if (pkg_type == TYPE_HOST) { status = parse_part_string (&buffer, &buffer_size, vl.host, sizeof (vl.host)); if (status == 0) sstrncpy (n.host, vl.host, sizeof (n.host)); } else if (pkg_type == TYPE_PLUGIN) { status = parse_part_string (&buffer, &buffer_size, vl.plugin, sizeof (vl.plugin)); if (status == 0) sstrncpy (n.plugin, vl.plugin, sizeof (n.plugin)); } else if (pkg_type == TYPE_PLUGIN_INSTANCE) { status = parse_part_string (&buffer, &buffer_size, vl.plugin_instance, sizeof (vl.plugin_instance)); if (status == 0) sstrncpy (n.plugin_instance, vl.plugin_instance, sizeof (n.plugin_instance)); } else if (pkg_type == TYPE_TYPE) { status = parse_part_string (&buffer, &buffer_size, vl.type, sizeof (vl.type)); if (status == 0) sstrncpy (n.type, vl.type, sizeof (n.type)); } else if (pkg_type == TYPE_TYPE_INSTANCE) { status = parse_part_string (&buffer, &buffer_size, vl.type_instance, sizeof (vl.type_instance)); if (status == 0) sstrncpy (n.type_instance, vl.type_instance, sizeof (n.type_instance)); } else if (pkg_type == TYPE_MESSAGE) { status = parse_part_string (&buffer, &buffer_size, n.message, sizeof (n.message)); if (status != 0) { /* do nothing */ } else if ((n.severity != NOTIF_FAILURE) && (n.severity != NOTIF_WARNING) && (n.severity != NOTIF_OKAY)) { INFO ("network plugin: " "Ignoring notification with " "unknown severity %i.", n.severity); } else if (n.time <= 0) { INFO ("network plugin: " "Ignoring notification with " "time == 0."); } else if (strlen (n.message) <= 0) { INFO ("network plugin: " "Ignoring notification with " "an empty message."); } else { plugin_dispatch_notification (&n); } } else if (pkg_type == TYPE_SEVERITY) { uint64_t tmp = 0; status = parse_part_number (&buffer, &buffer_size, &tmp); if (status == 0) n.severity = (int) tmp; } else { DEBUG ("network plugin: parse_packet: Unknown part" " type: 0x%04hx", pkg_type); buffer = ((char *) buffer) + pkg_length; } } /* while (buffer_size > sizeof (part_header_t)) */ if (status == 0 && buffer_size > 0) WARNING ("network plugin: parse_packet: Received truncated " "packet, try increasing `MaxPacketSize'"); return (status); } /* }}} int parse_packet */
static int top_read(void) { struct dirent **namelist; int n; n = scandir ("/proc", &namelist, 0, alphasort); if (n < 0) perror ("scandir"); else { int hz; hz = sysconf(_SC_CLK_TCK); char *bufferout; notification_t notif; memset (¬if, '\0', sizeof (n)); bufferout = malloc(n * sizeof(char) * 256); *bufferout = '\0'; //printf("pid ppid uid user gid group rss stime utime name\n"); while (n--) { if (atoi (namelist[n]->d_name)) { stat_t *stat; stat = malloc(sizeof(stat_t)); //if (getStat (atoi (namelist[n]->d_name), stat) == 0 || stat->ppid == 2 || stat->ppid == 0) { if (getStat (atoi (namelist[n]->d_name), stat) == 0) { free(namelist[n]); free(stat); continue; } status_t *status; status = malloc(sizeof(status_t)); if (getStatus (atoi (namelist[n]->d_name), status) == 0) { free(namelist[n]); free(stat); free(status); } char buf[256]; struct passwd *pwd; pwd = getpwuid(status->Uid[1]); struct group *grp; grp = getgrgid(status->Gid[1]); #if KERNEL_LINUX snprintf(buf, sizeof(buf), "%d %d %lu %s %lu %s %ld %ld %ld %s\n", stat->pid, stat->ppid, status->Uid[1], pwd->pw_name, status->Gid[1], grp->gr_name, stat->rss, stat->stime * 100 / hz, stat->utime * 100 / hz, status->Name); #elif KERNEL_SOLARIS snprintf (buf, sizeof (buf), "%d %d %lu %s %lu %s %ld %ld %ld %s\n", stat->pid, stat->ppid, status->Uid[1], pwd->pw_name, status->Gid[1], grp->gr_name, stat->rss, stat->stime, stat->utime, status->Name); #endif free(namelist[n]); free(stat); free(status); strncat(bufferout, buf, sizeof(buf)); } } //ERROR("%s", bufferout); notif.severity = NOTIF_OKAY; notif.time = cdtime (); sstrncpy(notif.host, hostname_g, sizeof(notif.host)); sstrncpy(notif.plugin, "top", sizeof(notif.plugin)); sstrncpy(notif.type, "ps", sizeof(notif.type)); sstrncpy(notif.message, bufferout, sizeof(notif.message)); plugin_dispatch_notification(¬if); free(bufferout); } free(namelist); return 0; }