summaryrefslogtreecommitdiffstats
path: root/python.d
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@tsaousis.gr>2017-09-04 23:30:41 +0300
committerGitHub <noreply@github.com>2017-09-04 23:30:41 +0300
commitaebbd49643735a0ba9456cf248aa80ad5fb86433 (patch)
treed772522397c16d147ed1068d2bf6b2a11e5d2382 /python.d
parent751722ac0814e84747702a1cf1a8777737368bde (diff)
parentc6f0748f2b238474d7f7b69110a5df96c9ad2f5a (diff)
Merge pull request #2639 from domschl/chrony
Statistics for precision of time data of local chrony
Diffstat (limited to 'python.d')
-rw-r--r--python.d/Makefile.am1
-rw-r--r--python.d/README.md32
-rw-r--r--python.d/chrony.chart.py108
3 files changed, 141 insertions, 0 deletions
diff --git a/python.d/Makefile.am b/python.d/Makefile.am
index 6a43e94c13..84c2aeadd0 100644
--- a/python.d/Makefile.am
+++ b/python.d/Makefile.am
@@ -16,6 +16,7 @@ dist_python_DATA = \
apache.chart.py \
apache_cache.chart.py \
bind_rndc.chart.py \
+ chrony.chart.py \
cpufreq.chart.py \
cpuidle.chart.py \
dns_query_time.chart.py \
diff --git a/python.d/README.md b/python.d/README.md
index c4504a7c59..1b04ccdf3d 100644
--- a/python.d/README.md
+++ b/python.d/README.md
@@ -186,6 +186,38 @@ If no configuration is given, module will attempt to read named.stats file at `
---
+# chrony
+
+This module monitors the precision and statistics of a local chronyd server.
+
+It produces:
+
+* frequency
+* last offset
+* RMS offset
+* residual freq
+* root delay
+* root dispersion
+* skew
+* system time
+
+**Requirements:**
+Verify that user netdata can execute `chronyc tracking`. If necessary, update `/etc/chrony.conf`, `cmdallow`.
+
+### Configuration
+
+Sample:
+```yaml
+# data collection frequency:
+update_every: 1
+
+# chrony query command:
+local:
+ command: 'chronyc -n tracking'
+```
+
+---
+
# cpufreq
This module shows the current CPU frequency as set by the cpufreq kernel
diff --git a/python.d/chrony.chart.py b/python.d/chrony.chart.py
new file mode 100644
index 0000000000..580a2e6760
--- /dev/null
+++ b/python.d/chrony.chart.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# Description: chrony netdata python.d module
+# Author: Dominik Schloesser (domschl)
+
+from base import ExecutableService
+
+# default module values (can be overridden per job in `config`)
+# update_every = 10
+priority = 60000
+retries = 10
+
+# charts order (can be overridden if you want less charts, or different order)
+ORDER = ['timediff', 'lastoffset', 'rmsoffset', 'rootdelay',
+ 'rootdispersion', 'skew', 'frequency', 'residualfreq']
+
+CHARTS = {
+ # id: {
+ # 'options': [name, title, units, family, context, charttype],
+ # 'lines': [
+ # [unique_dimension_name, name, algorithm, multiplier, divisor]
+ # ]}
+ 'timediff': {
+ 'options': [None, "Difference system time to NTP", "us", 'chrony', 'chrony.timediff', 'line'],
+ 'lines': [
+ ['timediff', None, 'absolute', 1, 1000]
+ ]},
+ 'lastoffset': {
+ 'options': [None, "Last offset", "us", 'chrony', 'chrony.lastoffset', 'line'],
+ 'lines': [
+ ['lastoffset', None, 'absolute', 1, 1000]
+ ]},
+ 'rmsoffset': {
+ 'options': [None, "RMS offset", "us", 'chrony', 'chrony.rmsoffset', 'line'],
+ 'lines': [
+ ['rmsoffset', None, 'absolute', 1, 1000]
+ ]},
+ 'rootdelay': {
+ 'options': [None, "Root delay", "us", 'chrony', 'chrony.rootdelay', 'line'],
+ 'lines': [
+ ['rootdelay', None, 'absolute', 1, 1000]
+ ]},
+ 'rootdispersion': {
+ 'options': [None, "Root dispersion", "us", 'chrony', 'chrony.rootdispersion', 'line'],
+ 'lines': [
+ ['rootdispersion', None, 'absolute', 1, 1000]
+ ]},
+ 'skew': {
+ 'options': [None, "Skew, error bound on frequency", "ppm", 'chrony', 'chrony.skew', 'line'],
+ 'lines': [
+ ['skew', None, 'absolute', 1, 1000]
+ ]},
+ 'frequency': {
+ 'options': [None, "Frequency", "ppm", 'chrony', 'chrony.frequency', 'line'],
+ 'lines': [
+ ['frequency', None, 'absolute', 1, 1000]
+ ]},
+ 'residualfreq': {
+ 'options': [None, "Residual frequency", "ppm", 'chrony', 'chrony.residualfreq', 'line'],
+ 'lines': [
+ ['residualfreq', None, 'absolute', 1, 1000]
+ ]}
+}
+
+CHRONY = [('Frequency', 'frequency', 1e3),
+ ('Last offset', 'lastoffset', 1e9),
+ ('RMS offset', 'rmsoffset', 1e9),
+ ('Residual freq', 'residualfreq', 1e3),
+ ('Root delay', 'rootdelay', 1e9),
+ ('Root dispersion', 'rootdispersion', 1e9),
+ ('Skew', 'skew', 1e3),
+ ('System time', 'timediff', 1e9)]
+
+
+class Service(ExecutableService):
+ def __init__(self, configuration=None, name=None):
+ ExecutableService.__init__(
+ self, configuration=configuration, name=name)
+ self.command = "chronyc -n tracking"
+ self.order = ORDER
+ self.definitions = CHARTS
+
+ def _get_data(self):
+ """
+ Format data received from shell command
+ :return: dict
+ """
+ raw_data = self._get_raw_data()
+ if not raw_data:
+ return None
+
+ raw_data = (line.split(':', 1) for line in raw_data)
+ parsed, data = dict(), dict()
+
+ for line in raw_data:
+ try:
+ key, value = (l.strip() for l in line)
+ except ValueError:
+ continue
+ if value:
+ parsed[key] = value.split()[0]
+
+ for key, dim_id, multiplier in CHRONY:
+ try:
+ data[dim_id] = int(float(parsed[key]) * multiplier)
+ except (KeyError, ValueError):
+ continue
+
+ return data or None