@cryptotaxi247 / netdata-1 / commits / 3777b9173

Remove obsolete python modules (#5659)

##### Summary Fixes: #5647 ___ Remove obolete python modules: - cpuidle (moved to proc plugin #4635) - cpufreq (moved to proc plugin #4562) - mdstat (moved to proc plugin #4768) - linux_power_supply (moved to proc plugin #4960) ##### Component Name [/collectors/python.d.plugin/](https://github.com/netdata/netdata/tree/master/collectors/python.d.plugin) ##### Additional Information

Ilya Mashchenko committed Mar 19, 2019 at 13:39 UTC 3777b91736bfadb7c659ceb74e3c48c4054b8b27
20 files changed +6 -1041
README.md
+5 -5
@@ -186,7 +186,7 @@ The key improvements are:
186
187 - Improved internal database to support values above 64bit.
188 - New data collection plugins: [`openldap`](collectors/python.d.plugin/openldap/), [`tor`](collectors/python.d.plugin/tor/), [`nvidia_smi`](collectors/python.d.plugin/nvidia_smi/).
189 -- Improved data collection plugins: netdata now supports monitoring network interface aliases, [`smartd_log`](collectors/python.d.plugin/smartd_log/), [`cpufreq`](collectors/python.d.plugin/cpufreq/), [`sensors`](collectors/python.d.plugin/sensors/).
189 +- Improved data collection plugins: netdata now supports monitoring network interface aliases, [`smartd_log`](collectors/python.d.plugin/smartd_log/), [`cpufreq`](collectors/proc.plugin/README.md#cpu-frequency), [`sensors`](collectors/python.d.plugin/sensors/).
190 - Health monitoring improvements: network interface congestion alarm restored, [`alerta.io`](health/notifications/alerta/), `conntrack_max`.
191 - `my-netdata`menu has been refactored.
192 - Packaging: `openrc` service definition got a few improvements.
@@ -317,8 +317,8 @@ Its [Plugin API](collectors/plugins.d/) supports all programing languages (anyth
317 - **[SoftIRQs](collectors/proc.plugin/)** - total and per core SoftIRQs.
318 - **[SoftNet](collectors/proc.plugin/)** - total and per core SoftIRQs related to network activity.
319 - **[CPU Throttling](collectors/proc.plugin/)** - collects per core CPU throttling.
320 -- **[CPU Frequency](collectors/python.d.plugin/couchdb/)** - collects the current CPU frequency.
321 -- **[CPU Idle](collectors/python.d.plugin/cpuidle/)** - collects the time spent per processor state.
320 +- **[CPU Frequency](collectors/proc.plugin/)** - collects the current CPU frequency.
321 +- **[CPU Idle](collectors/proc.plugin/)** - collects the time spent per processor state.
322 - **[IdleJitter](collectors/idlejitter.plugin/)** - measures CPU latency.
323 - **[Entropy](collectors/proc.plugin/)** - random numbers pool, using in cryptography.
324 - **[Interprocess Communication - IPC](collectors/proc.plugin/)** - such as semaphores and semaphores arrays.
@@ -339,7 +339,7 @@ Its [Plugin API](collectors/plugins.d/) supports all programing languages (anyth
339 - **[block devices](collectors/proc.plugin/)** - per disk: I/O, operations, backlog, utilization, space, etc.
340 - **[BCACHE](collectors/proc.plugin/)** - detailed performance of SSD caching devices.
341 - **[DiskSpace](collectors/proc.plugin/)** - monitors disk space usage.
342 -- **[mdstat](collectors/python.d.plugin/mdstat/)** - software RAID.
342 +- **[mdstat](collectors/proc.plugin/)** - software RAID.
343 - **[hddtemp](collectors/python.d.plugin/hddtemp/)** - disk temperatures.
344 - **[smartd](collectors/python.d.plugin/smartd_log/)** - disk S.M.A.R.T. values.
345 - **[device mapper](collectors/proc.plugin/)** - naming disks.
@@ -448,7 +448,7 @@ Its [Plugin API](collectors/plugins.d/) supports all programing languages (anyth
448 #### UPSes
449 - **[apcupsd](collectors/charts.d.plugin/apcupsd/)** - load, charge, battery voltage, temperature, utility metrics, output metrics
450 - **[NUT](collectors/charts.d.plugin/nut/)** - load, charge, battery voltage, temperature, utility metrics, output metrics
451 -- **[Linux Power Supply](collectors/python.d.plugin/linux_power_supply/)** - collects metrics reported by power supply drivers on Linux.
451 +- **[Linux Power Supply](collectors/proc.plugin/)** - collects metrics reported by power supply drivers on Linux.
452
453 #### Social Sharing Servers
454 - **[RetroShare](collectors/python.d.plugin/retroshare/)** - connects to multiple retroshare servers (local or remote) to collect real-time performance metrics.
collectors/python.d.plugin/Makefile.am
-4
@@ -44,8 +44,6 @@ include boinc/Makefile.inc
44 include ceph/Makefile.inc
45 include chrony/Makefile.inc
46 include couchdb/Makefile.inc
47 -include cpufreq/Makefile.inc
48 -include cpuidle/Makefile.inc
47 include dnsdist/Makefile.inc
48 include dns_query_time/Makefile.inc
49 include dockerd/Makefile.inc
@@ -62,10 +60,8 @@ include httpcheck/Makefile.inc
60 include icecast/Makefile.inc
61 include ipfs/Makefile.inc
62 include isc_dhcpd/Makefile.inc
65 -include linux_power_supply/Makefile.inc
63 include litespeed/Makefile.inc
64 include logind/Makefile.inc
68 -include mdstat/Makefile.inc
65 include megacli/Makefile.inc
66 include memcached/Makefile.inc
67 include mongodb/Makefile.inc
collectors/python.d.plugin/cpufreq/Makefile.inc deleted
-13
@@ -1,13 +0,0 @@
1 -# SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -# THIS IS NOT A COMPLETE Makefile
4 -# IT IS INCLUDED BY ITS PARENT'S Makefile.am
5 -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT
6 -
7 -# install these files
8 -dist_python_DATA += cpufreq/cpufreq.chart.py
9 -dist_pythonconfig_DATA += cpufreq/cpufreq.conf
10 -
11 -# do not install these files, but include them in the distribution
12 -dist_noinst_DATA += cpufreq/README.md cpufreq/Makefile.inc
13 -
collectors/python.d.plugin/cpufreq/README.md deleted
-37
@@ -1,37 +0,0 @@
1 -# cpufreq
2 -
3 -> THIS MODULE IS OBSOLETE.
4 -> USE THE [PROC PLUGIN](../../proc.plugin) - IT IS MORE EFFICIENT
5 -
6 ----
7 -
8 -This module shows the current CPU frequency as set by the cpufreq kernel
9 -module.
10 -
11 -**Requirement:**
12 -You need to have `CONFIG_CPU_FREQ` and (optionally) `CONFIG_CPU_FREQ_STAT`
13 -enabled in your kernel.
14 -
15 -This module tries to read from one of two possible locations. On
16 -initialization, it tries to read the `time_in_state` files provided by
17 -cpufreq\_stats. If this file does not exist, or doesn't contain valid data, it
18 -falls back to using the more inaccurate `scaling_cur_freq` file (which only
19 -represents the **current** CPU frequency, and doesn't account for any state
20 -changes which happen between updates).
21 -
22 -It produces one chart with multiple lines (one line per core).
23 -
24 -### configuration
25 -
26 -Sample:
27 -
28 -```yaml
29 -sys_dir: "/sys/devices"
30 -```
31 -
32 -If no configuration is given, module will search for cpufreq files in `/sys/devices` directory.
33 -Directory is also prefixed with `NETDATA_HOST_PREFIX` if specified.
34 -
35 ----
36 -
37 -[![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%2Fpython.d.plugin%2Fcpufreq%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/python.d.plugin/cpufreq/cpufreq.chart.py deleted
-115
@@ -1,115 +0,0 @@
1 -# -*- coding: utf-8 -*-
2 -# Description: cpufreq netdata python.d module
3 -# Author: Pawel Krupa (paulfantom)
4 -# Author: Steven Noonan (tycho)
5 -# SPDX-License-Identifier: GPL-3.0-or-later
6 -
7 -import glob
8 -import os
9 -
10 -from bases.FrameworkServices.SimpleService import SimpleService
11 -
12 -# default module values (can be overridden per job in `config`)
13 -# update_every = 2
14 -
15 -ORDER = ['cpufreq']
16 -
17 -CHARTS = {
18 - 'cpufreq': {
19 - 'options': [None, 'CPU Clock', 'MHz', 'cpufreq', 'cpufreq.cpufreq', 'line'],
20 - 'lines': [
21 - # lines are created dynamically in `check()` method
22 - ]
23 - }
24 -}
25 -
26 -
27 -class Service(SimpleService):
28 - def __init__(self, configuration=None, name=None):
29 - prefix = os.getenv('NETDATA_HOST_PREFIX', "")
30 - if prefix.endswith('/'):
31 - prefix = prefix[:-1]
32 - self.sys_dir = prefix + "/sys/devices"
33 - SimpleService.__init__(self, configuration=configuration, name=name)
34 - self.order = ORDER
35 - self.definitions = CHARTS
36 - self.fake_name = 'cpu'
37 - self.assignment = {}
38 - self.accurate_exists = True
39 - self.accurate_last = {}
40 -
41 - def _get_data(self):
42 - data = {}
43 -
44 - if self.accurate_exists:
45 - accurate_ok = True
46 -
47 - for name, paths in self.assignment.items():
48 - last = self.accurate_last[name]
49 -
50 - current = {}
51 - deltas = {}
52 - ticks_since_last = 0
53 -
54 - for line in open(paths['accurate'], 'r'):
55 - line = list(map(int, line.split()))
56 - current[line[0]] = line[1]
57 - ticks = line[1] - last.get(line[0], 0)
58 - ticks_since_last += ticks
59 - deltas[line[0]] = line[1] - last.get(line[0], 0)
60 -
61 - avg_freq = 0
62 - if ticks_since_last != 0:
63 - for frequency, ticks in deltas.items():
64 - avg_freq += frequency * ticks
65 - avg_freq /= ticks_since_last
66 -
67 - data[name] = avg_freq
68 - self.accurate_last[name] = current
69 - if avg_freq == 0 or ticks_since_last == 0:
70 - # Delta is either too large or nonexistent, fall back to
71 - # less accurate reading. This can happen if we switch
72 - # to/from the 'schedutil' governor, which doesn't report
73 - # stats.
74 - accurate_ok = False
75 -
76 - if accurate_ok:
77 - return data
78 -
79 - for name, paths in self.assignment.items():
80 - data[name] = open(paths['inaccurate'], 'r').read()
81 -
82 - return data
83 -
84 - def check(self):
85 - try:
86 - self.sys_dir = str(self.configuration['sys_dir'])
87 - except (KeyError, TypeError):
88 - self.error("No path specified. Using: '" + self.sys_dir + "'")
89 -
90 - for path in glob.glob(self.sys_dir + '/system/cpu/cpu*/cpufreq/stats/time_in_state'):
91 - path_elem = path.split('/')
92 - cpu = path_elem[-4]
93 - if cpu not in self.assignment:
94 - self.assignment[cpu] = {}
95 - self.assignment[cpu]['accurate'] = path
96 - self.accurate_last[cpu] = {}
97 -
98 - if not self.assignment:
99 - self.accurate_exists = False
100 -
101 - for path in glob.glob(self.sys_dir + '/system/cpu/cpu*/cpufreq/scaling_cur_freq'):
102 - path_elem = path.split('/')
103 - cpu = path_elem[-3]
104 - if cpu not in self.assignment:
105 - self.assignment[cpu] = {}
106 - self.assignment[cpu]['inaccurate'] = path
107 -
108 - if not self.assignment:
109 - self.error("couldn't find a method to read cpufreq statistics")
110 - return False
111 -
112 - for name in sorted(self.assignment, key=lambda v: int(v[3:])):
113 - self.definitions[ORDER[0]]['lines'].append([name, name, 'absolute', 1, 1000])
114 -
115 - return True
collectors/python.d.plugin/cpufreq/cpufreq.conf deleted
-41
@@ -1,41 +0,0 @@
1 -# netdata python.d.plugin configuration for cpufreq
2 -#
3 -# This file is in YaML format. Generally the format is:
4 -#
5 -# name: value
6 -#
7 -# There are 2 sections:
8 -# - global variables
9 -# - one or more JOBS
10 -#
11 -# JOBS allow you to collect values from multiple sources.
12 -# Each source will have its own set of charts.
13 -#
14 -# JOB parameters have to be indented (using spaces only, example below).
15 -
16 -# ----------------------------------------------------------------------
17 -# Global Variables
18 -# These variables set the defaults for all JOBs, however each JOB
19 -# may define its own, overriding the defaults.
20 -
21 -# update_every sets the default data collection frequency.
22 -# If unset, the python.d.plugin default is used.
23 -# update_every: 1
24 -
25 -# priority controls the order of charts at the netdata dashboard.
26 -# Lower numbers move the charts towards the top of the page.
27 -# If unset, the default for python.d.plugin is used.
28 -# priority: 60000
29 -
30 -# penalty indicates whether to apply penalty to update_every in case of failures.
31 -# Penalty will increase every 5 failed updates in a row. Maximum penalty is 10 minutes.
32 -# penalty: yes
33 -
34 -# autodetection_retry sets the job re-check interval in seconds.
35 -# The job is not deleted if check fails.
36 -# Attempts to start the job are made once every autodetection_retry.
37 -# This feature is disabled by default.
38 -# autodetection_retry: 0
39 -
40 -# The directory to search for the file scaling_cur_freq
41 -sys_dir: "/sys/devices"
collectors/python.d.plugin/cpuidle/Makefile.inc deleted
-13
@@ -1,13 +0,0 @@
1 -# SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -# THIS IS NOT A COMPLETE Makefile
4 -# IT IS INCLUDED BY ITS PARENT'S Makefile.am
5 -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT
6 -
7 -# install these files
8 -dist_python_DATA += cpuidle/cpuidle.chart.py
9 -dist_pythonconfig_DATA += cpuidle/cpuidle.conf
10 -
11 -# do not install these files, but include them in the distribution
12 -dist_noinst_DATA += cpuidle/README.md cpuidle/Makefile.inc
13 -
collectors/python.d.plugin/cpuidle/README.md deleted
-13
@@ -1,13 +0,0 @@
1 -# cpuidle
2 -
3 -This module monitors the usage of CPU idle states.
4 -
5 -**Requirement:**
6 -Your kernel needs to have `CONFIG_CPU_IDLE` enabled.
7 -
8 -It produces one stacked chart per CPU, showing the percentage of time spent in
9 -each state.
10 -
11 ----
12 -
13 -[![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%2Fpython.d.plugin%2Fcpuidle%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/python.d.plugin/cpuidle/cpuidle.chart.py deleted
-148
@@ -1,148 +0,0 @@
1 -# -*- coding: utf-8 -*-
2 -# Description: cpuidle netdata python.d module
3 -# Author: Steven Noonan (tycho)
4 -# SPDX-License-Identifier: GPL-3.0-or-later
5 -
6 -import ctypes
7 -import glob
8 -import os
9 -import platform
10 -
11 -from bases.FrameworkServices.SimpleService import SimpleService
12 -
13 -syscall = ctypes.CDLL('libc.so.6').syscall
14 -
15 -# default module values (can be overridden per job in `config`)
16 -# update_every = 2
17 -
18 -
19 -class Service(SimpleService):
20 - def __init__(self, configuration=None, name=None):
21 - prefix = os.getenv('NETDATA_HOST_PREFIX', "")
22 - if prefix.endswith('/'):
23 - prefix = prefix[:-1]
24 - self.sys_dir = prefix + "/sys/devices/system/cpu"
25 - self.schedstat_path = prefix + "/proc/schedstat"
26 - SimpleService.__init__(self, configuration=configuration, name=name)
27 - self.order = []
28 - self.definitions = {}
29 - self.fake_name = 'cpu'
30 - self.assignment = {}
31 - self.last_schedstat = None
32 -
33 - @staticmethod
34 - def __gettid():
35 - # This is horrendous. We need the *thread id* (not the *process id*),
36 - # but there's no Python standard library way of doing that. If you need
37 - # to enable this module on a non-x86 machine type, you'll have to find
38 - # the Linux syscall number for gettid() and add it to the dictionary
39 - # below.
40 - syscalls = {
41 - 'i386': 224,
42 - 'x86_64': 186,
43 - }
44 - if platform.machine() not in syscalls:
45 - return None
46 - tid = syscall(syscalls[platform.machine()])
47 - return tid
48 -
49 - def __wake_cpus(self, cpus):
50 - # Requires Python 3.3+. This will "tickle" each CPU to force it to
51 - # update its idle counters.
52 - if hasattr(os, 'sched_setaffinity'):
53 - pid = self.__gettid()
54 - save_affinity = os.sched_getaffinity(pid)
55 - for idx in cpus:
56 - os.sched_setaffinity(pid, [idx])
57 - os.sched_getaffinity(pid)
58 - os.sched_setaffinity(pid, save_affinity)
59 -
60 - def __read_schedstat(self):
61 - cpus = {}
62 - for line in open(self.schedstat_path, 'r'):
63 - if not line.startswith('cpu'):
64 - continue
65 - line = line.rstrip().split()
66 - cpu = line[0]
67 - active_time = line[7]
68 - cpus[cpu] = int(active_time) // 1000
69 - return cpus
70 -
71 - def _get_data(self):
72 - results = {}
73 -
74 - # Use the kernel scheduler stats to determine how much time was spent
75 - # in C0 (active).
76 - schedstat = self.__read_schedstat()
77 -
78 - # Determine if any of the CPUs are idle. If they are, then we need to
79 - # tickle them in order to update their C-state residency statistics.
80 - if self.last_schedstat is None:
81 - needs_tickle = list(self.assignment.keys())
82 - else:
83 - needs_tickle = []
84 - for cpu, active_time in self.last_schedstat.items():
85 - delta = schedstat[cpu] - active_time
86 - if delta < 1:
87 - needs_tickle.append(cpu)
88 -
89 - if needs_tickle:
90 - # This line is critical for the stats to update. If we don't "tickle"
91 - # idle CPUs, then the counters for those CPUs stop counting.
92 - self.__wake_cpus([int(cpu[3:]) for cpu in needs_tickle])
93 -
94 - # Re-read schedstat now that we've tickled any idlers.
95 - schedstat = self.__read_schedstat()
96 -
97 - self.last_schedstat = schedstat
98 -
99 - for cpu, metrics in self.assignment.items():
100 - update_time = schedstat[cpu]
101 - results[cpu + '_active_time'] = update_time
102 -
103 - for metric, path in metrics.items():
104 - residency = int(open(path, 'r').read())
105 - results[metric] = residency
106 -
107 - return results
108 -
109 - def check(self):
110 - if self.__gettid() is None:
111 - self.error('Cannot get thread ID. Stats would be completely broken.')
112 - return False
113 -
114 - for path in sorted(glob.glob(self.sys_dir + '/cpu*/cpuidle/state*/name')):
115 - # ['', 'sys', 'devices', 'system', 'cpu', 'cpu0', 'cpuidle', 'state3', 'name']
116 - path_elem = path.split('/')
117 - cpu = path_elem[-4]
118 - state = path_elem[-2]
119 - statename = open(path, 'rt').read().rstrip()
120 -
121 - orderid = '%s_cpuidle' % (cpu,)
122 - if orderid not in self.definitions:
123 - self.order.append(orderid)
124 - active_name = '%s_active_time' % (cpu,)
125 - self.definitions[orderid] = {
126 - 'options': [None, 'C-state residency', 'time%', 'cpuidle', 'cpuidle.cpuidle', 'stacked'],
127 - 'lines': [
128 - [active_name, 'C0 (active)', 'percentage-of-incremental-row', 1, 1],
129 - ],
130 - }
131 - self.assignment[cpu] = {}
132 -
133 - defid = '%s_%s_time' % (orderid, state)
134 -
135 - self.definitions[orderid]['lines'].append(
136 - [defid, statename, 'percentage-of-incremental-row', 1, 1]
137 - )
138 -
139 - self.assignment[cpu][defid] = '/'.join(path_elem[:-1] + ['time'])
140 -
141 - # Sort order by kernel-specified CPU index
142 - self.order.sort(key=lambda x: int(x.split('_')[0][3:]))
143 -
144 - if not self.definitions:
145 - self.error("couldn't find cstate stats")
146 - return False
147 -
148 - return True
collectors/python.d.plugin/cpuidle/cpuidle.conf deleted
-38
@@ -1,38 +0,0 @@
1 -# netdata python.d.plugin configuration for cpuidle
2 -#
3 -# This file is in YaML format. Generally the format is:
4 -#
5 -# name: value
6 -#
7 -# There are 2 sections:
8 -# - global variables
9 -# - one or more JOBS
10 -#
11 -# JOBS allow you to collect values from multiple sources.
12 -# Each source will have its own set of charts.
13 -#
14 -# JOB parameters have to be indented (using spaces only, example below).
15 -
16 -# ----------------------------------------------------------------------
17 -# Global Variables
18 -# These variables set the defaults for all JOBs, however each JOB
19 -# may define its own, overriding the defaults.
20 -
21 -# update_every sets the default data collection frequency.
22 -# If unset, the python.d.plugin default is used.
23 -# update_every: 1
24 -
25 -# priority controls the order of charts at the netdata dashboard.
26 -# Lower numbers move the charts towards the top of the page.
27 -# If unset, the default for python.d.plugin is used.
28 -# priority: 60000
29 -
30 -# penalty indicates whether to apply penalty to update_every in case of failures.
31 -# Penalty will increase every 5 failed updates in a row. Maximum penalty is 10 minutes.
32 -# penalty: yes
33 -
34 -# autodetection_retry sets the job re-check interval in seconds.
35 -# The job is not deleted if check fails.
36 -# Attempts to start the job are made once every autodetection_retry.
37 -# This feature is disabled by default.
38 -# autodetection_retry: 0
collectors/python.d.plugin/linux_power_supply/Makefile.inc deleted
-13
@@ -1,13 +0,0 @@
1 -# SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -# THIS IS NOT A COMPLETE Makefile
4 -# IT IS INCLUDED BY ITS PARENT'S Makefile.am
5 -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT
6 -
7 -# install these files
8 -dist_python_DATA += linux_power_supply/linux_power_supply.chart.py
9 -dist_pythonconfig_DATA += linux_power_supply/linux_power_supply.conf
10 -
11 -# do not install these files, but include them in the distribution
12 -dist_noinst_DATA += linux_power_supply/README.md linux_power_supply/Makefile.inc
13 -
collectors/python.d.plugin/linux_power_supply/README.md deleted
-74
@@ -1,74 +0,0 @@
1 -# Linux power supply
2 -
3 -> THIS MODULE IS OBSOLETE.
4 -> USE THE [PROC PLUGIN](../../proc.plugin) - IT IS MORE EFFICIENT
5 -
6 ----
7 -
8 -This module monitors variosu metrics reported by power supply drivers
9 -on Linux. This allows tracking and alerting on things like remaining
10 -battery capacity.
11 -
12 -Depending on the uderlying driver, it may provide the following charts
13 -and metrics:
14 -
15 -1. Capacity: The power supply capacity expressed as a percentage.
16 - * capacity\_now
17 -
18 -2. Charge: The charge for the power supply, expressed as microamphours.
19 - * charge\_full\_design
20 - * charge\_full
21 - * charge\_now
22 - * charge\_empty
23 - * charge\_empty\_design
24 -
25 -3. Energy: The energy for the power supply, expressed as microwatthours.
26 - * energy\_full\_design
27 - * energy\_full
28 - * energy\_now
29 - * energy\_empty
30 - * energy\_empty\_design
31 -
32 -2. Voltage: The voltage for the power supply, expressed as microvolts.
33 - * voltage\_max\_design
34 - * voltage\_max
35 - * voltage\_now
36 - * voltage\_min
37 - * voltage\_min\_design
38 -
39 -### configuration
40 -
41 -Sample:
42 -
43 -```yaml
44 -battery:
45 - supply: 'BAT0'
46 - charts: 'capacity charge energy voltage'
47 -```
48 -
49 -The `supply` key specifies the name of the power supply device to monitor.
50 -You can use `ls /sys/class/power_supply` to get a list of such devices
51 -on your system.
52 -
53 -The `charts` key is a space separated list of which charts to try
54 -to display. It defaults to trying to display everything.
55 -
56 -### notes
57 -
58 -* Most drivers provide at least the first chart. Battery powered ACPI
59 -compliant systems (like most laptops) provide all but the third, but do
60 -not provide all of the metrics for each chart.
61 -
62 -* Current, energy, and voltages are reported with a _very_ high precision
63 -by the power\_supply framework. Usually, this is far higher than the
64 -actual hardware supports reporting, so expect to see changes in these
65 -charts jump instead of scaling smoothly.
66 -
67 -* If `max` or `full` attribute is defined by the driver, but not a
68 -corresponding `min or `empty` attribute, then netdata will still provide
69 -the corresponding `min` or `empty`, which will then always read as zero.
70 -This way, alerts which match on these will still work.
71 -
72 ----
73 -
74 -[![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%2Fpython.d.plugin%2Flinux_power_supply%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/python.d.plugin/linux_power_supply/linux_power_supply.chart.py deleted
-160
@@ -1,160 +0,0 @@
1 -# -*- coding: utf-8 -*-
2 -# Description: Linux power_supply netdata python.d module
3 -# Author: Austin S. Hemmelgarn (Ferroin)
4 -
5 -import os
6 -import platform
7 -
8 -from bases.FrameworkServices.SimpleService import SimpleService
9 -
10 -# Everything except percentages is reported as µ units.
11 -PRECISION = 10 ** 6
12 -
13 -# A priority of 90000 places us next to the other PSU related stuff.
14 -PRIORITY = 90000
15 -
16 -# We add our charts dynamically when we probe for the device attributes,
17 -# so these are empty by default.
18 -ORDER = []
19 -
20 -CHARTS = {}
21 -
22 -
23 -def get_capacity_chart(syspath):
24 - # Capacity is measured in percent. We track one value.
25 - options = [None, 'Capacity', '%', 'power_supply', 'power_supply.capacity', 'line']
26 - lines = list()
27 - attr_now = 'capacity'
28 - if get_sysfs_value(os.path.join(syspath, attr_now)) is not None:
29 - lines.append([attr_now, attr_now, 'absolute', 1, 1])
30 - return {'capacity': {'options': options, 'lines': lines}}, [attr_now]
31 - else:
32 - return None, None
33 -
34 -
35 -def get_generic_chart(syspath, name, unit, maxname, minname):
36 - # Used to generate charts for energy, charge, and voltage.
37 - options = [None, name.title(), unit, 'power_supply', 'power_supply.{0}'.format(name), 'line']
38 - lines = list()
39 - attrlist = list()
40 - attr_max_design = '{0}_{1}_design'.format(name, maxname)
41 - attr_max = '{0}_{1}'.format(name, maxname)
42 - attr_now = '{0}_now'.format(name)
43 - attr_min = '{0}_{1}'.format(name, minname)
44 - attr_min_design = '{0}_{1}_design'.format(name, minname)
45 - if get_sysfs_value(os.path.join(syspath, attr_now)) is not None:
46 - lines.append([attr_now, attr_now, 'absolute', 1, PRECISION])
47 - attrlist.append(attr_now)
48 - else:
49 - return None, None
50 - if get_sysfs_value(os.path.join(syspath, attr_max)) is not None:
51 - lines.insert(0, [attr_max, attr_max, 'absolute', 1, PRECISION])
52 - lines.append([attr_min, attr_min, 'absolute', 1, PRECISION])
53 - attrlist.append(attr_max)
54 - attrlist.append(attr_min)
55 - elif get_sysfs_value(os.path.join(syspath, attr_min)) is not None:
56 - lines.append([attr_min, attr_min, 'absolute', 1, PRECISION])
57 - attrlist.append(attr_min)
58 - if get_sysfs_value(os.path.join(syspath, attr_max_design)) is not None:
59 - lines.insert(0, [attr_max_design, attr_max_design, 'absolute', 1, PRECISION])
60 - lines.append([attr_min_design, attr_min_design, 'absolute', 1, PRECISION])
61 - attrlist.append(attr_max_design)
62 - attrlist.append(attr_min_design)
63 - elif get_sysfs_value(os.path.join(syspath, attr_min_design)) is not None:
64 - lines.append([attr_min_design, attr_min_design, 'absolute', 1, PRECISION])
65 - attrlist.append(attr_min_design)
66 - return {name: {'options': options, 'lines': lines}}, attrlist
67 -
68 -
69 -def get_charge_chart(syspath):
70 - # Charge is measured in microamphours. We track up to five
71 - # attributes.
72 - return get_generic_chart(syspath, 'charge', 'µAh', 'full', 'empty')
73 -
74 -
75 -def get_energy_chart(syspath):
76 - # Energy is measured in microwatthours. We track up to five
77 - # attributes.
78 - return get_generic_chart(syspath, 'energy', 'µWh', 'full', 'empty')
79 -
80 -
81 -def get_voltage_chart(syspath):
82 - # Voltage is measured in microvolts. We track up to five attributes.
83 - return get_generic_chart(syspath, 'voltage', 'µV', 'min', 'max')
84 -
85 -
86 -# This is a list of functions for generating charts. Used below to save
87 -# a bit of code (and to make it a bit easier to add new charts).
88 -GET_CHART = {
89 - 'capacity': get_capacity_chart,
90 - 'charge': get_charge_chart,
91 - 'energy': get_energy_chart,
92 - 'voltage': get_voltage_chart
93 -}
94 -
95 -
96 -# This opens the specified file and returns the value in it or None if
97 -# the file doesn't exist.
98 -def get_sysfs_value(filepath):
99 - try:
100 - with open(filepath, 'r') as datasource:
101 - return int(datasource.read())
102 - except (OSError, IOError):
103 - return None
104 -
105 -
106 -class Service(SimpleService):
107 - def __init__(self, configuration=None, name=None):
108 - SimpleService.__init__(self, configuration=configuration, name=name)
109 - self.definitions = dict()
110 - self.order = list()
111 - self.attrlist = list()
112 - self.supply = self.configuration.get('supply', None)
113 - if self.supply is not None:
114 - self.syspath = '/sys/class/power_supply/{0}'.format(self.supply)
115 - self.types = self.configuration.get('charts', 'capacity').split()
116 -
117 - def check(self):
118 - if platform.system() != 'Linux':
119 - self.error('Only supported on Linux.')
120 - return False
121 - if self.supply is None:
122 - self.error('No power supply specified for monitoring.')
123 - return False
124 - if not self.types:
125 - self.error('No attributes requested for monitoring.')
126 - return False
127 - if not os.access(self.syspath, os.R_OK):
128 - self.error('Unable to access {0}'.format(self.syspath))
129 - return False
130 - return self.create_charts()
131 -
132 - def create_charts(self):
133 - chartset = set(GET_CHART).intersection(set(self.types))
134 - if not chartset:
135 - self.error('No valid attributes requested for monitoring.')
136 - return False
137 - charts = dict()
138 - attrlist = list()
139 - for item in chartset:
140 - chart, attrs = GET_CHART[item](self.syspath)
141 - if chart is not None:
142 - charts.update(chart)
143 - attrlist.extend(attrs)
144 - if len(charts) == 0:
145 - self.error('No charts can be created.')
146 - return False
147 - self.definitions.update(charts)
148 - self.order.extend(sorted(charts))
149 - self.attrlist.extend(attrlist)
150 - return True
151 -
152 - def _get_data(self):
153 - data = dict()
154 - for attr in self.attrlist:
155 - attrpath = os.path.join(self.syspath, attr)
156 - if attr.endswith(('_min', '_min_design', '_empty', '_empty_design')):
157 - data[attr] = get_sysfs_value(attrpath) or 0
158 - else:
159 - data[attr] = get_sysfs_value(attrpath)
160 - return data
collectors/python.d.plugin/linux_power_supply/linux_power_supply.conf deleted
-79
@@ -1,79 +0,0 @@
1 -# netdata python.d.plugin configuration for linux_power_supply
2 -#
3 -# This file is in YaML format. Generally the format is:
4 -#
5 -# name: value
6 -#
7 -# There are 2 sections:
8 -# - global variables
9 -# - one or more JOBS
10 -#
11 -# JOBS allow you to collect values from multiple sources.
12 -# Each source will have its own set of charts.
13 -#
14 -# JOB parameters have to be indented (using spaces only, example below).
15 -
16 -# ----------------------------------------------------------------------
17 -# Global Variables
18 -# These variables set the defaults for all JOBs, however each JOB
19 -# may define its own, overriding the defaults.
20 -
21 -# update_every sets the default data collection frequency.
22 -# If unset, the python.d.plugin default is used.
23 -# update_every: 1
24 -
25 -# priority controls the order of charts at the netdata dashboard.
26 -# Lower numbers move the charts towards the top of the page.
27 -# If unset, the default for python.d.plugin is used.
28 -# priority: 60000
29 -
30 -# penalty indicates whether to apply penalty to update_every in case of failures.
31 -# Penalty will increase every 5 failed updates in a row. Maximum penalty is 10 minutes.
32 -# penalty: yes
33 -
34 -# autodetection_retry sets the job re-check interval in seconds.
35 -# The job is not deleted if check fails.
36 -# Attempts to start the job are made once every autodetection_retry.
37 -# This feature is disabled by default.
38 -# autodetection_retry: 0
39 -
40 -# ----------------------------------------------------------------------
41 -# JOBS (data collection sources)
42 -#
43 -# The default JOBS share the same *name*. JOBS with the same name
44 -# are mutually exclusive. Only one of them will be allowed running at
45 -# any time. This allows autodetection to try several alternatives and
46 -# pick the one that works.
47 -#
48 -# Any number of jobs is supported.
49 -#
50 -# All python.d.plugin JOBS (for all its modules) support a set of
51 -# predefined parameters. These are:
52 -#
53 -# job_name:
54 -# name: myname # the JOB's name as it will appear at the
55 -# # dashboard (by default is the job_name)
56 -# # JOBs sharing a name are mutually exclusive
57 -# update_every: 1 # the JOB's data collection frequency
58 -# priority: 60000 # the JOB's order on the dashboard
59 -# penalty: yes # the JOB's penalty
60 -# autodetection_retry: 0 # the JOB's re-check interval in seconds
61 -#
62 -# In addition to the above parameters, linux_power_supply also supports
63 -# the following extra parameters.
64 -#
65 -# supply: '' # the name of the power supply to monitor
66 -# charts: 'capacity' # a space separated list of the charts to try
67 -# # and generate valid charts are 'capacity',
68 -# # 'charge', 'current', and 'voltage'
69 -#
70 -# Note that linux_power_supply will not automatically detect power
71 -# supplies in the system, you have to manually specify which ones you
72 -# want it to monitor.
73 -#
74 -# The following config will work to monitor the first battery in most
75 -# ACPI compliant battery powered systems (such as most laptops).
76 -#
77 -# battery:
78 -# name: battery
79 -# supply: BAT0
collectors/python.d.plugin/mdstat/Makefile.inc deleted
-13
@@ -1,13 +0,0 @@
1 -# SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -# THIS IS NOT A COMPLETE Makefile
4 -# IT IS INCLUDED BY ITS PARENT'S Makefile.am
5 -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT
6 -
7 -# install these files
8 -dist_python_DATA += mdstat/mdstat.chart.py
9 -dist_pythonconfig_DATA += mdstat/mdstat.conf
10 -
11 -# do not install these files, but include them in the distribution
12 -dist_noinst_DATA += mdstat/README.md mdstat/Makefile.inc
13 -
collectors/python.d.plugin/mdstat/README.md deleted
-33
@@ -1,33 +0,0 @@
1 -# mdstat
2 -
3 -> THIS MODULE IS OBSOLETE.
4 -> USE THE [PROC PLUGIN](../../proc.plugin) - IT IS MORE EFFICIENT
5 -
6 ----
7 -
8 -Module monitor /proc/mdstat
9 -
10 -It produces:
11 -
12 -1. **Health** Number of failed disks in every array (aggregate chart).
13 -
14 -2. **Disks stats**
15 - * total (number of devices array ideally would have)
16 - * inuse (number of devices currently are in use)
17 -
18 -3. **Current status**
19 - * resync in percent
20 - * recovery in percent
21 - * reshape in percent
22 - * check in percent
23 -
24 -4. **Operation status** (if resync/recovery/reshape/check is active)
25 - * finish in minutes
26 - * speed in megabytes/s
27 -
28 -### configuration
29 -No configuration is needed.
30 -
31 ----
32 -
33 -[![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%2Fpython.d.plugin%2Fmdstat%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/python.d.plugin/mdstat/mdstat.chart.py deleted
-205
@@ -1,205 +0,0 @@
1 -# -*- coding: utf-8 -*-
2 -# Description: mdstat netdata python.d module
3 -# Author: Ilya Mashchenko (l2isbad)
4 -# SPDX-License-Identifier: GPL-3.0-or-later
5 -
6 -import re
7 -
8 -from collections import defaultdict
9 -
10 -from bases.FrameworkServices.SimpleService import SimpleService
11 -
12 -MDSTAT = '/proc/mdstat'
13 -MISMATCH_CNT = '/sys/block/{0}/md/mismatch_cnt'
14 -
15 -ORDER = ['mdstat_health']
16 -
17 -CHARTS = {
18 - 'mdstat_health': {
19 - 'options': [None, 'Faulty Devices In MD', 'failed disks', 'health', 'md.health', 'line'],
20 - 'lines': []
21 - }
22 -}
23 -
24 -RE_DISKS = re.compile(r' (?P<array>[a-zA-Z_0-9]+) : active .+\['
25 - r'(?P<total_disks>[0-9]+)/'
26 - r'(?P<inuse_disks>[0-9]+)\]')
27 -
28 -RE_STATUS = re.compile(r' (?P<array>[a-zA-Z_0-9]+) : active .+ '
29 - r'(?P<operation>[a-z]+) =[ ]{1,2}'
30 - r'(?P<operation_status>[0-9.]+).+finish='
31 - r'(?P<finish_in>([0-9.]+))min speed='
32 - r'(?P<speed>[0-9]+)')
33 -
34 -
35 -def md_charts(name):
36 - order = [
37 - '{0}_disks'.format(name),
38 - '{0}_operation'.format(name),
39 - '{0}_mismatch_cnt'.format(name),
40 - '{0}_finish'.format(name),
41 - '{0}_speed'.format(name)
42 - ]
43 -
44 - charts = dict()
45 - charts[order[0]] = {
46 - 'options': [None, 'Disks Stats', 'disks', name, 'md.disks', 'stacked'],
47 - 'lines': [
48 - ['{0}_total_disks'.format(name), 'total', 'absolute'],
49 - ['{0}_inuse_disks'.format(name), 'inuse', 'absolute']
50 - ]
51 - }
52 -
53 - charts[order[1]] = {
54 - 'options': [None, 'Current Status', 'percent', name, 'md.status', 'line'],
55 - 'lines': [
56 - ['{0}_resync'.format(name), 'resync', 'absolute', 1, 100],
57 - ['{0}_recovery'.format(name), 'recovery', 'absolute', 1, 100],
58 - ['{0}_reshape'.format(name), 'reshape', 'absolute', 1, 100],
59 - ['{0}_check'.format(name), 'check', 'absolute', 1, 100],
60 - ]
61 - }
62 -
63 - charts[order[2]] = {
64 - 'options': [None, 'Mismatch Count', 'unsynchronized blocks', name, 'md.mismatch_cnt', 'line'],
65 - 'lines': [
66 - ['{0}_mismatch_cnt'.format(name), 'count', 'absolute']
67 - ]
68 - }
69 -
70 - charts[order[3]] = {
71 - 'options': [None, 'Approximate Time Until Finish', 'seconds', name, 'md.rate', 'line'],
72 - 'lines': [
73 - ['{0}_finish_in'.format(name), 'finish in', 'absolute', 1, 1000]
74 - ]
75 - }
76 -
77 - charts[order[4]] = {
78 - 'options': [None, 'Operation Speed', 'KB/s', name, 'md.rate', 'line'],
79 - 'lines': [
80 - ['{0}_speed'.format(name), 'speed', 'absolute', 1, 1000]
81 - ]
82 - }
83 -
84 - return order, charts
85 -
86 -
87 -class MD:
88 - def __init__(self, raw_data):
89 - self.name = raw_data['array']
90 - self.d = raw_data
91 -
92 - def data(self):
93 - rv = {
94 - 'total_disks': self.d['total_disks'],
95 - 'inuse_disks': self.d['inuse_disks'],
96 - 'health': int(self.d['total_disks']) - int(self.d['inuse_disks']),
97 - 'resync': 0,
98 - 'recovery': 0,
99 - 'reshape': 0,
100 - 'check': 0,
101 - 'finish_in': 0,
102 - 'speed': 0,
103 - }
104 -
105 - v = read_lines(MISMATCH_CNT.format(self.name))
106 - if v:
107 - rv['mismatch_cnt'] = v
108 -
109 - if self.d.get('operation'):
110 - rv[self.d['operation']] = float(self.d['operation_status']) * 100
111 - rv['finish_in'] = float(self.d['finish_in']) * 1000 * 60
112 - rv['speed'] = float(self.d['speed']) * 1000
113 -
114 - return dict(('{0}_{1}'.format(self.name, k), v) for k, v in rv.items())
115 -
116 -
117 -class Service(SimpleService):
118 - def __init__(self, configuration=None, name=None):
119 - SimpleService.__init__(self, configuration=configuration, name=name)
120 - self.order = ORDER
121 - self.definitions = CHARTS
122 - self.mds = list()
123 -
124 - @staticmethod
125 - def get_mds():
126 - raw = read_lines(MDSTAT)
127 -
128 - if not raw:
129 - return None
130 -
131 - return find_mds(raw)
132 -
133 - def get_data(self):
134 - """
135 - Parse data from _get_raw_data()
136 - :return: dict
137 - """
138 - mds = self.get_mds()
139 -
140 - if not mds:
141 - return None
142 -
143 - data = dict()
144 - for md in mds:
145 - if md.name not in self.mds:
146 - self.mds.append(md.name)
147 - self.add_new_md_charts(md.name)
148 - data.update(md.data())
149 - return data
150 -
151 - def check(self):
152 - if not self.get_mds():
153 - self.error('Failed to read data from {0} or there is no active arrays'.format(MDSTAT))
154 - return False
155 - return True
156 -
157 - def add_new_md_charts(self, name):
158 - order, charts = md_charts(name)
159 -
160 - self.charts['mdstat_health'].add_dimension(['{0}_health'.format(name), name])
161 -
162 - for chart_name in order:
163 - params = [chart_name] + charts[chart_name]['options']
164 - dims = charts[chart_name]['lines']
165 -
166 - chart = self.charts.add_chart(params)
167 - for dim in dims:
168 - chart.add_dimension(dim)
169 -
170 -
171 -def find_mds(raw_data):
172 - data = defaultdict(str)
173 - counter = 1
174 -
175 - for row in (elem.strip() for elem in raw_data):
176 - if not row:
177 - counter += 1
178 - continue
179 - data[counter] = ' '.join([data[counter], row])
180 -
181 - mds = list()
182 -
183 - for v in data.values():
184 - m = RE_DISKS.search(v)
185 -
186 - if not m:
187 - continue
188 -
189 - d = m.groupdict()
190 -
191 - m = RE_STATUS.search(v)
192 - if m:
193 - d.update(m.groupdict())
194 -
195 - mds.append(MD(d))
196 -
197 - return sorted(mds, key=lambda md: md.name)
198 -
199 -
200 -def read_lines(path):
201 - try:
202 - with open(path) as f:
203 - return f.readlines()
204 - except (IOError, OSError):
205 - return None
collectors/python.d.plugin/mdstat/mdstat.conf deleted
-30
@@ -1,30 +0,0 @@
1 -# netdata python.d.plugin configuration for mdstat
2 -#
3 -# This file is in YaML format. Generally the format is:
4 -#
5 -# name: value
6 -#
7 -
8 -# ----------------------------------------------------------------------
9 -# Global Variables
10 -# These variables set the defaults for all JOBs, however each JOB
11 -# may define its own, overriding the defaults.
12 -
13 -# update_every sets the default data collection frequency.
14 -# If unset, the python.d.plugin default is used.
15 -# update_every: 1
16 -
17 -# priority controls the order of charts at the netdata dashboard.
18 -# Lower numbers move the charts towards the top of the page.
19 -# If unset, the default for python.d.plugin is used.
20 -# priority: 60000
21 -
22 -# penalty indicates whether to apply penalty to update_every in case of failures.
23 -# Penalty will increase every 5 failed updates in a row. Maximum penalty is 10 minutes.
24 -# penalty: yes
25 -
26 -# autodetection_retry sets the job re-check interval in seconds.
27 -# The job is not deleted if check fails.
28 -# Attempts to start the job are made once every autodetection_retry.
29 -# This feature is disabled by default.
30 -# autodetection_retry: 0
collectors/python.d.plugin/python.d.conf
-4
@@ -36,8 +36,6 @@ apache_cache: no
36 # ceph: yes
37 chrony: no
38 # couchdb: yes
39 -# cpufreq: yes
40 -# cpuidle: yes
39 # dns_query_time: yes
40 # dnsdist: yes
41 # dockerd: yes
@@ -60,10 +58,8 @@ gunicorn_log: no
58 # icecast: yes
59 # ipfs: yes
60 # isc_dhcpd: yes
63 -# linux_power_supply: yes
61 # litespeed: yes
62 logind: no
66 -# mdstat: yes
63 # megacli: yes
64 # memcached: yes
65 # mongodb: yes
docs/Add-more-charts-to-netdata.md
+1 -3
@@ -16,7 +16,7 @@ To collect non-system metrics, netdata supports a plugin architecture. The follo
16 - **[Name Servers](#name-servers)** (DNS), like bind, nsd, powerdns, dnsdist
17 - **[DHCP Servers](#dhcp-servers)**, like ISC DHCP
18 - **[UPS](#ups)**, such as APC UPS, NUT
19 -- **[RAID](#raid)**, such as linux software raid (mdadm), MegaRAID
19 +- **[RAID](#raid)**, such as MegaRAID
20 - **[Mail Servers](#mail-servers)**, like postfix, exim, dovecot
21 - **[File Servers](#file-servers)**, like samba, NFS, ftp, sftp, WebDAV
22 - **[Print Servers](#print-servers)**, like CUPS
@@ -268,7 +268,6 @@ nut|BASH<br/>Shell Script|Connects to a nut server (upsd) to collect real-time U
268
269 application|language|notes|
270 :---------:|:------:|:----|
271 -mdstat|python<br/>v2 or v3|Parses `/proc/mdstat` to get mds health metrics.<br/>&nbsp;<br/>netdata plugin: [python.d.plugin](../collectors/python.d.plugin)<br/>plugin module: [mdstat.chart.py](../collectors/python.d.plugin/mdstat)<br/>configuration file: [python.d/mdstat.conf](../collectors/python.d.plugin/mdstat)|
271 megacli|python<br/>v2 or v3|Collects adapter, physical drives and battery stats..<br/>&nbsp;<br/>netdata plugin: [python.d.plugin](../collectors/python.d.plugin)<br/>plugin module: [megacli.chart.py](../collectors/python.d.plugin/megacli)<br/>configuration file: [python.d/megacli.conf](../collectors/python.d.plugin/megacli)|
272
273 ---
@@ -318,7 +317,6 @@ mem_apps|BASH<br/>Shell Script|Collects the memory footprint of select applicati
317
318 application|language|notes|
319 :---------:|:------:|:----|
321 -cpufreq|python<br/>v2 or v3|Collects the current CPU frequency from `/sys/devices`.<br/>&nbsp;<br/>netdata plugin: [python.d.plugin](../collectors/python.d.plugin)<br/>plugin module: [cpufreq.chart.py](../collectors/python.d.plugin/cpufreq)<br/>configuration file: [python.d/cpufreq.conf](../collectors/python.d.plugin/cpufreq)|
320 cpufreq|BASH<br/>Shell Script|Collects current CPU frequency from `/sys/devices`.<br/><br/>DEPRECATED IN FAVOR OF THE PYTHON ONE. It is still supplied only as an example module to shell scripting plugins.<br/>&nbsp;<br/>netdata plugin: [charts.d.plugin](../collectors/charts.d.plugin#chartsdplugin)<br/>plugin module: [cpufreq.chart.sh](../collectors/charts.d.plugin/cpufreq)<br/>configuration file: [charts.d/cpufreq.conf](../collectors/charts.d.plugin/cpufreq)|
321 IPMI|C|Collects temperatures, voltages, currents, power, fans and `SEL` events from IPMI using `libipmimonitoring`.<br/>Check [Monitoring IPMI](../collectors/freeipmi.plugin/) for more information<br/>&nbsp;<br/>netdata plugin: [freeipmi.plugin](../collectors/freeipmi.plugin)<br/>configuration file: none required - to enable it, compile/install netdata with `--enable-plugin-freeipmi`|
322 hddtemp|python<br/>v2 or v3|Connects to multiple hddtemp servers (local or remote) to collect real-time performance metrics.<br/>&nbsp;<br/>netdata plugin: [python.d.plugin](../collectors/python.d.plugin)<br/>plugin module: [hddtemp.chart.py](../collectors/python.d.plugin/hddtemp)<br/>configuration file: [python.d/hddtemp.conf](../collectors/python.d.plugin/hddtemp)|