static int do_check (lcc_connection_t *connection) { gauge_t *values; char **values_names; size_t values_num; char ident_str[1024]; lcc_identifier_t ident; size_t i; int status; snprintf (ident_str, sizeof (ident_str), "%s/%s", hostname_g, value_string_g); ident_str[sizeof (ident_str) - 1] = 0; memset (&ident, 0, sizeof (ident)); status = lcc_string_to_identifier (connection, &ident, ident_str); if (status != 0) { printf ("ERROR: Creating an identifier failed: %s.\n", lcc_strerror (connection)); LCC_DESTROY (connection); return (RET_CRITICAL); } status = lcc_getval (connection, &ident, &values_num, &values, &values_names); if (status != 0) { printf ("ERROR: Retrieving values from the daemon failed: %s.\n", lcc_strerror (connection)); LCC_DESTROY (connection); return (RET_CRITICAL); } LCC_DESTROY (connection); status = filter_ds (&values_num, &values, &values_names); if (status != RET_OKAY) return (status); status = RET_UNKNOWN; if (consolitation_g == CON_NONE) status = do_check_con_none (values_num, values, values_names); else if (consolitation_g == CON_AVERAGE) status = do_check_con_average (values_num, values, values_names); else if (consolitation_g == CON_SUM) status = do_check_con_sum (values_num, values, values_names); else if (consolitation_g == CON_PERCENTAGE) status = do_check_con_percentage (values_num, values, values_names); free (values); if (values_names != NULL) for (i = 0; i < values_num; i++) free (values_names[i]); free (values_names); return (status); } /* int do_check */
static int flush ( const char *address, const char *plugin, const char *ident_str, int timeout) { lcc_connection_t *connection; lcc_identifier_t ident; /* Pointer which is passed to lcc_flush. * Either a null pointer or it points to ident */ lcc_identifier_t *identp; int status; connection = NULL; status = lcc_connect(address, &connection); if (status != 0) { fprintf (stderr, "ERROR: Connecting to daemon at %s failed: %s.\n", address, strerror (errno)); return 1; } identp = NULL; if (ident_str != NULL && *ident_str != '\0') { status = lcc_string_to_identifier (connection, &ident, ident_str); if (status != 0) { fprintf (stderr, "ERROR: Creating and identifier failed: %s.\n", lcc_strerror(connection)); LCC_DESTROY (connection); return 1; } identp = &ident; } status = lcc_flush (connection, plugin, identp, timeout); if (status != 0) { fprintf (stderr, "ERROR: Flushing failed: %s.\n", lcc_strerror (connection)); LCC_DESTROY (connection); return 1; } LCC_DESTROY (connection); return 0; }
static int parse_identifier(lcc_connection_t *c, const char *value, lcc_identifier_t *ident) { char hostname[1024]; char ident_str[1024] = ""; int n_slashes; int status; n_slashes = count_chars(value, '/'); if (n_slashes == 1) { /* The user has omitted the hostname part of the identifier * (there is only one '/' in the identifier) * Let's add the local hostname */ if (gethostname(hostname, sizeof(hostname)) != 0) { fprintf(stderr, "ERROR: Failed to get local hostname: %s", strerror(errno)); return (-1); } hostname[sizeof(hostname) - 1] = '\0'; snprintf(ident_str, sizeof(ident_str), "%s/%s", hostname, value); ident_str[sizeof(ident_str) - 1] = '\0'; } else { strncpy(ident_str, value, sizeof(ident_str)); ident_str[sizeof(ident_str) - 1] = '\0'; } status = lcc_string_to_identifier(c, ident, ident_str); if (status != 0) { fprintf(stderr, "ERROR: Failed to parse identifier ``%s'': %s.\n", ident_str, lcc_strerror(c)); return (-1); } return (0); } /* parse_identifier */
/** Refresh and send the stats to the collectd server * */ void rs_stats_collectd_do_stats(rs_t *conf, rs_stats_tmpl_t *tmpls, struct timeval *now) { rs_stats_tmpl_t *tmpl = tmpls; char identifier[6 * LCC_NAME_LEN]; int i; while (tmpl) { /* * Refresh the value of whatever were sending */ for (i = 0; i < (int) tmpl->value->values_len; i++) { tmpl->value_tmpl[i].cb(conf, &tmpl->value_tmpl[i]); } tmpl->value->time = now->tv_sec; lcc_identifier_to_string(conf->stats.handle, identifier, sizeof(identifier), &tmpl->value->identifier); if (lcc_putval(conf->stats.handle, tmpl->value) < 0) { char const *error; error = lcc_strerror(conf->stats.handle); ERROR("Failed PUTVAL \"%s\" interval=%i %" PRIu64 " : %s", identifier, (int) tmpl->value->interval, (uint64_t) tmpl->value->time, error ? error : "unknown error"); } tmpl = tmpl->next; } }
static int listval (lcc_connection_t *c, int argc, char **argv) { lcc_identifier_t *ret_ident = NULL; size_t ret_ident_num = 0; int status; size_t i; assert (strcasecmp (argv[0], "listval") == 0); if (argc != 1) { fprintf (stderr, "ERROR: listval: Does not accept any arguments.\n"); return (-1); } #define BAIL_OUT(s) \ do { \ if (ret_ident != NULL) \ free (ret_ident); \ ret_ident_num = 0; \ return (s); \ } while (0) status = lcc_listval (c, &ret_ident, &ret_ident_num); if (status != 0) { fprintf (stderr, "ERROR: %s\n", lcc_strerror (c)); BAIL_OUT (status); } for (i = 0; i < ret_ident_num; ++i) { char id[1024]; status = lcc_identifier_to_string (c, id, sizeof (id), ret_ident + i); if (status != 0) { fprintf (stderr, "ERROR: listval: Failed to convert returned " "identifier to a string: %s\n", lcc_strerror (c)); continue; } printf ("%s\n", id); } BAIL_OUT (0); #undef BAIL_OUT } /* listval */
static int getval (lcc_connection_t *c, int argc, char **argv) { lcc_identifier_t ident; size_t ret_values_num = 0; gauge_t *ret_values = NULL; char **ret_values_names = NULL; int status; size_t i; assert (strcasecmp (argv[0], "getval") == 0); if (argc != 2) { fprintf (stderr, "ERROR: getval: Missing identifier.\n"); return (-1); } memset (&ident, 0, sizeof (ident)); status = parse_identifier (c, argv[1], &ident); if (status != 0) return (status); #define BAIL_OUT(s) \ do { \ if (ret_values != NULL) \ free (ret_values); \ if (ret_values_names != NULL) { \ for (i = 0; i < ret_values_num; ++i) \ free (ret_values_names[i]); \ free (ret_values_names); \ } \ ret_values_num = 0; \ return (s); \ } while (0) status = lcc_getval (c, &ident, &ret_values_num, &ret_values, &ret_values_names); if (status != 0) { fprintf (stderr, "ERROR: %s\n", lcc_strerror (c)); BAIL_OUT (-1); } for (i = 0; i < ret_values_num; ++i) printf ("%s=%e\n", ret_values_names[i], ret_values[i]); BAIL_OUT (0); #undef BAIL_OUT } /* getval */
static int putval (lcc_connection_t *c, int argc, char **argv) { lcc_value_list_t vl = LCC_VALUE_LIST_INIT; /* 64 ought to be enough for anybody ;-) */ value_t values[64]; int values_types[64]; size_t values_len = 0; int status; int i; assert (strcasecmp (argv[0], "putval") == 0); if (argc < 3) { fprintf (stderr, "ERROR: putval: Missing identifier " "and/or value list.\n"); return (-1); } vl.values = values; vl.values_types = values_types; status = parse_identifier (c, argv[1], &vl.identifier); if (status != 0) return (status); for (i = 2; i < argc; ++i) { char *tmp; tmp = strchr (argv[i], (int)'='); if (tmp != NULL) { /* option */ char *key = argv[i]; char *value = tmp; *value = '\0'; ++value; if (strcasecmp (key, "interval") == 0) { char *endptr; vl.interval = strtol (value, &endptr, 0); if (endptr == value) { fprintf (stderr, "ERROR: Failed to parse interval as number: %s.\n", value); return (-1); } else if ((endptr != NULL) && (*endptr != '\0')) { fprintf (stderr, "WARNING: Ignoring trailing garbage after " "interval: %s.\n", endptr); } } else { fprintf (stderr, "ERROR: putval: Unknown option `%s'.\n", key); return (-1); } } else { /* value list */ char *value; tmp = strchr (argv[i], (int)':'); if (tmp == NULL) { fprintf (stderr, "ERROR: putval: Invalid value list: %s.\n", argv[i]); return (-1); } *tmp = '\0'; ++tmp; if (strcasecmp (argv[i], "N") == 0) { vl.time = 0; } else { char *endptr; vl.time = strtol (argv[i], &endptr, 0); if (endptr == argv[i]) { fprintf (stderr, "ERROR: Failed to parse time as number: %s.\n", argv[i]); return (-1); } else if ((endptr != NULL) && (*endptr != '\0')) { fprintf (stderr, "ERROR: Garbage after time: %s.\n", endptr); return (-1); } } values_len = 0; value = tmp; while (value != 0) { char *dot, *endptr; tmp = strchr (value, (int)':'); if (tmp != NULL) { *tmp = '\0'; ++tmp; } /* This is a bit of a hack, but parsing types.db just does not make * much sense imho -- the server might have different types defined * anyway. Also, lcc uses the type information for formatting the * number only, so the real meaning does not matter. -tokkee */ dot = strchr (value, (int)'.'); endptr = NULL; if (strcasecmp (value, "U") == 0) { values[values_len].gauge = NAN; values_types[values_len] = LCC_TYPE_GAUGE; } else if (dot) { /* floating point value */ values[values_len].gauge = strtod (value, &endptr); values_types[values_len] = LCC_TYPE_GAUGE; } else { /* integer */ values[values_len].counter = strtol (value, &endptr, 0); values_types[values_len] = LCC_TYPE_COUNTER; } ++values_len; if (endptr == value) { fprintf (stderr, "ERROR: Failed to parse value as number: %s.\n", argv[i]); return (-1); } else if ((endptr != NULL) && (*endptr != '\0')) { fprintf (stderr, "ERROR: Garbage after value: %s.\n", endptr); return (-1); } value = tmp; } assert (values_len >= 1); vl.values_len = values_len; status = lcc_putval (c, &vl); if (status != 0) { fprintf (stderr, "ERROR: %s\n", lcc_strerror (c)); return (-1); } } } if (values_len == 0) { fprintf (stderr, "ERROR: putval: Missing value list(s).\n"); return (-1); } return (0); } /* putval */
static int flush (lcc_connection_t *c, int argc, char **argv) { int timeout = -1; lcc_identifier_t *identifiers = NULL; int identifiers_num = 0; char **plugins = NULL; int plugins_num = 0; int status; int i; assert (strcasecmp (argv[0], "flush") == 0); #define BAIL_OUT(s) \ do { \ if (identifiers != NULL) \ free (identifiers); \ identifiers_num = 0; \ if (plugins != NULL) \ free (plugins); \ plugins_num = 0; \ return (s); \ } while (0) for (i = 1; i < argc; ++i) { char *key, *value; key = argv[i]; value = strchr (argv[i], (int)'='); if (! value) { fprintf (stderr, "ERROR: flush: Invalid option ``%s''.\n", argv[i]); BAIL_OUT (-1); } *value = '\0'; ++value; if (strcasecmp (key, "timeout") == 0) { char *endptr = NULL; timeout = (int) strtol (value, &endptr, 0); if (endptr == value) { fprintf (stderr, "ERROR: Failed to parse timeout as number: %s.\n", value); BAIL_OUT (-1); } else if ((endptr != NULL) && (*endptr != '\0')) { fprintf (stderr, "WARNING: Ignoring trailing garbage after timeout: " "%s.\n", endptr); } } else if (strcasecmp (key, "plugin") == 0) { status = array_grow ((void *)&plugins, &plugins_num, sizeof (*plugins)); if (status != 0) BAIL_OUT (status); plugins[plugins_num - 1] = value; } else if (strcasecmp (key, "identifier") == 0) { status = array_grow ((void *)&identifiers, &identifiers_num, sizeof (*identifiers)); if (status != 0) BAIL_OUT (status); memset (identifiers + (identifiers_num - 1), 0, sizeof (*identifiers)); status = parse_identifier (c, value, identifiers + (identifiers_num - 1)); if (status != 0) BAIL_OUT (status); } else { fprintf (stderr, "ERROR: flush: Unknown option `%s'.\n", key); BAIL_OUT (-1); } } if (plugins_num == 0) { status = array_grow ((void *)&plugins, &plugins_num, sizeof (*plugins)); if (status != 0) BAIL_OUT (status); assert (plugins_num == 1); plugins[0] = NULL; } for (i = 0; i < plugins_num; ++i) { if (identifiers_num == 0) { status = lcc_flush (c, plugins[i], NULL, timeout); if (status != 0) fprintf (stderr, "ERROR: Failed to flush plugin `%s': %s.\n", (plugins[i] == NULL) ? "(all)" : plugins[i], lcc_strerror (c)); } else { int j; for (j = 0; j < identifiers_num; ++j) { status = lcc_flush (c, plugins[i], identifiers + j, timeout); if (status != 0) { char id[1024]; lcc_identifier_to_string (c, id, sizeof (id), identifiers + j); fprintf (stderr, "ERROR: Failed to flush plugin `%s', " "identifier `%s': %s.\n", (plugins[i] == NULL) ? "(all)" : plugins[i], id, lcc_strerror (c)); } } } } BAIL_OUT (0); #undef BAIL_OUT } /* flush */
static int do_listval (lcc_connection_t *connection) { lcc_identifier_t *ret_ident = NULL; size_t ret_ident_num = 0; char *hostname = NULL; int status; size_t i; status = lcc_listval (connection, &ret_ident, &ret_ident_num); if (status != 0) { printf ("UNKNOWN: %s\n", lcc_strerror (connection)); if (ret_ident != NULL) free (ret_ident); return (RET_UNKNOWN); } status = lcc_sort_identifiers (connection, ret_ident, ret_ident_num); if (status != 0) { printf ("UNKNOWN: %s\n", lcc_strerror (connection)); if (ret_ident != NULL) free (ret_ident); return (RET_UNKNOWN); } for (i = 0; i < ret_ident_num; ++i) { char id[1024]; if ((hostname_g != NULL) && (strcasecmp (hostname_g, ret_ident[i].host))) continue; if ((hostname == NULL) || strcasecmp (hostname, ret_ident[i].host)) { free (hostname); hostname = strdup (ret_ident[i].host); printf ("Host: %s\n", hostname); } /* empty hostname; not to be printed again */ ret_ident[i].host[0] = '\0'; status = lcc_identifier_to_string (connection, id, sizeof (id), ret_ident + i); if (status != 0) { printf ("ERROR: listval: Failed to convert returned " "identifier to a string: %s\n", lcc_strerror (connection)); free (hostname); hostname = NULL; continue; } /* skip over the (empty) hostname and following '/' */ printf ("\t%s\n", id + 1); } free (ret_ident); free (hostname); return (RET_OKAY); } /* int do_listval */