static int redis_config_node (oconfig_item_t *ci) /* {{{ */ { redis_node_t rn; int i; int status; memset (&rn, 0, sizeof (rn)); sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host)); rn.port = REDIS_DEF_PORT; rn.timeout = REDIS_DEF_TIMEOUT; status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name)); if (status != 0) return (status); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; if (strcasecmp ("Host", option->key) == 0) status = cf_util_get_string_buffer (option, rn.host, sizeof (rn.host)); else if (strcasecmp ("Port", option->key) == 0) { status = cf_util_get_port_number (option); if (status > 0) { rn.port = status; status = 0; } } else if (strcasecmp ("Timeout", option->key) == 0) status = cf_util_get_int (option, &rn.timeout); else if (strcasecmp ("Password", option->key) == 0) status = cf_util_get_string_buffer (option, rn.passwd, sizeof (rn.passwd)); else WARNING ("redis plugin: Option `%s' not allowed inside a `Node' " "block. I'll ignore this option.", option->key); if (status != 0) break; } if (status != 0) return (status); return (redis_node_add (&rn)); } /* }}} int redis_config_node */
static int wr_config_node (oconfig_item_t *ci) /* {{{ */ { wr_node_t *node; int timeout; int status; int i; node = calloc (1, sizeof (*node)); if (node == NULL) return (ENOMEM); node->host = NULL; node->port = 0; node->timeout.tv_sec = 0; node->timeout.tv_usec = 1000; node->conn = NULL; node->prefix = NULL; node->database = 0; node->max_set_size = -1; node->store_rates = 1; pthread_mutex_init (&node->lock, /* attr = */ NULL); status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); if (status != 0) { sfree (node); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &node->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { node->port = status; status = 0; } } else if (strcasecmp ("Timeout", child->key) == 0) { status = cf_util_get_int (child, &timeout); if (status == 0) node->timeout.tv_usec = timeout; } else if (strcasecmp ("Prefix", child->key) == 0) { status = cf_util_get_string (child, &node->prefix); } else if (strcasecmp ("Database", child->key) == 0) { status = cf_util_get_int (child, &node->database); } else if (strcasecmp ("MaxSetSize", child->key) == 0) { status = cf_util_get_int (child, &node->max_set_size); } else if (strcasecmp ("StoreRates", child->key) == 0) { status = cf_util_get_boolean (child, &node->store_rates); } else WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; user_data_t ud; ssnprintf (cb_name, sizeof (cb_name), "write_redis/%s", node->name); ud.data = node; ud.free_func = wr_config_free; status = plugin_register_write (cb_name, wr_write, &ud); } if (status != 0) wr_config_free (node); return (status); } /* }}} int wr_config_node */
static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ _Bool publish) { camqp_config_t *conf; int status; int i; conf = malloc (sizeof (*conf)); if (conf == NULL) { ERROR ("amqp plugin: malloc failed."); return (ENOMEM); } /* Initialize "conf" {{{ */ memset (conf, 0, sizeof (*conf)); conf->publish = publish; conf->name = NULL; conf->format = CAMQP_FORMAT_COMMAND; conf->host = NULL; conf->port = 5672; conf->vhost = NULL; conf->user = NULL; conf->password = NULL; conf->exchange = NULL; conf->routing_key = NULL; /* publish only */ conf->delivery_mode = CAMQP_DM_VOLATILE; conf->store_rates = 0; /* publish & graphite only */ conf->prefix = NULL; conf->postfix = NULL; conf->escape_char = '_'; /* subscribe only */ conf->exchange_type = NULL; conf->queue = NULL; /* general */ conf->connection = NULL; pthread_mutex_init (&conf->lock, /* attr = */ NULL); /* }}} */ status = cf_util_get_string (ci, &conf->name); if (status != 0) { sfree (conf); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &conf->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { conf->port = status; status = 0; } } else if (strcasecmp ("VHost", child->key) == 0) status = cf_util_get_string (child, &conf->vhost); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &conf->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &conf->password); else if (strcasecmp ("Exchange", child->key) == 0) status = cf_util_get_string (child, &conf->exchange); else if ((strcasecmp ("ExchangeType", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->exchange_type); else if ((strcasecmp ("Queue", child->key) == 0) && !publish) status = cf_util_get_string (child, &conf->queue); else if (strcasecmp ("RoutingKey", child->key) == 0) status = cf_util_get_string (child, &conf->routing_key); else if ((strcasecmp ("Persistent", child->key) == 0) && publish) { _Bool tmp = 0; status = cf_util_get_boolean (child, &tmp); if (tmp) conf->delivery_mode = CAMQP_DM_PERSISTENT; else conf->delivery_mode = CAMQP_DM_VOLATILE; } else if ((strcasecmp ("StoreRates", child->key) == 0) && publish) status = cf_util_get_boolean (child, &conf->store_rates); else if ((strcasecmp ("Format", child->key) == 0) && publish) status = camqp_config_set_format (child, conf); else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish) status = cf_util_get_string (child, &conf->prefix); else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish) status = cf_util_get_string (child, &conf->postfix); else if ((strcasecmp ("GraphiteEscapeChar", child->key) == 0) && publish) { char *tmp_buff = NULL; status = cf_util_get_string (child, &tmp_buff); if (strlen (tmp_buff) > 1) WARNING ("amqp plugin: The option \"GraphiteEscapeChar\" handles " "only one character. Others will be ignored."); conf->escape_char = tmp_buff[0]; sfree (tmp_buff); } else WARNING ("amqp plugin: Ignoring unknown " "configuration option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if ((status == 0) && (conf->exchange == NULL)) { if (conf->exchange_type != NULL) WARNING ("amqp plugin: The option \"ExchangeType\" was given " "without the \"Exchange\" option. It will be ignored."); if (!publish && (conf->routing_key != NULL)) WARNING ("amqp plugin: The option \"RoutingKey\" was given " "without the \"Exchange\" option. It will be ignored."); } if (status != 0) { camqp_config_free (conf); return (status); } if (conf->exchange != NULL) { DEBUG ("amqp plugin: camqp_config_connection: exchange = %s;", conf->exchange); } if (publish) { char cbname[128]; user_data_t ud = { conf, camqp_config_free }; ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name); status = plugin_register_write (cbname, camqp_write, &ud); if (status != 0) { camqp_config_free (conf); return (status); } } else { status = camqp_subscribe_init (conf); if (status != 0) { camqp_config_free (conf); return (status); } } return (0); } /* }}} int camqp_config_connection */
/* Configuration handling functions {{{ * * <Plugin mysql> * <Database "plugin_instance1"> * Host "localhost" * Port 22000 * ... * </Database> * </Plugin> */ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */ { mysql_database_t *db; int status = 0; int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { WARNING ("mysql plugin: The `Database' block " "needs exactly one string argument."); return (-1); } db = (mysql_database_t *) malloc (sizeof (*db)); if (db == NULL) { ERROR ("mysql plugin: malloc failed."); return (-1); } memset (db, 0, sizeof (*db)); /* initialize all the pointers */ db->host = NULL; db->user = NULL; db->pass = NULL; db->database = NULL; db->socket = NULL; db->con = NULL; /* trigger a notification, if it's not running */ db->slave_io_running = 1; db->slave_sql_running = 1; status = cf_util_get_string (ci, &db->instance); if (status != 0) { sfree (db); return (status); } assert (db->instance != NULL); /* Fill the `mysql_database_t' structure.. */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &db->host); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &db->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &db->pass); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { db->port = status; status = 0; } } else if (strcasecmp ("Socket", child->key) == 0) status = cf_util_get_string (child, &db->socket); else if (strcasecmp ("Database", child->key) == 0) status = cf_util_get_string (child, &db->database); else if (strcasecmp ("MasterStats", child->key) == 0) status = cf_util_get_boolean (child, &db->master_stats); else if (strcasecmp ("SlaveStats", child->key) == 0) status = cf_util_get_boolean (child, &db->slave_stats); else if (strcasecmp ("SlaveNotifications", child->key) == 0) status = cf_util_get_boolean (child, &db->slave_notif); else { WARNING ("mysql plugin: Option `%s' not allowed here.", child->key); status = -1; } if (status != 0) break; } /* If all went well, register this database for reading */ if (status == 0) { user_data_t ud; char cb_name[DATA_MAX_NAME_LEN]; DEBUG ("mysql plugin: Registering new read callback: %s", (db->database != NULL) ? db->database : "<default>"); memset (&ud, 0, sizeof (ud)); ud.data = (void *) db; ud.free_func = mysql_database_free; if (db->instance != NULL) ssnprintf (cb_name, sizeof (cb_name), "mysql-%s", db->instance); else sstrncpy (cb_name, "mysql", sizeof (cb_name)); plugin_register_complex_read (/* group = */ NULL, cb_name, mysql_read, /* interval = */ NULL, &ud); } else { mysql_database_free (db); return (-1); } return (0); } /* }}} int mysql_config_database */
static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */ { mb_host_t *host; int status; int i; host = malloc (sizeof (*host)); if (host == NULL) return (ENOMEM); memset (host, 0, sizeof (*host)); host->slaves = NULL; status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host)); if (status != 0) return (status); if (host->host[0] == 0) return (EINVAL); for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; status = 0; if (strcasecmp ("Address", child->key) == 0) { char buffer[NI_MAXHOST]; status = cf_util_get_string_buffer (child, buffer, sizeof (buffer)); if (status == 0) status = mb_config_set_host_address (host, buffer); } else if (strcasecmp ("Port", child->key) == 0) { host->port = cf_util_get_port_number (child); if (host->port <= 0) status = -1; } else if (strcasecmp ("Interval", child->key) == 0) status = cf_util_get_cdtime (child, &host->interval); else if (strcasecmp ("Slave", child->key) == 0) /* Don't set status: Gracefully continue if a slave fails. */ mb_config_add_slave (host, child); else { ERROR ("Modbus plugin: Unknown configuration option: %s", child->key); status = -1; } if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ assert (host->host[0] != 0); if (host->host[0] == 0) { ERROR ("Modbus plugin: Data block \"%s\": No type has been specified.", host->host); status = -1; } if (status == 0) { user_data_t ud; char name[1024]; struct timespec interval = { 0, 0 }; ud.data = host; ud.free_func = host_free; ssnprintf (name, sizeof (name), "modbus-%s", host->host); CDTIME_T_TO_TIMESPEC (host->interval, &interval); plugin_register_complex_read (/* group = */ NULL, name, /* callback = */ mb_read, /* interval = */ (host->interval > 0) ? &interval : NULL, &ud); } else { host_free (host); } return (status); } /* }}} int mb_config_add_host */
static int wm_config_node (oconfig_item_t *ci) /* {{{ */ { wm_node_t *node; int status; node = calloc (1, sizeof (*node)); if (node == NULL) return (ENOMEM); mongo_init (node->conn); node->host = NULL; node->store_rates = 1; pthread_mutex_init (&node->lock, /* attr = */ NULL); status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); if (status != 0) { sfree (node); return (status); } for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &node->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { node->port = status; status = 0; } } else if (strcasecmp ("Timeout", child->key) == 0) status = cf_util_get_int (child, &node->timeout); else if (strcasecmp ("StoreRates", child->key) == 0) status = cf_util_get_boolean (child, &node->store_rates); else if (strcasecmp ("Database", child->key) == 0) status = cf_util_get_string (child, &node->db); else if (strcasecmp ("User", child->key) == 0) status = cf_util_get_string (child, &node->user); else if (strcasecmp ("Password", child->key) == 0) status = cf_util_get_string (child, &node->passwd); else WARNING ("write_mongodb plugin: Ignoring unknown config option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if ((node->db != NULL) || (node->user != NULL) || (node->passwd != NULL)) { if ((node->db == NULL) || (node->user == NULL) || (node->passwd == NULL)) { WARNING ("write_mongodb plugin: Authentication requires the " "\"Database\", \"User\" and \"Password\" options to be specified, " "but at last one of them is missing. Authentication will NOT be " "used."); sfree (node->db); sfree (node->user); sfree (node->passwd); } } if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; user_data_t ud; ssnprintf (cb_name, sizeof (cb_name), "write_mongodb/%s", node->name); ud.data = node; ud.free_func = wm_config_free; status = plugin_register_write (cb_name, wm_write, &ud); INFO ("write_mongodb plugin: registered write plugin %s %d",cb_name,status); } if (status != 0) wm_config_free (node); return (status); } /* }}} int wm_config_node */
static int wm_config_node (oconfig_item_t *ci) /* {{{ */ { wm_node_t *node; int status; int i; node = malloc (sizeof (*node)); if (node == NULL) return (ENOMEM); memset (node, 0, sizeof (*node)); mongo_init (node->conn); node->host = NULL; node->store_rates = 1; pthread_mutex_init (&node->lock, /* attr = */ NULL); status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name)); if (status != 0) { sfree (node); return (status); } for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("Host", child->key) == 0) status = cf_util_get_string (child, &node->host); else if (strcasecmp ("Port", child->key) == 0) { status = cf_util_get_port_number (child); if (status > 0) { node->port = status; status = 0; } } else if (strcasecmp ("Timeout", child->key) == 0) status = cf_util_get_int (child, &node->timeout); else if (strcasecmp ("StoreRates", child->key) == 0) status = cf_util_get_boolean (child, &node->store_rates); else WARNING ("write_mongodb plugin: Ignoring unknown config option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if (status == 0) { char cb_name[DATA_MAX_NAME_LEN]; user_data_t ud; ssnprintf (cb_name, sizeof (cb_name), "write_mongodb/%s", node->name); ud.data = node; ud.free_func = wm_config_free; status = plugin_register_write (cb_name, wm_write, &ud); INFO ("write_mongodb plugin: registered write plugin %s %d",cb_name,status); } if (status != 0) wm_config_free (node); return (status); } /* }}} int wm_config_node */
static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */ bool publish) { camqp_config_t *conf; int status; conf = calloc(1, sizeof(*conf)); if (conf == NULL) { ERROR("amqp plugin: calloc failed."); return ENOMEM; } /* Initialize "conf" {{{ */ conf->publish = publish; conf->name = NULL; conf->format = CAMQP_FORMAT_COMMAND; conf->host = NULL; conf->port = 5672; conf->vhost = NULL; conf->user = NULL; conf->password = NULL; conf->exchange = NULL; conf->routing_key = NULL; conf->connection_retry_delay = 0; /* publish only */ conf->delivery_mode = CAMQP_DM_VOLATILE; conf->store_rates = false; conf->graphite_flags = 0; /* publish & graphite only */ conf->prefix = NULL; conf->postfix = NULL; conf->escape_char = '_'; /* subscribe only */ conf->exchange_type = NULL; conf->queue = NULL; conf->queue_durable = false; conf->queue_auto_delete = true; /* general */ conf->connection = NULL; pthread_mutex_init(&conf->lock, /* attr = */ NULL); /* }}} */ status = cf_util_get_string(ci, &conf->name); if (status != 0) { sfree(conf); return status; } for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp("Host", child->key) == 0) status = cf_util_get_string(child, &conf->host); else if (strcasecmp("Port", child->key) == 0) { status = cf_util_get_port_number(child); if (status > 0) { conf->port = status; status = 0; } } else if (strcasecmp("VHost", child->key) == 0) status = cf_util_get_string(child, &conf->vhost); else if (strcasecmp("User", child->key) == 0) status = cf_util_get_string(child, &conf->user); else if (strcasecmp("Password", child->key) == 0) status = cf_util_get_string(child, &conf->password); else if (strcasecmp("Exchange", child->key) == 0) status = cf_util_get_string(child, &conf->exchange); else if (strcasecmp("ExchangeType", child->key) == 0) status = cf_util_get_string(child, &conf->exchange_type); else if ((strcasecmp("Queue", child->key) == 0) && !publish) status = cf_util_get_string(child, &conf->queue); else if ((strcasecmp("QueueDurable", child->key) == 0) && !publish) status = cf_util_get_boolean(child, &conf->queue_durable); else if ((strcasecmp("QueueAutoDelete", child->key) == 0) && !publish) status = cf_util_get_boolean(child, &conf->queue_auto_delete); else if (strcasecmp("RoutingKey", child->key) == 0) status = cf_util_get_string(child, &conf->routing_key); else if ((strcasecmp("Persistent", child->key) == 0) && publish) { bool tmp = 0; status = cf_util_get_boolean(child, &tmp); if (tmp) conf->delivery_mode = CAMQP_DM_PERSISTENT; else conf->delivery_mode = CAMQP_DM_VOLATILE; } else if ((strcasecmp("StoreRates", child->key) == 0) && publish) { status = cf_util_get_boolean(child, &conf->store_rates); (void)cf_util_get_flag(child, &conf->graphite_flags, GRAPHITE_STORE_RATES); } else if ((strcasecmp("Format", child->key) == 0) && publish) status = camqp_config_set_format(child, conf); else if ((strcasecmp("GraphiteSeparateInstances", child->key) == 0) && publish) status = cf_util_get_flag(child, &conf->graphite_flags, GRAPHITE_SEPARATE_INSTANCES); else if ((strcasecmp("GraphiteAlwaysAppendDS", child->key) == 0) && publish) status = cf_util_get_flag(child, &conf->graphite_flags, GRAPHITE_ALWAYS_APPEND_DS); else if ((strcasecmp("GraphitePreserveSeparator", child->key) == 0) && publish) status = cf_util_get_flag(child, &conf->graphite_flags, GRAPHITE_PRESERVE_SEPARATOR); else if ((strcasecmp("GraphitePrefix", child->key) == 0) && publish) status = cf_util_get_string(child, &conf->prefix); else if ((strcasecmp("GraphitePostfix", child->key) == 0) && publish) status = cf_util_get_string(child, &conf->postfix); else if ((strcasecmp("GraphiteEscapeChar", child->key) == 0) && publish) { char *tmp_buff = NULL; status = cf_util_get_string(child, &tmp_buff); if (strlen(tmp_buff) > 1) WARNING("amqp plugin: The option \"GraphiteEscapeChar\" handles " "only one character. Others will be ignored."); conf->escape_char = tmp_buff[0]; sfree(tmp_buff); } else if (strcasecmp("ConnectionRetryDelay", child->key) == 0) status = cf_util_get_int(child, &conf->connection_retry_delay); else WARNING("amqp plugin: Ignoring unknown " "configuration option \"%s\".", child->key); if (status != 0) break; } /* for (i = 0; i < ci->children_num; i++) */ if ((status == 0) && (conf->exchange == NULL)) { if (conf->exchange_type != NULL) WARNING("amqp plugin: The option \"ExchangeType\" was given " "without the \"Exchange\" option. It will be ignored."); if (!publish && (conf->routing_key != NULL)) WARNING("amqp plugin: The option \"RoutingKey\" was given " "without the \"Exchange\" option. It will be ignored."); } if (status != 0) { camqp_config_free(conf); return status; } if (conf->exchange != NULL) { DEBUG("amqp plugin: camqp_config_connection: exchange = %s;", conf->exchange); } if (publish) { char cbname[128]; snprintf(cbname, sizeof(cbname), "amqp/%s", conf->name); status = plugin_register_write(cbname, camqp_write, &(user_data_t){ .data = conf, .free_func = camqp_config_free, }); if (status != 0) { camqp_config_free(conf); return status; } } else {
static int redis_config_node (oconfig_item_t *ci) /* {{{ */ { redis_query_t *rq; int status; int timeout; redis_node_t rn = { .port = REDIS_DEF_PORT, .timeout.tv_usec = REDIS_DEF_TIMEOUT }; sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host)); status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name)); if (status != 0) return (status); for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; if (strcasecmp ("Host", option->key) == 0) status = cf_util_get_string_buffer (option, rn.host, sizeof (rn.host)); else if (strcasecmp ("Port", option->key) == 0) { status = cf_util_get_port_number (option); if (status > 0) { rn.port = status; status = 0; } } else if (strcasecmp ("Query", option->key) == 0) { rq = redis_config_query(option); if (rq == NULL) { status =1; } else { rq->next = rn.queries; rn.queries = rq; } } else if (strcasecmp ("Timeout", option->key) == 0) { status = cf_util_get_int (option, &timeout); if (status == 0) rn.timeout.tv_usec = timeout; } else if (strcasecmp ("Password", option->key) == 0) status = cf_util_get_string_buffer (option, rn.passwd, sizeof (rn.passwd)); else WARNING ("redis plugin: Option `%s' not allowed inside a `Node' " "block. I'll ignore this option.", option->key); if (status != 0) break; } if (status != 0) return (status); return (redis_node_add (&rn)); } /* }}} int redis_config_node */ static int redis_config (oconfig_item_t *ci) /* {{{ */ { for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; if (strcasecmp ("Node", option->key) == 0) redis_config_node (option); else WARNING ("redis plugin: Option `%s' not allowed in redis" " configuration. It will be ignored.", option->key); } if (nodes_head == NULL) { ERROR ("redis plugin: No valid node configuration could be found."); return (ENOENT); } return (0); } /* }}} */ __attribute__ ((nonnull(2))) static void redis_submit (char *plugin_instance, const char *type, const char *type_instance, value_t value) /* {{{ */ { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; values[0] = value; vl.values = values; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "redis", sizeof (vl.plugin)); if (plugin_instance != NULL) sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); if (type_instance != NULL) sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /* }}} */