X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fplugin.c;h=c69046c3fab5f2e4192814994fafb6a15d6bd781;hb=6d85a198dd90fb5af963ad847d9dbff7b8025c46;hp=002955d5164f96fb66096d0d1224350fd83c4399;hpb=d5ba2cb628f0c5c3e5c3eef1c62aacc23f3d8aef;p=collectd.git diff --git a/src/plugin.c b/src/plugin.c index 002955d5..c69046c3 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -359,28 +359,28 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) int rf_type; int rc; - /* Get the read function that needs to be read next. */ + /* Get the read function that needs to be read next. + * We don't need to hold "read_lock" for the heap, but we need + * to call c_heap_get_root() and pthread_cond_wait() in the + * same protected block. */ + pthread_mutex_lock (&read_lock); rf = c_heap_get_root (read_heap); if (rf == NULL) { - struct timespec abstime; - - now = cdtime (); - - CDTIME_T_TO_TIMESPEC (now + interval_g, &abstime); - - pthread_mutex_lock (&read_lock); - pthread_cond_timedwait (&read_cond, &read_lock, - &abstime); - pthread_mutex_unlock (&read_lock); + pthread_cond_wait (&read_cond, &read_lock); + pthread_mutex_unlock (&read_lock); continue; } + pthread_mutex_unlock (&read_lock); if ((rf->rf_interval.tv_sec == 0) && (rf->rf_interval.tv_nsec == 0)) { + /* this should not happen, because the interval is set + * for each plugin when loading it + * XXX: issue a warning? */ now = cdtime (); - CDTIME_T_TO_TIMESPEC (interval_g, &rf->rf_interval); + CDTIME_T_TO_TIMESPEC (plugin_get_interval (), &rf->rf_interval); rf->rf_effective_interval = rf->rf_interval; @@ -781,6 +781,8 @@ static int plugin_insert_read (read_func_t *rf) /* This does not fail. */ llist_append (read_list, le); + /* Wake up all the read threads. */ + pthread_cond_broadcast (&read_cond); pthread_mutex_unlock (&read_lock); return (0); } /* int plugin_insert_read */ @@ -804,16 +806,13 @@ int plugin_register_read (const char *name, int status; if (ctx.interval != 0) { - /* If ctx.interval is not zero (== use interval_g), we need to - * use the "complex" read callback, because only that allows to - * specify a different interval. Wrap the callback using - * read_cb_wrapper(). */ + /* If ctx.interval is not zero (== use the plugin or global + * interval), we need to use the "complex" read callback, + * because only that allows to specify a different interval. + * Wrap the callback using read_cb_wrapper(). */ struct timespec interval; user_data_t user_data; - DEBUG ("plugin_register_read: plugin_interval = %.3f", - CDTIME_T_TO_DOUBLE(plugin_interval)); - user_data.data = callback; user_data.free_func = NULL; @@ -822,6 +821,9 @@ int plugin_register_read (const char *name, name, read_cb_wrapper, &interval, &user_data); } + DEBUG ("plugin_register_read: default_interval = %.3f", + CDTIME_T_TO_DOUBLE(plugin_get_interval ())); + rf = malloc (sizeof (*rf)); if (rf == NULL) { @@ -882,6 +884,10 @@ int plugin_register_complex_read (const char *group, const char *name, } rf->rf_effective_interval = rf->rf_interval; + DEBUG ("plugin_register_read: interval = %i.%09i", + (int) rf->rf_interval.tv_sec, + (int) rf->rf_interval.tv_nsec); + /* Set user data */ if (user_data == NULL) { @@ -1301,7 +1307,9 @@ int plugin_write (const char *plugin, /* {{{ */ { callback_func_t *cf = le->value; plugin_write_cb callback; - plugin_ctx_t old_ctx = plugin_set_ctx (cf->cf_ctx); + + /* do not switch plugin context; rather keep the context (interval) + * information of the calling read plugin */ DEBUG ("plugin: plugin_write: Writing values via %s.", le->key); callback = cf->cf_callback; @@ -1311,8 +1319,6 @@ int plugin_write (const char *plugin, /* {{{ */ else success++; - plugin_set_ctx (old_ctx); - le = le->next; } @@ -1325,7 +1331,6 @@ int plugin_write (const char *plugin, /* {{{ */ { callback_func_t *cf; plugin_write_cb callback; - plugin_ctx_t old_ctx; le = llist_head (list_write); while (le != NULL) @@ -1341,13 +1346,12 @@ int plugin_write (const char *plugin, /* {{{ */ cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); + /* do not switch plugin context; rather keep the context (interval) + * information of the calling read plugin */ DEBUG ("plugin: plugin_write: Writing values via %s.", le->key); callback = cf->cf_callback; status = (*callback) (ds, vl, &cf->cf_udata); - - plugin_set_ctx (old_ctx); } return (status); @@ -1540,13 +1544,25 @@ int plugin_dispatch_values (value_list_t *vl) if (vl->time == 0) vl->time = cdtime (); - if (vl->interval <= 0) { + 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_dispatch_values: 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 = interval_g; + } } DEBUG ("plugin_dispatch_values: time = %.3f; interval = %.3f; " @@ -1735,14 +1751,14 @@ int plugin_dispatch_notification (const notification_t *notif) { callback_func_t *cf; plugin_notification_cb callback; - plugin_ctx_t old_ctx; int status; + /* do not switch plugin context; rather keep the context + * (interval) information of the calling plugin */ + cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); callback = cf->cf_callback; status = (*callback) (notif, &cf->cf_udata); - plugin_set_ctx (old_ctx); if (status != 0) { WARNING ("plugin_dispatch_notification: Notification " @@ -1783,19 +1799,57 @@ void plugin_log (int level, const char *format, ...) { callback_func_t *cf; plugin_log_cb callback; - plugin_ctx_t old_ctx; cf = le->value; - old_ctx = plugin_set_ctx (cf->cf_ctx); callback = cf->cf_callback; + /* do not switch plugin context; rather keep the context + * (interval) information of the calling plugin */ + (*callback) (level, msg, &cf->cf_udata); - plugin_set_ctx (old_ctx); le = le->next; } } /* void plugin_log */ +int parse_log_severity (const char *severity) +{ + int log_level = -1; + + if ((0 == strcasecmp (severity, "emerg")) + || (0 == strcasecmp (severity, "alert")) + || (0 == strcasecmp (severity, "crit")) + || (0 == strcasecmp (severity, "err"))) + log_level = LOG_ERR; + else if (0 == strcasecmp (severity, "warning")) + log_level = LOG_WARNING; + else if (0 == strcasecmp (severity, "notice")) + log_level = LOG_NOTICE; + else if (0 == strcasecmp (severity, "info")) + log_level = LOG_INFO; +#if COLLECT_DEBUG + else if (0 == strcasecmp (severity, "debug")) + log_level = LOG_DEBUG; +#endif /* COLLECT_DEBUG */ + + return (log_level); +} /* int parse_log_severity */ + +int parse_notif_severity (const char *severity) +{ + int notif_severity = -1; + + if (strcasecmp (severity, "FAILURE") == 0) + notif_severity = NOTIF_FAILURE; + else if (strcmp (severity, "OKAY") == 0) + notif_severity = NOTIF_OKAY; + else if ((strcmp (severity, "WARNING") == 0) + || (strcmp (severity, "WARN") == 0)) + notif_severity = NOTIF_WARNING; + + return (notif_severity); +} /* int parse_notif_severity */ + const data_set_t *plugin_get_ds (const char *name) { data_set_t *ds; @@ -2058,25 +2112,11 @@ cdtime_t plugin_get_interval (void) { cdtime_t interval; - const char *interval_str; - double interval_dbl; - interval = plugin_get_ctx().interval; if (interval > 0) return interval; - /* this should happen during initialization only */ - interval_str = global_option_get ("Interval"); - if (interval_str != NULL) - { - interval_dbl = atof (interval_str); - if (interval_dbl > 0.0) - interval = DOUBLE_TO_CDTIME_T (interval_dbl); - } - - if (interval > 0) - return interval; - return TIME_T_TO_CDTIME_T (10); + return cf_get_default_interval (); } /* cdtime_t plugin_get_interval */ typedef struct {