diff options
Diffstat (limited to 'collectors/idlejitter.plugin')
-rw-r--r-- | collectors/idlejitter.plugin/Makefile.am | 8 | ||||
-rw-r--r-- | collectors/idlejitter.plugin/README.md | 20 | ||||
-rw-r--r-- | collectors/idlejitter.plugin/plugin_idlejitter.c | 92 | ||||
-rw-r--r-- | collectors/idlejitter.plugin/plugin_idlejitter.h | 21 |
4 files changed, 141 insertions, 0 deletions
diff --git a/collectors/idlejitter.plugin/Makefile.am b/collectors/idlejitter.plugin/Makefile.am new file mode 100644 index 0000000..161784b --- /dev/null +++ b/collectors/idlejitter.plugin/Makefile.am @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +AUTOMAKE_OPTIONS = subdir-objects +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +dist_noinst_DATA = \ + README.md \ + $(NULL) diff --git a/collectors/idlejitter.plugin/README.md b/collectors/idlejitter.plugin/README.md new file mode 100644 index 0000000..3703e2e --- /dev/null +++ b/collectors/idlejitter.plugin/README.md @@ -0,0 +1,20 @@ +<!-- +title: "idlejitter.plugin" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/idlejitter.plugin/README.md +--> + +# idlejitter.plugin + +It works like this: + +A thread is spawned that requests to sleep for 20000 microseconds (20ms). +When the system wakes it up, it measures how many microseconds have passed. +The difference between the requested and the actual duration of the sleep, is the idle jitter. +This is done at most 50 times per second, to ensure we have a good average. + +This number is useful: + +1. in real-time environments, when the CPU jitter can affect the quality of the service (like VoIP media gateways). +2. in cloud infrastructure, at can pause the VM or container for a small duration to perform operations at the host. + +[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fidlejitter.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/idlejitter.plugin/plugin_idlejitter.c b/collectors/idlejitter.plugin/plugin_idlejitter.c new file mode 100644 index 0000000..c59541e --- /dev/null +++ b/collectors/idlejitter.plugin/plugin_idlejitter.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "plugin_idlejitter.h" + +#define CPU_IDLEJITTER_SLEEP_TIME_MS 20 + +static void cpuidlejitter_main_cleanup(void *ptr) { + struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; + static_thread->enabled = NETDATA_MAIN_THREAD_EXITING; + + info("cleaning up..."); + + static_thread->enabled = NETDATA_MAIN_THREAD_EXITED; +} + +void *cpuidlejitter_main(void *ptr) { + netdata_thread_cleanup_push(cpuidlejitter_main_cleanup, ptr); + + usec_t sleep_ut = config_get_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS) * USEC_PER_MS; + if(sleep_ut <= 0) { + config_set_number("plugin:idlejitter", "loop time in ms", CPU_IDLEJITTER_SLEEP_TIME_MS); + sleep_ut = CPU_IDLEJITTER_SLEEP_TIME_MS * USEC_PER_MS; + } + + RRDSET *st = rrdset_create_localhost( + "system" + , "idlejitter" + , NULL + , "idlejitter" + , NULL + , "CPU Idle Jitter" + , "microseconds lost/s" + , "idlejitter.plugin" + , NULL + , NETDATA_CHART_PRIO_SYSTEM_IDLEJITTER + , localhost->rrd_update_every + , RRDSET_TYPE_AREA + ); + RRDDIM *rd_min = rrddim_add(st, "min", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); + RRDDIM *rd_max = rrddim_add(st, "max", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); + RRDDIM *rd_avg = rrddim_add(st, "average", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); + + usec_t update_every_ut = localhost->rrd_update_every * USEC_PER_SEC; + struct timeval before, after; + unsigned long long counter; + + for(counter = 0; 1 ;counter++) { + int iterations = 0; + usec_t error_total = 0, + error_min = 0, + error_max = 0, + elapsed = 0; + + if(netdata_exit) break; + + while(elapsed < update_every_ut) { + now_monotonic_high_precision_timeval(&before); + sleep_usec(sleep_ut); + now_monotonic_high_precision_timeval(&after); + + usec_t dt = dt_usec(&after, &before); + elapsed += dt; + + usec_t error = dt - sleep_ut; + error_total += error; + + if(unlikely(!iterations)) + error_min = error; + else if(error < error_min) + error_min = error; + + if(error > error_max) + error_max = error; + + iterations++; + } + + if(netdata_exit) break; + + if(iterations) { + if (likely(counter)) rrdset_next(st); + rrddim_set_by_pointer(st, rd_min, error_min); + rrddim_set_by_pointer(st, rd_max, error_max); + rrddim_set_by_pointer(st, rd_avg, error_total / iterations); + rrdset_done(st); + } + } + + netdata_thread_cleanup_pop(1); + return NULL; +} + diff --git a/collectors/idlejitter.plugin/plugin_idlejitter.h b/collectors/idlejitter.plugin/plugin_idlejitter.h new file mode 100644 index 0000000..62fabea --- /dev/null +++ b/collectors/idlejitter.plugin/plugin_idlejitter.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef NETDATA_PLUGIN_IDLEJITTER_H +#define NETDATA_PLUGIN_IDLEJITTER_H 1 + +#include "../../daemon/common.h" + +#define NETDATA_PLUGIN_HOOK_IDLEJITTER \ + { \ + .name = "PLUGIN[idlejitter]", \ + .config_section = CONFIG_SECTION_PLUGINS, \ + .config_name = "idlejitter", \ + .enabled = 1, \ + .thread = NULL, \ + .init_routine = NULL, \ + .start_routine = cpuidlejitter_main \ + }, + +extern void *cpuidlejitter_main(void *ptr); + +#endif /* NETDATA_PLUGIN_IDLEJITTER_H */ |