summaryrefslogtreecommitdiffstats
path: root/src/collectors/python.d.plugin/gearman/gearman.chart.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/collectors/python.d.plugin/gearman/gearman.chart.py')
-rw-r--r--src/collectors/python.d.plugin/gearman/gearman.chart.py243
1 files changed, 0 insertions, 243 deletions
diff --git a/src/collectors/python.d.plugin/gearman/gearman.chart.py b/src/collectors/python.d.plugin/gearman/gearman.chart.py
deleted file mode 100644
index 5e280a4d..00000000
--- a/src/collectors/python.d.plugin/gearman/gearman.chart.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# Description: dovecot netdata python.d module
-# Author: Kyle Agronick (agronick)
-# SPDX-License-Identifier: GPL-3.0+
-
-# Gearman Netdata Plugin
-
-from copy import deepcopy
-
-from bases.FrameworkServices.SocketService import SocketService
-
-CHARTS = {
- 'total_workers': {
- 'options': [None, 'Total Jobs', 'Jobs', 'Total Jobs', 'gearman.total_jobs', 'line'],
- 'lines': [
- ['total_pending', 'Pending', 'absolute'],
- ['total_running', 'Running', 'absolute'],
- ]
- },
-}
-
-
-def job_chart_template(job_name):
- return {
- 'options': [None, job_name, 'Jobs', 'Activity by Job', 'gearman.single_job', 'stacked'],
- 'lines': [
- ['{0}_pending'.format(job_name), 'Pending', 'absolute'],
- ['{0}_idle'.format(job_name), 'Idle', 'absolute'],
- ['{0}_running'.format(job_name), 'Running', 'absolute'],
- ]
- }
-
-
-def build_result_dict(job):
- """
- Get the status for each job
- :return: dict
- """
-
- total, running, available = job['metrics']
-
- idle = available - running
- pending = total - running
-
- return {
- '{0}_pending'.format(job['job_name']): pending,
- '{0}_idle'.format(job['job_name']): idle,
- '{0}_running'.format(job['job_name']): running,
- }
-
-
-def parse_worker_data(job):
- job_name = job[0]
- job_metrics = job[1:]
-
- return {
- 'job_name': job_name,
- 'metrics': job_metrics,
- }
-
-
-class GearmanReadException(BaseException):
- pass
-
-
-class Service(SocketService):
- def __init__(self, configuration=None, name=None):
- super(Service, self).__init__(configuration=configuration, name=name)
- self.request = "status\n"
- self._keep_alive = True
-
- self.host = self.configuration.get('host', 'localhost')
- self.port = self.configuration.get('port', 4730)
-
- self.tls = self.configuration.get('tls', False)
- self.cert = self.configuration.get('cert', None)
- self.key = self.configuration.get('key', None)
-
- self.active_jobs = set()
- self.definitions = deepcopy(CHARTS)
- self.order = ['total_workers']
-
- def _get_data(self):
- """
- Format data received from socket
- :return: dict
- """
-
- try:
- active_jobs = self.get_active_jobs()
- except GearmanReadException:
- return None
-
- found_jobs, job_data = self.process_jobs(active_jobs)
- self.remove_stale_jobs(found_jobs)
- return job_data
-
- def get_active_jobs(self):
- active_jobs = []
-
- for job in self.get_worker_data():
- parsed_job = parse_worker_data(job)
-
- # Gearman does not clean up old jobs
- # We only care about jobs that have
- # some relevant data
- if not any(parsed_job['metrics']):
- continue
-
- active_jobs.append(parsed_job)
-
- return active_jobs
-
- def get_worker_data(self):
- """
- Split the data returned from Gearman
- into a list of lists
-
- This returns the same output that you
- would get from a gearadmin --status
- command.
-
- Example output returned from
- _get_raw_data():
- prefix generic_worker4 78 78 500
- generic_worker2 78 78 500
- generic_worker3 0 0 760
- generic_worker1 0 0 500
-
- :return: list
- """
-
- try:
- raw = self._get_raw_data()
- except (ValueError, AttributeError):
- raise GearmanReadException()
-
- if raw is None:
- self.debug("Gearman returned no data")
- raise GearmanReadException()
-
- workers = list()
-
- for line in raw.splitlines()[:-1]:
- parts = line.split()
- if not parts:
- continue
-
- name = '_'.join(parts[:-3])
- try:
- values = [int(w) for w in parts[-3:]]
- except ValueError:
- continue
-
- w = [name]
- w.extend(values)
- workers.append(w)
-
- return workers
-
- def process_jobs(self, active_jobs):
-
- output = {
- 'total_pending': 0,
- 'total_idle': 0,
- 'total_running': 0,
- }
- found_jobs = set()
-
- for parsed_job in active_jobs:
-
- job_name = self.add_job(parsed_job)
- found_jobs.add(job_name)
- job_data = build_result_dict(parsed_job)
-
- for sum_value in ('pending', 'running', 'idle'):
- output['total_{0}'.format(sum_value)] += job_data['{0}_{1}'.format(job_name, sum_value)]
-
- output.update(job_data)
-
- return found_jobs, output
-
- def remove_stale_jobs(self, active_job_list):
- """
- Removes jobs that have no workers, pending jobs,
- or running jobs
- :param active_job_list: The latest list of active jobs
- :type active_job_list: iterable
- :return: None
- """
-
- for to_remove in self.active_jobs - active_job_list:
- self.remove_job(to_remove)
-
- def add_job(self, parsed_job):
- """
- Adds a job to the list of active jobs
- :param parsed_job: A parsed job dict
- :type parsed_job: dict
- :return: None
- """
-
- def add_chart(job_name):
- """
- Adds a new job chart
- :param job_name: The name of the job to add
- :type job_name: string
- :return: None
- """
-
- job_key = 'job_{0}'.format(job_name)
- template = job_chart_template(job_name)
- new_chart = self.charts.add_chart([job_key] + template['options'])
- for dimension in template['lines']:
- new_chart.add_dimension(dimension)
-
- if parsed_job['job_name'] not in self.active_jobs:
- add_chart(parsed_job['job_name'])
- self.active_jobs.add(parsed_job['job_name'])
-
- return parsed_job['job_name']
-
- def remove_job(self, job_name):
- """
- Removes a job to the list of active jobs
- :param job_name: The name of the job to remove
- :type job_name: string
- :return: None
- """
-
- def remove_chart(job_name):
- """
- Removes a job chart
- :param job_name: The name of the job to remove
- :type job_name: string
- :return: None
- """
-
- job_key = 'job_{0}'.format(job_name)
- self.charts[job_key].obsolete()
- del self.charts[job_key]
-
- remove_chart(job_name)
- self.active_jobs.remove(job_name)