FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

# -*- coding: utf-8 -*- # Description: netdata python modules framework # Author: Pawel Krupa (paulfantom) # Remember: # ALL CODE NEEDS TO BE COMPATIBLE WITH Python > 2.7 and Python > 3.1 # Follow PEP8 as much as it is possible # "check" and "create" CANNOT be blocking. # "update" CAN be blocking # "update" function needs to be fast, so follow: # https://wiki.python.org/moin/PythonSpeed/PerformanceTips # basically: # - use local variables wherever it is possible # - avoid dots in expressions that are executed many times # - use "join()" instead of "+" # - use "import" only at the beginning # # using ".encode()" in one thread can block other threads as well (only in python2) import time # import sys import os import socket import select try: import urllib.request as urllib2 except ImportError: import urllib2 from subprocess import Popen, PIPE import threading import msg # class BaseService(threading.Thread): class SimpleService(threading.Thread): """ Prototype of Service class. Implemented basic functionality to run jobs by `python.d.plugin` """ def __init__(self, configuration=None, name=None): """ This needs to be initialized in child classes :param configuration: dict :param name: str """ threading.Thread.__init__(self) self._data_stream = "" self.daemon = True self.retries = 0 self.retries_left = 0 self.priority = 140000 self.update_every = 1 self.name = name self.override_name = None self.chart_name = "" self._dimensions = [] self._charts = [] self.__chart_set = False self.__first_run = True self.order = [] self.definitions = {} if configuration is None: self.error("BaseService: no configuration parameters supplied. Cannot create Service.") raise RuntimeError else: self._extract_base_config(configuration) self.timetable = {} self.create_timetable() # --- BASIC SERVICE CONFIGURATION --- def _extract_base_config(self, config): """ Get basic parameters to run service Minimum config: config = {'update_every':1, 'priority':100000, 'retries':0} :param config: dict """ pop = config.pop try: self.override_name = pop('name') except KeyError: pass self.update_every = int(pop('update_every')) self.priority = int(pop('priority')) self.retries = int(pop('retries')) self.retries_left = self.retries self.configuration = config def create_timetable(self, freq=None): """ Create service timetable. `freq` is optional Example: timetable = {'last': 1466370091.3767564, 'next': 1466370092, 'freq': 1} :param freq: int """ if freq is None: freq = self.update_every now = time.time() self.timetable = {'last': now, 'next': now - (now % freq) + freq, 'freq': freq} # --- THREAD CONFIGURATION --- def _run_once(self): """ Executes self.update(interval) and draws run time chart. Return value presents exit status of update() :return: boolean """ t_start = time.time() timetable = self.timetable chart_name = self.chart_name # check if it is time to execute job update() function if timetable['next'] > t_start: self.debug(chart_name, "will be run in", str(int((timetable['next'] - t_start) * 1000)), "ms") return True since_last = int((t_start - timetable['last']) * 1000000) self.debug(chart_name, "ready to run, after", str(int((t_start - timetable['last']) * 1000)), "ms (update_every:", str(timetable['freq'] * 1000), "ms, latency:", str(int((t_start - timetable['next']) * 1000)), "ms") if self.__first_run: since_last = 0 if not self.update(since_last): self.error("update function failed.") return False t_end = time.time() self.timetable['next'] = t_end - (t_end % timetable['freq']) + timetable['freq'] # draw performance graph run_time = str(int((t_end - t_start) * 1000)) # noinspection SqlNoDataSourceInspection print("BEGIN netdata.plugin_pythond_%s %s\nSET run_time = %s\nEND\n" % (self.chart_name, str(since_last), run_time)) # sys.stdout.write("BEGIN netdata.plugin_pythond_%s %s\nSET run_time = %s\nEND\n" % # (self.chart_name, str(since_last), run_time)) self.debug(chart_name, "updated in", str(run_time), "ms") self.timetable['last'] = t_start self.__first_run = False return True def run(self): """ Runs job in thread. Handles retries. Exits when job failed or timed out. :return: None """ self.timetable['last'] = time.time() while True: # run forever, unless something is wrong try: status = self._run_once() except Exception as e: self.error("Something wrong: ", str(e)) return if status: # handle retries if update failed time.sleep(self.timetable['next'] - time.time()) self.retries_left = self.retries else: self.retries_left -= 1 if self.retries_left

Back | FazBrowse Home | New Git URL