X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdaemon%2Fplugin.c;h=daddf684babdf85bf23c81df7e0e7f5b3f3b0639;hp=92e1ab261288cb7a653aac1f33e68284180625b6;hb=0bbf058d6f9935e6e727cda7db79312281e2f58d;hpb=b626c5956e7289cb3d7fceb230baba0182f36d68 diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 92e1ab26..daddf684 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -30,18 +30,26 @@ #include "collectd.h" -#include "common.h" #include "configfile.h" #include "filter_chain.h" #include "plugin.h" -#include "utils_avltree.h" +#include "utils/avltree/avltree.h" +#include "utils/common/common.h" +#include "utils/heap/heap.h" #include "utils_cache.h" #include "utils_complain.h" -#include "utils_heap.h" #include "utils_llist.h" #include "utils_random.h" #include "utils_time.h" +#ifdef WIN32 +#define EXPORT __declspec(dllexport) +#include +#include +#else +#define EXPORT +#endif + #if HAVE_PTHREAD_NP_H #include /* for pthread_set_name_np(3) */ #endif @@ -138,6 +146,7 @@ static bool plugin_ctx_key_initialized; static long write_limit_high; static long write_limit_low; +static pthread_mutex_t statistics_lock = PTHREAD_MUTEX_INITIALIZER; static derive_t stats_values_dropped; static bool record_statistics; @@ -292,10 +301,10 @@ static int register_callback(llist_t **list, /* {{{ */ old_cf = le->value; le->value = cf; - WARNING("plugin: register_callback: " - "a callback named `%s' already exists - " - "overwriting the old entry!", - name); + P_WARNING("register_callback: " + "a callback named `%s' already exists - " + "overwriting the old entry!", + name); destroy_callback(old_cf); sfree(key); @@ -311,19 +320,16 @@ static void log_list_callbacks(llist_t **list, /* {{{ */ int i; llentry_t *le; int n; - char **keys; n = llist_size(*list); if (n == 0) { - INFO("%s [none]", comment); + INFO("%s: [none]", comment); return; } - keys = calloc(n, sizeof(char *)); - + char **keys = calloc(n, sizeof(*keys)); if (keys == NULL) { ERROR("%s: failed to allocate memory for list of callbacks", comment); - return; } @@ -360,7 +366,8 @@ static int create_register_callback(llist_t **list, /* {{{ */ cf->cf_callback = callback; if (ud == NULL) { cf->cf_udata = (user_data_t){ - .data = NULL, .free_func = NULL, + .data = NULL, + .free_func = NULL, }; } else { cf->cf_udata = *ud; @@ -621,7 +628,7 @@ static void start_read_threads(size_t num) /* {{{ */ if (read_threads != NULL) return; - read_threads = (pthread_t *)calloc(num, sizeof(pthread_t)); + read_threads = calloc(num, sizeof(*read_threads)); if (read_threads == NULL) { ERROR("plugin: start_read_threads: calloc failed."); return; @@ -640,7 +647,8 @@ static void start_read_threads(size_t num) /* {{{ */ } char name[THREAD_NAME_MAX]; - snprintf(name, sizeof(name), "reader#%" PRIsz, read_threads_num); + ssnprintf(name, sizeof(name), "reader#%" PRIu64, + (uint64_t)read_threads_num); set_thread_name(read_threads[read_threads_num], name); read_threads_num++; @@ -713,25 +721,8 @@ plugin_value_list_clone(value_list_t const *vl_orig) /* {{{ */ vl->time = cdtime(); /* Fill in the interval from the thread context, if it is zero. */ - if (vl->interval == 0) { - plugin_ctx_t ctx = plugin_get_ctx(); - - if (ctx.interval != 0) - vl->interval = ctx.interval; - else { - char name[6 * DATA_MAX_NAME_LEN]; - FORMAT_VL(name, sizeof(name), vl); - ERROR("plugin_value_list_clone: Unable to determine " - "interval from context for " - "value list \"%s\". " - "This indicates a broken plugin. " - "Please report this problem to the " - "collectd mailing list or at " - ".", - name); - vl->interval = cf_get_default_interval(); - } - } + if (vl->interval == 0) + vl->interval = plugin_get_interval(); return vl; } /* }}} value_list_t *plugin_value_list_clone */ @@ -827,7 +818,7 @@ static void start_write_threads(size_t num) /* {{{ */ if (write_threads != NULL) return; - write_threads = (pthread_t *)calloc(num, sizeof(pthread_t)); + write_threads = calloc(num, sizeof(*write_threads)); if (write_threads == NULL) { ERROR("plugin: start_write_threads: calloc failed."); return; @@ -846,7 +837,8 @@ static void start_write_threads(size_t num) /* {{{ */ } char name[THREAD_NAME_MAX]; - snprintf(name, sizeof(name), "writer#%" PRIsz, write_threads_num); + ssnprintf(name, sizeof(name), "writer#%" PRIu64, + (uint64_t)write_threads_num); set_thread_name(write_threads[write_threads_num], name); write_threads_num++; @@ -915,15 +907,13 @@ void plugin_set_dir(const char *dir) { ERROR("plugin_set_dir: strdup(\"%s\") failed", dir); } -static bool plugin_is_loaded(char const *name) { - int status; - +bool plugin_is_loaded(char const *name) { if (plugins_loaded == NULL) plugins_loaded = c_avl_create((int (*)(const void *, const void *))strcasecmp); assert(plugins_loaded != NULL); - status = c_avl_get(plugins_loaded, name, /* ret_value = */ NULL); + int status = c_avl_get(plugins_loaded, name, /* ret_value = */ NULL); return status == 0; } @@ -957,6 +947,11 @@ static void plugin_free_loaded(void) { } #define BUFSIZE 512 +#ifdef WIN32 +#define SHLIB_SUFFIX ".dll" +#else +#define SHLIB_SUFFIX ".so" +#endif int plugin_load(char const *plugin_name, bool global) { DIR *dh; const char *dir; @@ -993,11 +988,12 @@ int plugin_load(char const *plugin_name, bool global) { (strcasecmp("python", plugin_name) == 0)) global = true; - /* `cpu' should not match `cpufreq'. To solve this we add `.so' to the + /* `cpu' should not match `cpufreq'. To solve this we add SHLIB_SUFFIX to the * type when matching the filename */ - status = snprintf(typename, sizeof(typename), "%s.so", plugin_name); + status = snprintf(typename, sizeof(typename), "%s" SHLIB_SUFFIX, plugin_name); if ((status < 0) || ((size_t)status >= sizeof(typename))) { - WARNING("plugin_load: Filename too long: \"%s.so\"", plugin_name); + WARNING("plugin_load: Filename too long: \"%s" SHLIB_SUFFIX "\"", + plugin_name); return -1; } @@ -1050,19 +1046,20 @@ int plugin_load(char const *plugin_name, bool global) { /* * The `register_*' functions follow */ -int plugin_register_config(const char *name, - int (*callback)(const char *key, const char *val), - const char **keys, int keys_num) { +EXPORT int plugin_register_config(const char *name, + int (*callback)(const char *key, + const char *val), + const char **keys, int keys_num) { cf_register(name, callback, keys, keys_num); return 0; } /* int plugin_register_config */ -int plugin_register_complex_config(const char *type, - int (*callback)(oconfig_item_t *)) { +EXPORT int plugin_register_complex_config(const char *type, + int (*callback)(oconfig_item_t *)) { return cf_register_complex(type, callback); } /* int plugin_register_complex_config */ -int plugin_register_init(const char *name, int (*callback)(void)) { +EXPORT int plugin_register_init(const char *name, int (*callback)(void)) { return create_register_callback(&list_init, name, (void *)callback, NULL); } /* plugin_register_init */ @@ -1114,9 +1111,9 @@ static int plugin_insert_read(read_func_t *rf) { le = llist_search(read_list, rf->rf_name); if (le != NULL) { pthread_mutex_unlock(&read_lock); - WARNING("The read function \"%s\" is already registered. " - "Check for duplicates in your configuration!", - rf->rf_name); + P_WARNING("The read function \"%s\" is already registered. " + "Check for duplicates in your configuration!", + rf->rf_name); return EINVAL; } @@ -1144,7 +1141,7 @@ static int plugin_insert_read(read_func_t *rf) { return 0; } /* int plugin_insert_read */ -int plugin_register_read(const char *name, int (*callback)(void)) { +EXPORT int plugin_register_read(const char *name, int (*callback)(void)) { read_func_t *rf; int status; @@ -1162,6 +1159,7 @@ int plugin_register_read(const char *name, int (*callback)(void)) { rf->rf_name = strdup(name); rf->rf_type = RF_SIMPLE; rf->rf_interval = plugin_get_interval(); + rf->rf_ctx.interval = rf->rf_interval; status = plugin_insert_read(rf); if (status != 0) { @@ -1172,9 +1170,10 @@ int plugin_register_read(const char *name, int (*callback)(void)) { return status; } /* int plugin_register_read */ -int plugin_register_complex_read(const char *group, const char *name, - plugin_read_cb callback, cdtime_t interval, - user_data_t const *user_data) { +EXPORT int plugin_register_complex_read(const char *group, const char *name, + plugin_read_cb callback, + cdtime_t interval, + user_data_t const *user_data) { read_func_t *rf; int status; @@ -1203,6 +1202,7 @@ int plugin_register_complex_read(const char *group, const char *name, } rf->rf_ctx = plugin_get_ctx(); + rf->rf_ctx.interval = rf->rf_interval; status = plugin_insert_read(rf); if (status != 0) { @@ -1214,8 +1214,8 @@ int plugin_register_complex_read(const char *group, const char *name, return status; } /* int plugin_register_complex_read */ -int plugin_register_write(const char *name, plugin_write_cb callback, - user_data_t const *ud) { +EXPORT int plugin_register_write(const char *name, plugin_write_cb callback, + user_data_t const *ud) { return create_register_callback(&list_write, name, (void *)callback, ud); } /* int plugin_register_write */ @@ -1256,8 +1256,8 @@ static char *plugin_flush_callback_name(const char *name) { return flush_name; } /* static char *plugin_flush_callback_name */ -int plugin_register_flush(const char *name, plugin_flush_cb callback, - user_data_t const *ud) { +EXPORT int plugin_register_flush(const char *name, plugin_flush_cb callback, + user_data_t const *ud) { int status; plugin_ctx_t ctx = plugin_get_ctx(); @@ -1294,8 +1294,10 @@ int plugin_register_flush(const char *name, plugin_flush_cb callback, /* name = */ flush_name, /* callback = */ plugin_flush_timeout_callback, /* interval = */ ctx.flush_interval, - /* user data = */ &(user_data_t){ - .data = cb, .free_func = plugin_flush_timeout_callback_free, + /* user data = */ + &(user_data_t){ + .data = cb, + .free_func = plugin_flush_timeout_callback_free, }); sfree(flush_name); @@ -1305,12 +1307,12 @@ int plugin_register_flush(const char *name, plugin_flush_cb callback, return 0; } /* int plugin_register_flush */ -int plugin_register_missing(const char *name, plugin_missing_cb callback, - user_data_t const *ud) { +EXPORT int plugin_register_missing(const char *name, plugin_missing_cb callback, + user_data_t const *ud) { return create_register_callback(&list_missing, name, (void *)callback, ud); } /* int plugin_register_missing */ -int plugin_register_shutdown(const char *name, int (*callback)(void)) { +EXPORT int plugin_register_shutdown(const char *name, int (*callback)(void)) { return create_register_callback(&list_shutdown, name, (void *)callback, NULL); } /* int plugin_register_shutdown */ @@ -1333,7 +1335,7 @@ static void plugin_free_data_sets(void) { data_sets = NULL; } /* void plugin_free_data_sets */ -int plugin_register_data_set(const data_set_t *ds) { +EXPORT int plugin_register_data_set(const data_set_t *ds) { data_set_t *ds_copy; if ((data_sets != NULL) && (c_avl_get(data_sets, ds->type, NULL) == 0)) { @@ -1362,33 +1364,33 @@ int plugin_register_data_set(const data_set_t *ds) { return c_avl_insert(data_sets, (void *)ds_copy->type, (void *)ds_copy); } /* int plugin_register_data_set */ -int plugin_register_log(const char *name, plugin_log_cb callback, - user_data_t const *ud) { +EXPORT int plugin_register_log(const char *name, plugin_log_cb callback, + user_data_t const *ud) { return create_register_callback(&list_log, name, (void *)callback, ud); } /* int plugin_register_log */ -int plugin_register_notification(const char *name, - plugin_notification_cb callback, - user_data_t const *ud) { +EXPORT int plugin_register_notification(const char *name, + plugin_notification_cb callback, + user_data_t const *ud) { return create_register_callback(&list_notification, name, (void *)callback, ud); } /* int plugin_register_log */ -int plugin_unregister_config(const char *name) { +EXPORT int plugin_unregister_config(const char *name) { cf_unregister(name); return 0; } /* int plugin_unregister_config */ -int plugin_unregister_complex_config(const char *name) { +EXPORT int plugin_unregister_complex_config(const char *name) { cf_unregister_complex(name); return 0; } /* int plugin_unregister_complex_config */ -int plugin_unregister_init(const char *name) { +EXPORT int plugin_unregister_init(const char *name) { return plugin_unregister(list_init, name); } -int plugin_unregister_read(const char *name) /* {{{ */ +EXPORT int plugin_unregister_read(const char *name) /* {{{ */ { llentry_t *le; read_func_t *rf; @@ -1425,7 +1427,7 @@ int plugin_unregister_read(const char *name) /* {{{ */ return 0; } /* }}} int plugin_unregister_read */ -void plugin_log_available_writers(void) { +EXPORT void plugin_log_available_writers(void) { log_list_callbacks(&list_write, "Available write targets:"); } @@ -1437,7 +1439,7 @@ static int compare_read_func_group(llentry_t *e, void *ud) /* {{{ */ return strcmp(rf->rf_group, (const char *)group); } /* }}} int compare_read_func_group */ -int plugin_unregister_read_group(const char *group) /* {{{ */ +EXPORT int plugin_unregister_read_group(const char *group) /* {{{ */ { llentry_t *le; read_func_t *rf; @@ -1487,11 +1489,11 @@ int plugin_unregister_read_group(const char *group) /* {{{ */ return 0; } /* }}} int plugin_unregister_read_group */ -int plugin_unregister_write(const char *name) { +EXPORT int plugin_unregister_write(const char *name) { return plugin_unregister(list_write, name); } -int plugin_unregister_flush(const char *name) { +EXPORT int plugin_unregister_flush(const char *name) { plugin_ctx_t ctx = plugin_get_ctx(); if (ctx.flush_interval != 0) { @@ -1507,15 +1509,15 @@ int plugin_unregister_flush(const char *name) { return plugin_unregister(list_flush, name); } -int plugin_unregister_missing(const char *name) { +EXPORT int plugin_unregister_missing(const char *name) { return plugin_unregister(list_missing, name); } -int plugin_unregister_shutdown(const char *name) { +EXPORT int plugin_unregister_shutdown(const char *name) { return plugin_unregister(list_shutdown, name); } -int plugin_unregister_data_set(const char *name) { +EXPORT int plugin_unregister_data_set(const char *name) { data_set_t *ds; if (data_sets == NULL) @@ -1530,15 +1532,15 @@ int plugin_unregister_data_set(const char *name) { return 0; } /* int plugin_unregister_data_set */ -int plugin_unregister_log(const char *name) { +EXPORT int plugin_unregister_log(const char *name) { return plugin_unregister(list_log, name); } -int plugin_unregister_notification(const char *name) { +EXPORT int plugin_unregister_notification(const char *name) { return plugin_unregister(list_notification, name); } -int plugin_init_all(void) { +EXPORT int plugin_init_all(void) { char const *chain_name; llentry_t *le; int status; @@ -1637,14 +1639,14 @@ int plugin_init_all(void) { } /* void plugin_init_all */ /* TODO: Rename this function. */ -void plugin_read_all(void) { +EXPORT void plugin_read_all(void) { uc_check_timeout(); return; } /* void plugin_read_all */ /* Read function called when the `-T' command line argument is given. */ -int plugin_read_all_once(void) { +EXPORT int plugin_read_all_once(void) { int status; int return_status = 0; @@ -1689,8 +1691,8 @@ int plugin_read_all_once(void) { return return_status; } /* int plugin_read_all_once */ -int plugin_write(const char *plugin, /* {{{ */ - const data_set_t *ds, const value_list_t *vl) { +EXPORT int plugin_write(const char *plugin, /* {{{ */ + const data_set_t *ds, const value_list_t *vl) { llentry_t *le; int status; @@ -1769,7 +1771,8 @@ int plugin_write(const char *plugin, /* {{{ */ return status; } /* }}} int plugin_write */ -int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) { +EXPORT int plugin_flush(const char *plugin, cdtime_t timeout, + const char *identifier) { llentry_t *le; if (list_flush == NULL) @@ -1799,7 +1802,7 @@ int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) { return 0; } /* int plugin_flush */ -int plugin_shutdown_all(void) { +EXPORT int plugin_shutdown_all(void) { llentry_t *le; int ret = 0; // Assume success. @@ -1865,7 +1868,7 @@ int plugin_shutdown_all(void) { return ret; } /* void plugin_shutdown_all */ -int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */ +EXPORT int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */ { if (list_missing == NULL) return 0; @@ -2071,9 +2074,8 @@ static bool check_drop_value(void) /* {{{ */ return false; } /* }}} bool check_drop_value */ -int plugin_dispatch_values(value_list_t const *vl) { +EXPORT int plugin_dispatch_values(value_list_t const *vl) { int status; - static pthread_mutex_t statistics_lock = PTHREAD_MUTEX_INITIALIZER; if (check_drop_value()) { if (record_statistics) { @@ -2103,6 +2105,15 @@ plugin_dispatch_multivalue(value_list_t const *template, /* {{{ */ gauge_t sum = 0.0; va_list ap; + if (check_drop_value()) { + if (record_statistics) { + pthread_mutex_lock(&statistics_lock); + stats_values_dropped++; + pthread_mutex_unlock(&statistics_lock); + } + return 0; + } + assert(template->values_len == 1); /* Calculate sum for Gauge to calculate percent if needed */ @@ -2170,7 +2181,7 @@ plugin_dispatch_multivalue(value_list_t const *template, /* {{{ */ return failed; } /* }}} int plugin_dispatch_multivalue */ -int plugin_dispatch_notification(const notification_t *notif) { +EXPORT int plugin_dispatch_notification(const notification_t *notif) { llentry_t *le; /* Possible TODO: Add flap detection here */ @@ -2207,7 +2218,7 @@ int plugin_dispatch_notification(const notification_t *notif) { return 0; } /* int plugin_dispatch_notification */ -void plugin_log(int level, const char *format, ...) { +EXPORT void plugin_log(int level, const char *format, ...) { char msg[1024]; va_list ap; llentry_t *le; @@ -2280,7 +2291,7 @@ int parse_log_severity(const char *severity) { return log_level; } /* int parse_log_severity */ -int parse_notif_severity(const char *severity) { +EXPORT int parse_notif_severity(const char *severity) { int notif_severity = -1; if (strcasecmp(severity, "FAILURE") == 0) @@ -2294,11 +2305,11 @@ int parse_notif_severity(const char *severity) { return notif_severity; } /* int parse_notif_severity */ -const data_set_t *plugin_get_ds(const char *name) { +EXPORT const data_set_t *plugin_get_ds(const char *name) { data_set_t *ds; if (data_sets == NULL) { - ERROR("plugin_get_ds: No data sets are defined yet."); + P_ERROR("plugin_get_ds: No data sets are defined yet."); return NULL; } @@ -2481,12 +2492,12 @@ static plugin_ctx_t *plugin_ctx_create(void) { return ctx; } /* int plugin_ctx_create */ -void plugin_init_ctx(void) { +EXPORT void plugin_init_ctx(void) { pthread_key_create(&plugin_ctx_key, plugin_ctx_destructor); plugin_ctx_key_initialized = true; } /* void plugin_init_ctx */ -plugin_ctx_t plugin_get_ctx(void) { +EXPORT plugin_ctx_t plugin_get_ctx(void) { plugin_ctx_t *ctx; assert(plugin_ctx_key_initialized); @@ -2502,7 +2513,7 @@ plugin_ctx_t plugin_get_ctx(void) { return *ctx; } /* plugin_ctx_t plugin_get_ctx */ -plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) { +EXPORT plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) { plugin_ctx_t *c; plugin_ctx_t old; @@ -2522,13 +2533,15 @@ plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) { return old; } /* void plugin_set_ctx */ -cdtime_t plugin_get_interval(void) { +EXPORT cdtime_t plugin_get_interval(void) { cdtime_t interval; interval = plugin_get_ctx().interval; if (interval > 0) return interval; + P_ERROR("plugin_get_interval: Unable to determine Interval from context."); + return cf_get_default_interval(); } /* cdtime_t plugin_get_interval */