typedef struct metric_definition_s metric_definition_t;
struct instance_definition_s {
+ char *plugin_name;
char *instance;
char *path;
cu_tail_t *tail;
metric_definition_t **metric_list;
size_t metric_list_len;
- cdtime_t interval;
ssize_t time_from;
struct instance_definition_s *next;
};
typedef struct instance_definition_s instance_definition_t;
/* Private */
-static metric_definition_t *metric_head = NULL;
+static metric_definition_t *metric_head;
static int tcsv_submit(instance_definition_t *id, metric_definition_t *md,
value_t v, cdtime_t t) {
vl.values_len = 1;
vl.values = &v;
- sstrncpy(vl.plugin, "tail_csv", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (id->plugin_name != NULL) ? id->plugin_name : "tail_csv",
+ sizeof(vl.plugin));
if (id->instance != NULL)
sstrncpy(vl.plugin_instance, id->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, md->type, sizeof(vl.type));
sstrncpy(vl.type_instance, md->instance, sizeof(vl.type_instance));
vl.time = t;
- vl.interval = id->interval;
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
}
static cdtime_t parse_time(char const *tbuf) {
errno = 0;
t = strtod(tbuf, &endptr);
if ((errno != 0) || (endptr == NULL) || (endptr[0] != 0))
- return (cdtime());
+ return cdtime();
- return (DOUBLE_TO_CDTIME_T(t));
+ return DOUBLE_TO_CDTIME_T(t);
}
static int tcsv_read_metric(instance_definition_t *id, metric_definition_t *md,
int status;
if (md->data_source_type == -1)
- return (EINVAL);
+ return EINVAL;
assert(md->value_from >= 0);
if (((size_t)md->value_from) >= fields_num)
- return (EINVAL);
+ return EINVAL;
status = parse_value(fields[md->value_from], &v, md->data_source_type);
if (status != 0)
- return (status);
+ return status;
if (id->time_from >= 0) {
if (((size_t)id->time_from) >= fields_num)
- return (EINVAL);
+ return EINVAL;
t = parse_time(fields[id->time_from]);
}
- return (tcsv_submit(id, md, v, t));
+ return tcsv_submit(id, md, v, t);
}
-static _Bool tcsv_check_index(ssize_t index, size_t fields_num,
- char const *name) {
+static bool tcsv_check_index(ssize_t index, size_t fields_num,
+ char const *name) {
if (index < 0)
- return 1;
+ return true;
else if (((size_t)index) < fields_num)
- return 1;
+ return true;
ERROR("tail_csv plugin: Metric \"%s\": Request for index %zd when "
- "only %zu fields are available.",
+ "only %" PRIsz " fields are available.",
name, index, fields_num);
- return (0);
+ return false;
}
static int tcsv_read_buffer(instance_definition_t *id, char *buffer,
/* Ignore empty lines. */
if ((buffer_size == 0) || (buffer[0] == '#'))
- return (0);
+ return 0;
/* Count the number of fields. */
metrics_num = 1;
ERROR("tail_csv plugin: last line of `%s' does not contain "
"enough values.",
id->path);
- return (-1);
+ return -1;
}
/* Create a list of all values */
metrics = calloc(metrics_num, sizeof(*metrics));
if (metrics == NULL) {
ERROR("tail_csv plugin: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
ptr = buffer;
/* Free up resources */
sfree(metrics);
- return (0);
+ return 0;
}
static int tcsv_read(user_data_t *ud) {
id->tail = cu_tail_create(id->path);
if (id->tail == NULL) {
ERROR("tail_csv plugin: cu_tail_create (\"%s\") failed.", id->path);
- return (-1);
+ return -1;
}
}
ERROR("tail_csv plugin: File \"%s\": cu_tail_readline failed "
"with status %i.",
id->path, status);
- return (-1);
+ return -1;
}
buffer_len = strlen(buffer);
tcsv_read_buffer(id, buffer, buffer_len);
}
- return (0);
+ return 0;
}
static void tcsv_metric_definition_destroy(void *arg) {
WARNING("tail_csv plugin: The \"%s\" config option needs exactly one "
"integer argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].value.number < 0) {
WARNING("tail_csv plugin: The \"%s\" config option must be positive "
"(or zero).",
ci->key);
- return (-1);
+ return -1;
}
*ret_index = (ssize_t)ci->values[0].value.number;
- return (0);
+ return 0;
}
/* Parse metric */
md = calloc(1, sizeof(*md));
if (md == NULL)
- return (-1);
+ return -1;
md->name = NULL;
md->type = NULL;
md->instance = NULL;
status = cf_util_get_string(ci, &md->name);
if (status != 0) {
sfree(md);
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->children_num; ++i) {
if (status != 0) {
tcsv_metric_definition_destroy(md);
- return (-1);
+ return -1;
}
/* Verify all necessary options have been set. */
}
if (status != 0) {
tcsv_metric_definition_destroy(md);
- return (status);
+ return status;
}
if (metric_head == NULL)
last->next = md;
}
- return (0);
+ return 0;
}
static void tcsv_instance_definition_destroy(void *arg) {
cu_tail_destroy(id->tail);
id->tail = NULL;
+ sfree(id->plugin_name);
sfree(id->instance);
sfree(id->path);
sfree(id->metric_list);
if (ci->values_num < 1) {
WARNING("tail_csv plugin: The `Collect' config option needs at least one "
"argument.");
- return (-1);
+ return -1;
}
metric_list_size = id->metric_list_len + (size_t)ci->values_num;
metric_list =
realloc(id->metric_list, sizeof(*id->metric_list) * metric_list_size);
if (metric_list == NULL)
- return (-1);
+ return -1;
id->metric_list = metric_list;
for (int i = 0; i < ci->values_num; i++) {
id->metric_list_len++;
}
- return (0);
+ return 0;
}
/* <File /> block */
int status = 0;
/* Registration variables */
+ cdtime_t interval = 0;
char cb_name[DATA_MAX_NAME_LEN];
id = calloc(1, sizeof(*id));
if (id == NULL)
- return (-1);
+ return -1;
+ id->plugin_name = NULL;
id->instance = NULL;
id->path = NULL;
id->metric_list = NULL;
status = cf_util_get_string(ci, &id->path);
if (status != 0) {
sfree(id);
- return (status);
+ return status;
}
- /* Use default interval. */
- id->interval = plugin_get_interval();
-
for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *option = ci->children + i;
status = 0;
else if (strcasecmp("Collect", option->key) == 0)
status = tcsv_config_add_instance_collect(id, option);
else if (strcasecmp("Interval", option->key) == 0)
- cf_util_get_cdtime(option, &id->interval);
+ cf_util_get_cdtime(option, &interval);
else if (strcasecmp("TimeFrom", option->key) == 0)
status = tcsv_config_get_index(option, &id->time_from);
+ else if (strcasecmp("Plugin", option->key) == 0)
+ status = cf_util_get_string(option, &id->plugin_name);
else {
WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key);
status = -1;
if (status != 0) {
tcsv_instance_definition_destroy(id);
- return (-1);
+ return -1;
}
/* Verify all necessary options have been set. */
if (status != 0) {
tcsv_instance_definition_destroy(id);
- return (-1);
+ return -1;
}
- ssnprintf(cb_name, sizeof(cb_name), "tail_csv/%s", id->path);
+ snprintf(cb_name, sizeof(cb_name), "tail_csv/%s", id->path);
status = plugin_register_complex_read(
- NULL, cb_name, tcsv_read, id->interval,
+ NULL, cb_name, tcsv_read, interval,
&(user_data_t){
.data = id, .free_func = tcsv_instance_definition_destroy,
});
if (status != 0) {
ERROR("tail_csv plugin: Registering complex read function failed.");
- tcsv_instance_definition_destroy(id);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
/* Parse blocks */
child->key);
}
- return (0);
+ return 0;
} /* int tcsv_config */
static int tcsv_init(void) { /* {{{ */
- static _Bool have_init = 0;
+ static bool have_init;
metric_definition_t *md;
if (have_init)
- return (0);
+ return 0;
for (md = metric_head; md != NULL; md = md->next) {
data_set_t const *ds;
md->type, md->name);
continue;
} else if (ds->ds_num != 1) {
- ERROR("tail_csv plugin: The type \"%s\" has %zu data sources. "
+ ERROR("tail_csv plugin: The type \"%s\" has %" PRIsz " data sources. "
"Only types with a single data source are supported.",
ds->type, ds->ds_num);
continue;
md->data_source_type = ds->ds->type;
}
- return (0);
+ return 0;
} /* }}} int tcsv_init */
static int tcsv_shutdown(void) {
tcsv_metric_definition_destroy(metric_head);
metric_head = NULL;
- return (0);
+ return 0;
}
void module_register(void) {
plugin_register_init("tail_csv", tcsv_init);
plugin_register_shutdown("tail_csv", tcsv_shutdown);
}
-
-/* vim: set sw=4 sts=4 et : */