summaryrefslogtreecommitdiffstats
path: root/collectors/plugins.d
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/plugins.d')
-rw-r--r--collectors/plugins.d/README.md16
-rw-r--r--collectors/plugins.d/plugins_d.c7
-rw-r--r--collectors/plugins.d/pluginsd_parser.c99
3 files changed, 69 insertions, 53 deletions
diff --git a/collectors/plugins.d/README.md b/collectors/plugins.d/README.md
index ac838d21d..c84384215 100644
--- a/collectors/plugins.d/README.md
+++ b/collectors/plugins.d/README.md
@@ -21,7 +21,6 @@ from external processes, thus allowing Netdata to use **external plugins**.
|[nfacct.plugin](/collectors/nfacct.plugin/README.md)|`C`|linux|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`.|
|[xenstat.plugin](/collectors/xenstat.plugin/README.md)|`C`|linux|collects XenServer and XCP-ng metrics using `lxenstat`.|
|[perf.plugin](/collectors/perf.plugin/README.md)|`C`|linux|collects CPU performance metrics using performance monitoring units (PMU).|
-|[node.d.plugin](/collectors/node.d.plugin/README.md)|`node.js`|all|a **plugin orchestrator** for data collection modules written in `node.js`.|
|[python.d.plugin](/collectors/python.d.plugin/README.md)|`python`|all|a **plugin orchestrator** for data collection modules written in `python` v2 or v3 (both are supported).|
|[slabinfo.plugin](/collectors/slabinfo.plugin/README.md)|`C`|linux|collects kernel internal cache objects (SLAB) metrics.|
@@ -74,7 +73,6 @@ Example:
# charts.d = yes
# fping = yes
# ioping = yes
- # node.d = yes
# python.d = yes
```
@@ -187,7 +185,10 @@ the template is:
- `name`
- is the name that will be presented to the user instead of `id` in `type.id`. This means that only the `id` part of `type.id` is changed. When a name has been given, the chart is index (and can be referred) as both `type.id` and `type.name`. You can set name to `''`, or `null`, or `(null)` to disable it.
+ is the name that will be presented to the user instead of `id` in `type.id`. This means that only the `id` part of
+ `type.id` is changed. When a name has been given, the chart is indexed (and can be referred) as both `type.id` and
+ `type.name`. You can set name to `''`, or `null`, or `(null)` to disable it. If a chart with the same name already
+ exists, a serial number is automatically attached to the name to avoid naming collisions.
- `title`
@@ -388,17 +389,12 @@ or do not output the line at all.
python is ideal for Netdata plugins. It is a simple, yet powerful way to collect data, it has a very small memory footprint, although it is not the most CPU efficient way to do it.
-2. **node.js**, use `node.d.plugin`, there are a few examples in the [node.d
- directory](/collectors/node.d.plugin/README.md)
-
- node.js is the fastest scripting language for collecting data. If your plugin needs to do a lot of work, compute values, etc, node.js is probably the best choice before moving to compiled code. Keep in mind though that node.js is not memory efficient; it will probably need more RAM compared to python.
-
-3. **BASH**, use `charts.d.plugin`, there are many examples in the [charts.d
+2. **BASH**, use `charts.d.plugin`, there are many examples in the [charts.d
directory](/collectors/charts.d.plugin/README.md)
BASH is the simplest scripting language for collecting values. It is the less efficient though in terms of CPU resources. You can use it to collect data quickly, but extensive use of it might use a lot of system resources.
-4. **C**
+3. **C**
Of course, C is the most efficient way of collecting data. This is why Netdata itself is written in C.
diff --git a/collectors/plugins.d/plugins_d.c b/collectors/plugins.d/plugins_d.c
index 614e43d58..2916f1c13 100644
--- a/collectors/plugins.d/plugins_d.c
+++ b/collectors/plugins.d/plugins_d.c
@@ -127,7 +127,7 @@ inline int pluginsd_initialize_plugin_directories()
// Get the configuration entry
if (likely(!plugins_dir_list)) {
snprintfz(plugins_dirs, FILENAME_MAX * 2, "\"%s\" \"%s/custom-plugins.d\"", PLUGINS_DIR, CONFIG_DIR);
- plugins_dir_list = strdupz(config_get(CONFIG_SECTION_GLOBAL, "plugins directory", plugins_dirs));
+ plugins_dir_list = strdupz(config_get(CONFIG_SECTION_DIRECTORIES, "plugins", plugins_dirs));
}
// Parse it and store it to plugin directories
@@ -230,6 +230,8 @@ static void pluginsd_worker_thread_handle_error(struct plugind *cd, int worker_r
void *pluginsd_worker_thread(void *arg)
{
+ worker_register("PLUGINSD");
+
netdata_thread_cleanup_push(pluginsd_worker_thread_cleanup, arg);
struct plugind *cd = (struct plugind *)arg;
@@ -260,6 +262,7 @@ void *pluginsd_worker_thread(void *arg)
if (unlikely(!cd->enabled))
break;
}
+ worker_unregister();
netdata_thread_cleanup_pop(1);
return NULL;
@@ -281,6 +284,8 @@ static void pluginsd_main_cleanup(void *data)
info("cleanup completed.");
static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
+
+ worker_unregister();
}
void *pluginsd_main(void *ptr)
diff --git a/collectors/plugins.d/pluginsd_parser.c b/collectors/plugins.d/pluginsd_parser.c
index 22b77362f..f014a29d0 100644
--- a/collectors/plugins.d/pluginsd_parser.c
+++ b/collectors/plugins.d/pluginsd_parser.c
@@ -125,26 +125,36 @@ PARSER_RC pluginsd_dimension_action(void *user, RRDSET *st, char *id, char *name
UNUSED(algorithm);
RRDDIM *rd = rrddim_add(st, id, name, multiplier, divisor, algorithm_type);
- rrddim_flag_clear(rd, RRDDIM_FLAG_HIDDEN);
+ int unhide_dimension = 1;
+
rrddim_flag_clear(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS);
if (options && *options) {
if (strstr(options, "obsolete") != NULL)
rrddim_is_obsolete(st, rd);
else
rrddim_isnot_obsolete(st, rd);
- if (strstr(options, "hidden") != NULL) {
- rrddim_flag_set(rd, RRDDIM_FLAG_HIDDEN);
- (void) sql_set_dimension_option(&rd->state->metric_uuid, "hidden");
- }
- else
- (void) sql_set_dimension_option(&rd->state->metric_uuid, NULL);
+
+ unhide_dimension = !strstr(options, "hidden");
+
if (strstr(options, "noreset") != NULL)
rrddim_flag_set(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS);
if (strstr(options, "nooverflow") != NULL)
rrddim_flag_set(rd, RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS);
- } else {
- (void) sql_set_dimension_option(&rd->state->metric_uuid, NULL);
+ } else
rrddim_isnot_obsolete(st, rd);
+
+ if (likely(unhide_dimension)) {
+ rrddim_flag_clear(rd, RRDDIM_FLAG_HIDDEN);
+ if (rrddim_flag_check(rd, RRDDIM_FLAG_META_HIDDEN)) {
+ (void)sql_set_dimension_option(&rd->state->metric_uuid, NULL);
+ rrddim_flag_clear(rd, RRDDIM_FLAG_META_HIDDEN);
+ }
+ } else {
+ rrddim_flag_set(rd, RRDDIM_FLAG_HIDDEN);
+ if (!rrddim_flag_check(rd, RRDDIM_FLAG_META_HIDDEN)) {
+ (void)sql_set_dimension_option(&rd->state->metric_uuid, "hidden");
+ rrddim_flag_set(rd, RRDDIM_FLAG_META_HIDDEN);
+ }
}
return PARSER_RC_OK;
}
@@ -725,6 +735,11 @@ PARSER_RC metalog_pluginsd_host(char **words, void *user, PLUGINSD_ACTION *plug
return PARSER_RC_OK;
}
+static void pluginsd_process_thread_cleanup(void *ptr) {
+ PARSER *parser = (PARSER *)ptr;
+ parser_destroy(parser);
+}
+
// New plugins.d parser
inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int trust_durations)
@@ -743,50 +758,50 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
}
clearerr(fp);
- PARSER_USER_OBJECT *user = callocz(1, sizeof(*user));
- ((PARSER_USER_OBJECT *) user)->enabled = cd->enabled;
- ((PARSER_USER_OBJECT *) user)->host = host;
- ((PARSER_USER_OBJECT *) user)->cd = cd;
- ((PARSER_USER_OBJECT *) user)->trust_durations = trust_durations;
-
- PARSER *parser = parser_init(host, user, fp, PARSER_INPUT_SPLIT);
-
- if (unlikely(!parser)) {
- error("Failed to initialize parser");
- cd->serial_failures++;
- return 0;
- }
-
- parser->plugins_action->begin_action = &pluginsd_begin_action;
- parser->plugins_action->flush_action = &pluginsd_flush_action;
- parser->plugins_action->end_action = &pluginsd_end_action;
- parser->plugins_action->disable_action = &pluginsd_disable_action;
- parser->plugins_action->variable_action = &pluginsd_variable_action;
- parser->plugins_action->dimension_action = &pluginsd_dimension_action;
- parser->plugins_action->label_action = &pluginsd_label_action;
- parser->plugins_action->overwrite_action = &pluginsd_overwrite_action;
- parser->plugins_action->chart_action = &pluginsd_chart_action;
- parser->plugins_action->set_action = &pluginsd_set_action;
-
- user->parser = parser;
+ PARSER_USER_OBJECT user = {
+ .enabled = cd->enabled,
+ .host = host,
+ .cd = cd,
+ .trust_durations = trust_durations
+ };
+
+ PARSER *parser = parser_init(host, &user, fp, PARSER_INPUT_SPLIT);
+
+ // this keeps the parser with its current value
+ // so, parser needs to be allocated before pushing it
+ netdata_thread_cleanup_push(pluginsd_process_thread_cleanup, parser);
+
+ parser->plugins_action->begin_action = &pluginsd_begin_action;
+ parser->plugins_action->flush_action = &pluginsd_flush_action;
+ parser->plugins_action->end_action = &pluginsd_end_action;
+ parser->plugins_action->disable_action = &pluginsd_disable_action;
+ parser->plugins_action->variable_action = &pluginsd_variable_action;
+ parser->plugins_action->dimension_action = &pluginsd_dimension_action;
+ parser->plugins_action->label_action = &pluginsd_label_action;
+ parser->plugins_action->overwrite_action = &pluginsd_overwrite_action;
+ parser->plugins_action->chart_action = &pluginsd_chart_action;
+ parser->plugins_action->set_action = &pluginsd_set_action;
+ parser->plugins_action->clabel_commit_action = &pluginsd_clabel_commit_action;
+ parser->plugins_action->clabel_action = &pluginsd_clabel_action;
+
+ user.parser = parser;
while (likely(!parser_next(parser))) {
if (unlikely(netdata_exit || parser_action(parser, NULL)))
break;
}
- info("PARSER ended");
-
- parser_destroy(parser);
- cd->enabled = ((PARSER_USER_OBJECT *) user)->enabled;
- size_t count = ((PARSER_USER_OBJECT *) user)->count;
+ // free parser with the pop function
+ netdata_thread_cleanup_pop(1);
- freez(user);
+ cd->enabled = user.enabled;
+ size_t count = user.count;
if (likely(count)) {
cd->successful_collections += count;
cd->serial_failures = 0;
- } else
+ }
+ else
cd->serial_failures++;
return count;