X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Ftail_csv.c;h=c3efcc9a3d3c79c844590f5a898b5c45ccb00de0;hb=0ba2f3a1a1db4ed7ce6f990b22b9605e19fc7ab9;hp=dc89f0d70b01c10a8d2941d754c80326d4cf31f7;hpb=c842ed2091ed748da35295856d5c4a1042291a17;p=collectd.git diff --git a/src/tail_csv.c b/src/tail_csv.c index dc89f0d7..c3efcc9a 100644 --- a/src/tail_csv.c +++ b/src/tail_csv.c @@ -37,7 +37,7 @@ struct metric_definition_s { char *type; char *instance; int data_source_type; - int index; + int value_from; struct metric_definition_s *next; }; typedef struct metric_definition_s metric_definition_t; @@ -49,6 +49,7 @@ struct instance_definition_s { metric_definition_t **metric_list; size_t metric_list_len; cdtime_t interval; + int time_from; struct instance_definition_s *next; }; typedef struct instance_definition_s instance_definition_t; @@ -105,18 +106,36 @@ static int tcsv_read_metric (instance_definition_t *id, if (md->data_source_type == -1) return (EINVAL); - if (md->index >= fields_num) + if (md->value_from >= fields_num) + return (EINVAL); + + if (id->time_from >= 0 && (id->time_from >= fields_num)) return (EINVAL); - t = parse_time (fields[0]); + t = 0; + if (id->time_from >= 0) + t = parse_time (fields[id->time_from]); - status = parse_value (fields[md->index], &v, md->data_source_type); + status = parse_value (fields[md->value_from], &v, md->data_source_type); if (status != 0) return (status); return (tcsv_submit (id, md, v, t)); } +static _Bool tcsv_check_index (int index, size_t fields_num, char const *name) +{ + if (index < 0) + return 1; + else if (((size_t) index) < fields_num) + return 1; + + ERROR ("tail_csv plugin: Metric \"%s\": Request for index %i when " + "only %zu fields are available.", + name, index, fields_num); + return (0); +} + static int tcsv_read_buffer (instance_definition_t *id, char *buffer, size_t buffer_size) { @@ -178,12 +197,9 @@ static int tcsv_read_buffer (instance_definition_t *id, for (i = 0; i < id->metric_list_len; ++i){ metric_definition_t *md = id->metric_list[i]; - if (((size_t) md->index) >= metrics_num) { - ERROR ("tail_csv plugin: Metric \"%s\": Request for index %i when " - "only %zu fields are available.", - md->name, md->index, metrics_num); + if (!tcsv_check_index (md->value_from, metrics_num, md->name) + || !tcsv_check_index (id->time_from, metrics_num, md->name)) continue; - } tcsv_read_metric (id, md, metrics, metrics_num); } @@ -251,18 +267,23 @@ static void tcsv_metric_definition_destroy(void *arg){ tcsv_metric_definition_destroy (next); } -static int tcsv_config_add_metric_index(metric_definition_t *md, oconfig_item_t *ci){ +static int tcsv_config_get_index(oconfig_item_t *ci, int *ret_index) { + int index; + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)){ - WARNING("tail_csv plugin: `Index' needs exactly one integer argument."); + WARNING("tail_csv plugin: The \"%s\" config option needs exactly one " + "integer argument.", ci->key); return (-1); } - md->index = (int)ci->values[0].value.number; - if (md->index <= 0){ - WARNING("tail_csv plugin: `Index' must be higher than 0."); + index = (int) ci->values[0].value.number; + if (index < 0) { + WARNING("tail_csv plugin: The \"%s\" config option must be positive " + "(or zero).", ci->key); return (-1); } + *ret_index = index; return (0); } @@ -280,6 +301,7 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){ md->type = NULL; md->instance = NULL; md->data_source_type = -1; + md->value_from = -1; md->next = NULL; status = cf_util_get_string (ci, &md->name); @@ -290,14 +312,13 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){ for (i = 0; i < ci->children_num; ++i){ oconfig_item_t *option = ci->children + i; - status = 0; if (strcasecmp("Type", option->key) == 0) status = cf_util_get_string(option, &md->type); else if (strcasecmp("Instance", option->key) == 0) status = cf_util_get_string(option, &md->instance); - else if (strcasecmp("Index", option->key) == 0) - status = tcsv_config_add_metric_index(md, option); + else if (strcasecmp("ValueFrom", option->key) == 0) + status = tcsv_config_get_index (option, &md->value_from); else { WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); status = -1; @@ -316,8 +337,8 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){ if (md->type == NULL) { WARNING("tail_csv plugin: Option `Type' must be set."); status = -1; - } else if (md->index == 0) { - WARNING("tail_csv plugin: Option `Index' must be set."); + } else if (md->value_from < 0) { + WARNING("tail_csv plugin: Option `ValueFrom' must be set."); status = -1; } if (status != 0) { @@ -325,9 +346,6 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){ return (status); } - DEBUG ("tail_csv plugin: md = { name = %s, type = %s, index = %d }", - md->name, md->type, md->index); - if (metric_head == NULL) metric_head = md; else { @@ -348,7 +366,8 @@ static void tcsv_instance_definition_destroy(void *arg){ if (id == NULL) return; - cu_tail_destroy (id->tail); + if (id->tail != NULL) + cu_tail_destroy (id->tail); id->tail = NULL; sfree(id->instance); @@ -357,37 +376,42 @@ static void tcsv_instance_definition_destroy(void *arg){ sfree(id); } -static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_item_t *ci){ +static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_item_t *ci) { metric_definition_t *metric; + metric_definition_t **metric_list; + size_t metric_list_size; int i; - if (ci->values_num < 1){ + if (ci->values_num < 1) { WARNING("tail_csv plugin: The `Collect' config option needs at least one argument."); return (-1); } - /* Verify string arguments */ - for (i = 0; i < ci->values_num; ++i) - if (ci->values[i].type != OCONFIG_TYPE_STRING){ + 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); + id->metric_list = metric_list; + + for (i = 0; i < ci->values_num; i++) { + char *metric_name; + + if (ci->values[i].type != OCONFIG_TYPE_STRING) { WARNING("tail_csv plugin: All arguments to `Collect' must be strings."); - return (-1); + continue; } + metric_name = ci->values[i].value.string; - id->metric_list = (metric_definition_t **)malloc(sizeof(metric_definition_t *) * ci->values_num); - if (id->metric_list == NULL) - return (-1); - - for (i = 0; i < ci->values_num; ++i){ for (metric = metric_head; metric != NULL; metric = metric->next) - if (strcasecmp(ci->values[i].value.string, metric->name) == 0) + if (strcasecmp(metric_name, metric->name) == 0) break; - if (metric == NULL){ - WARNING("tail_csv plugin: `Collect' argument not found `%s'.", ci->values[i].value.string); - return (-1); + if (metric == NULL) { + WARNING ("tail_csv plugin: `Collect' argument not found `%s'.", metric_name); + continue; } - id->metric_list[i] = metric; + id->metric_list[id->metric_list_len] = metric; id->metric_list_len++; } @@ -413,6 +437,7 @@ static int tcsv_config_add_file(oconfig_item_t *ci) id->instance = NULL; id->path = NULL; id->metric_list = NULL; + id->time_from = -1; id->next = NULL; status = cf_util_get_string (ci, &id->path); @@ -434,6 +459,8 @@ static int tcsv_config_add_file(oconfig_item_t *ci) status = tcsv_config_add_instance_collect(id, option); else if (strcasecmp("Interval", option->key) == 0) cf_util_get_cdtime(option, &id->interval); + else if (strcasecmp("TimeFrom", option->key) == 0) + status = tcsv_config_get_index (option, &id->time_from); else { WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key); status = -1;