]> arthur.barton.de Git - netdata.git/blobdiff - python.d/varnish.chart.py
delete obsolete charts and orphan hosts by default
[netdata.git] / python.d / varnish.chart.py
index 7965557356029a3877f8e617936ff14e2d5b84f0..2665bb383b687d3ebb5b2e8acefb1acf98df784f 100644 (file)
@@ -4,27 +4,17 @@
 
 from base import SimpleService
 from re import compile
-from os import access as is_executable, X_OK
 from subprocess import Popen, PIPE
 
-
 # default module values (can be overridden per job in `config`)
 # update_every = 2
 priority = 60000
 retries = 60
 
-ORDER = ['hit_rate', 'chit_rate', 'request_rate', 'transfer_rates', 'session', 'backend_traffic', 'memory_usage', 'bad', 'uptime']
-EXTRA_ORDER = ['hit_rate','chit_rate', 'request_rate', 'transfer_rates', 'session', 'backend_traffic', 'bad',
-               'objects', 'threads', 'memory_usage', 'objects_per_objhead', 'losthdr', 'hcb', 'esi', 'session_herd',
-               'shm_writes', 'shm', 'allocations', 'vcl', 'bans', 'bans_lurker', 'expunge', 'lru', 'gzip', 'uptime']
+ORDER = ['session', 'hit_rate', 'chit_rate', 'expunge', 'threads', 'backend_health', 'memory_usage', 'bad', 'uptime']
 
-CHARTS = {'allocations': 
-             {'lines': [['sm_nreq', None, 'incremental', 1, 1],
-                       ['sma_nreq', None, 'incremental', 1, 1],
-                       ['sms_nreq', None, 'incremental', 1, 1]],
-              'options': [None, 'Memory allocation requests', 'units', 'Extra charts', 'varnish.alloc','line']},
-          'backend_traffic': 
-             {'lines': [['backend_conn_bt', 'conn', 'incremental', 1, 1],
+CHARTS = {'backend_health': 
+             {'lines': [['backend_conn', 'conn', 'incremental', 1, 1],
                        ['backend_unhealthy', 'unhealthy', 'incremental', 1, 1],
                        ['backend_busy', 'busy', 'incremental', 1, 1],
                        ['backend_fail', 'fail', 'incremental', 1, 1],
@@ -33,7 +23,7 @@ CHARTS = {'allocations':
                        ['backend_toolate', 'toolate', 'incremental', 1, 1],
                        ['backend_retry', 'retry', 'incremental', 1, 1],
                        ['backend_req', 'req', 'incremental', 1, 1]],
-              'options': [None, 'Backend health', 'units', 'Backend health', 'varnish.backend_traf', 'line']},
+              'options': [None, 'Backend health', 'connections', 'Backend health', 'varnish.backend_traf', 'line']},
           'bad': 
              {'lines': [['sess_drop_b', None, 'incremental', 1, 1],
                        ['backend_unhealthy_b', None, 'incremental', 1, 1],
@@ -42,51 +32,18 @@ CHARTS = {'allocations':
                        ['threads_failed_b', None, 'incremental', 1, 1],
                        ['threads_limited_b', None, 'incremental', 1, 1],
                        ['threads_destroyed_b', None, 'incremental', 1, 1],
-                       ['thread_queue_len', None, 'absolute', 1, 1],
+                       ['thread_queue_len_b', 'queue_len', 'absolute', 1, 1],
                        ['losthdr_b', None, 'incremental', 1, 1],
                        ['esi_errors_b', None, 'incremental', 1, 1],
                        ['esi_warnings_b', None, 'incremental', 1, 1],
                        ['sess_fail_b', None, 'incremental', 1, 1],
+                       ['sc_pipe_overflow_b', None, 'incremental', 1, 1],
                        ['sess_pipe_overflow_b', None, 'incremental', 1, 1]],
-              'options': [None, 'Misbehavior', 'units', 'Problems summary', 'varnish.bad', 'line']},
-          'bans': 
-             {'lines': [['bans', None, 'absolute', 1, 1],
-                       ['bans_added', 'added', 'incremental', 1, 1],
-                       ['bans_deleted', 'deleted', 'incremental', 1, 1],
-                       ['bans_completed', 'completed', 'absolute', 1, 1],
-                       ['bans_obj', 'obj', 'absolute', 1, 1],
-                       ['bans_req', 'req', 'absolute', 1, 1],
-                       ['bans_tested', 'tested', 'incremental', 1, 1],
-                       ['bans_obj_killed', 'obj_killed', 'incremental', 1, 1],
-                       ['bans_tests_tested', 'tests_tested', 'incremental', 1, 1],
-                       ['bans_dups', 'dups', 'absolute', 1, 1],
-                       ['bans_persisted_bytes', 'pers_bytes', 'absolute', 1, 1],
-                       ['bans_persisted_fragmentation', 'pers_fragmentation', 'absolute', 1, 1]],
-              'options': [None, 'Bans', 'units', 'Extra charts', 'varnish.bans', 'line']},
-          'bans_lurker': 
-             {'lines': [['bans_lurker_tested', 'tested', 'incremental', 1, 1],
-                       ['bans_lurker_tests_tested', 'tests_tested', 'incremental', 1, 1],
-                       ['bans_lurker_obj_killed', 'obj_killed', 'incremental', 1, 1],
-                       ['bans_lurker_contention', 'contention', 'incremental', 1, 1]],
-              'options': [None, 'Ban Lurker', 'units', 'Extra charts', 'varnish.bans_lurker', 'line']},
-          'esi':
-             {'lines': [['esi_parse', None, 'incremental', 1, 1],
-                       ['esi_errors', None, 'incremental', 1, 1],
-                       ['esi_warnings', None, 'incremental', 1, 1]],
-              'options': [None, 'ESI', 'units', 'Extra charts', 'varnish.esi', 'line']},
+              'options': [None, 'Misbehavior', 'problems', 'Problems summary', 'varnish.bad', 'line']},
           'expunge':
-             {'lines': [['n_expired', None, 'incremental', 1, 1],
-                       ['n_lru_nuked_e', None, 'incremental', 1, 1]],
-              'options': [None, 'Object expunging', 'units', 'Extra charts', 'varnish.expunge', 'line']},
-          'gzip': 
-             {'lines': [['n_gzip', None, 'incremental', 1, 1],
-                       ['n_gunzip', None, 'incremental', 1, 1]],
-              'options': [None, 'GZIP activity', 'units', 'Extra charts', 'varnish.gzip', 'line']},
-          'hcb': 
-             {'lines': [['hcb_nolock', 'nolock', 'incremental', 1, 1],
-                       ['hcb_lock', 'lock', 'incremental', 1, 1],
-                       ['hcb_insert', 'insert', 'incremental', 1, 1]],
-              'options': [None, 'Critbit data', 'units', 'Extra charts', 'varnish.hcb', 'line']},
+             {'lines': [['n_expired', 'expired', 'incremental', 1, 1],
+                       ['n_lru_nuked', 'lru_nuked', 'incremental', 1, 1]],
+              'options': [None, 'Object expunging', 'objects', 'Cache performance', 'varnish.expunge', 'line']},
           'hit_rate': 
              {'lines': [['cache_hit_perc', 'hit', 'absolute', 1, 100],
                        ['cache_miss_perc', 'miss', 'absolute', 1, 100],
@@ -97,108 +54,49 @@ CHARTS = {'allocations':
                        ['cache_miss_cperc', 'miss', 'absolute', 1, 100],
                        ['cache_hitpass_cperc', 'hitpass', 'absolute', 1, 100]],
               'options': [None, 'Current poll hit rate ratio','percent', 'Cache performance', 'varnish.chit_rate', 'stacked']},
-          'losthdr': 
-             {'lines': [['losthdr', None, 'incremental', 1, 1]],
-              'options': [None, 'HTTP Header overflows', 'units', 'Extra charts', 'varnish.losthdr', 'line']},
-          'lru':
-             {'lines': [['n_lru_nuked', 'nuked', 'incremental', 1, 1],
-                       ['n_lru_moved', 'moved', 'incremental', 1, 1]],
-              'options': [None, 'LRU activity', 'units', 'Extra charts', 'varnish.lru', 'line']},
           'memory_usage': 
              {'lines': [['s0.g_space', 'available', 'absolute', 1, 1048576],
                        ['s0.g_bytes', 'allocated', 'absolute', -1, 1048576]],
               'options': [None, 'Memory usage', 'megabytes', 'Memory usage', 'varnish.memory_usage', 'stacked']},
-          'objects': 
-             {'lines': [['n_object', 'object', 'absolute', 1, 1],
-                       ['n_objectcore', 'objectcore', 'absolute', 1, 1],
-                       ['n_vampireobject', 'vampireobject, ''absolute', 1, 1],
-                       ['n_objecthead', 'objecthead', 'absolute', 1, 1]],
-              'options': [None, 'Number of objects', 'units', 'Extra charts', 'varnish.objects', 'line']},
-          'objects_per_objhead': 
-             {'lines': [['obj_per_objhead', 'per_objhead', 'absolute', 1, 100]],
-              'options': [None, 'Objects per objecthead', 'units', 'Extra charts', 'varnish.objects_per_objhead', 'line']},
-          'request_rate': 
-             {'lines': [['sess_conn_rr', None, 'incremental', 1, 1],
-                       ['client_req', None, 'incremental', 1, 1],
-                       ['cache_hit', None, 'incremental', 1, 1],
-                       ['cache_hitpass', None, 'incremental', 1, 1],
-                       ['cache_miss', None, 'incremental', 1, 1],
-                       ['backend_conn', None, 'incremental', 1, 1],
-                       ['backend_unhealthy', None, 'incremental', 1, 1],
-                       ['s_pipe', None, 'incremental', 1, 1],
-                       ['s_pass', None, 'incremental', 1, 1]],
-              'options': [None, 'Request rates', 'units', 'Varnish statistics', 'varnish.request_rate', 'line']},
           'session': 
-             {'lines': [['sess_conn', 'conn', 'incremental', 1, 1],
-                       ['sess_drop', 'drop', 'incremental', 1, 1],
-                       ['sess_fail', 'fail', 'incremental', 1, 1],
-                       ['sess_pipe_overflow', 'pipe_overflow', 'incremental', 1, 1],
-                       ['sess_queued', 'queued', 'incremental', 1, 1],
-                       ['sess_dropped', 'dropped', 'incremental', 1, 1],
-                       ['sess_closed', 'closed', 'incremental', 1, 1],
-                       ['sess_pipeline', 'pipeline', 'incremental', 1, 1],
-                       ['sess_readahead' , 'readhead', 'incremental', 1, 1]],
-
-              'options': [None, 'Sessions', 'units', 'Varnish statistics', 'varnish.session', 'line']},
-          'session_herd': 
-             {'lines': [['sess_herd', None, 'incremental', 1, 1]],
-              'options': [None, 'Session herd', 'units', 'Extra charts', 'varnish.session_herd', 'line']},
-          'shm': 
-             {'lines': [['shm_flushes', 'flushes', 'incremental', 1, 1],
-                       ['shm_cont', 'cont', 'incremental', 1, 1],
-                       ['shm_cycles', 'cycles', 'incremental', 1, 1]],
-              'options': [None, 'SHM writes and records', 'units', 'Extra charts', 'varnish.shm', 'line']},
-          'shm_writes': 
-             {'lines': [['shm_records', 'records', 'incremental', 1, 1],
-                       ['shm_writes', 'writes', 'incremental', 1, 1]],
-              'options': [None, 'SHM writes and records', 'units', 'Extra charts', 'varnish.shm_writes', 'line']},
+             {'lines': [['sess_conn', 'sess_conn', 'incremental', 1, 1],
+                       ['client_req', 'client_requests', 'incremental', 1, 1],
+                       ['client_conn', 'client_conn', 'incremental', 1, 1],
+                       ['client_drop', 'client_drop', 'incremental', 1, 1],
+                       ['sess_dropped', 'sess_dropped', 'incremental', 1, 1]],
+              'options': [None, 'Sessions', 'units', 'Client metrics', 'varnish.session', 'line']},
           'threads': 
              {'lines': [['threads', None, 'absolute', 1, 1],
                        ['threads_created', 'created', 'incremental', 1, 1],
                        ['threads_failed', 'failed', 'incremental', 1, 1],
                        ['threads_limited', 'limited', 'incremental', 1, 1],
-                       ['threads_destroyed', 'destroyed', 'incremental', 1, 1]],
-              'options': [None, 'Thread status', 'units', 'Extra charts', 'varnish.threads', 'line']},
-          'transfer_rates': 
-             {'lines': [['s_resp_hdrbytes', 'header', 'incremental', 8, 1000],
-                       ['s_resp_bodybytes', 'body', 'incremental', -8, 1000]],
-              'options': [None, 'Transfer rates', 'kilobit/s', 'Varnish statistics', 'varnish.transfer_rates', 'area']},
+                       ['thread_queue_len', 'queue_len', 'incremental', 1, 1],
+                       ['sess_queued', 'sess_queued', 'incremental', 1, 1]],
+              'options': [None, 'Thread status', 'threads', 'Thread-related metrics', 'varnish.threads', 'line']},
           'uptime': 
              {'lines': [['uptime', None, 'absolute', 1, 1]],
-              'options': [None, 'Varnish uptime', 'seconds', 'Varnish statistics', 'varnish.uptime', 'line']},
-          'vcl': 
-             {'lines': [['n_backend', None, 'absolute', 1, 1],
-                       ['n_vcl', None, 'incremental', 1, 1],
-                       ['n_vcl_avail', None, 'incremental', 1, 1],
-                       ['n_vcl_discard', None, 'incremental', 1, 1]],
-              'options': [None, 'VCL', 'units', 'Extra charts', 'varnish.vcl', 'line']}}
-
-DIRECTORIES = ['/bin/', '/usr/bin/', '/sbin/', '/usr/sbin/']
+              'options': [None, 'Varnish uptime', 'seconds', 'Uptime', 'varnish.uptime', 'line']}
+}
 
 
 class Service(SimpleService):
     def __init__(self, configuration=None, name=None):
         SimpleService.__init__(self, configuration=configuration, name=name)
-        try:
-            self.varnish = [''.join([directory, 'varnishstat']) for directory in DIRECTORIES
-                         if is_executable(''.join([directory, 'varnishstat']), X_OK)][0]
-        except IndexError:
-            self.varnish = False
-        self.rgx_all = compile(r'([A-Z]+\.)([\d\w_.]+)\s+(\d+)')
+        self.varnish = self.find_binary('varnishstat')
+        self.rgx_all = compile(r'([A-Z]+\.)?([\d\w_.]+)\s+(\d+)')
         # Could be
         # VBE.boot.super_backend.pipe_hdrbyte (new)
         # or
         # VBE.default2(127.0.0.2,,81).bereq_bodybytes (old)
         # Regex result: [('super_backend', 'beresp_hdrbytes', '0'), ('super_backend', 'beresp_bodybytes', '0')]
         self.rgx_bck = (compile(r'VBE.([\d\w_.]+)\(.*?\).(beresp[\w_]+)\s+(\d+)'),
-                        compile(r'VBE.boot.([\w\d_]+).(beresp[\w_]+)\s+(\d+)'))
-        self.extra_charts = self.configuration.get('extra_charts', [])
+                        compile(r'VBE\.[\d\w-]+\.([\w\d_]+).(beresp[\w_]+)\s+(\d+)'))
         self.cache_prev = list()
 
     def check(self):
         # Cant start without 'varnishstat' command
         if not self.varnish:
-            self.error('\'varnishstat\' command was not found in %s or not executable by netdata' % DIRECTORIES)
+            self.error('Can\'t locate \'varnishstat\' binary or binary is not executable by netdata')
             return False
 
         # If command is present and we can execute it we need to make sure..
@@ -211,7 +109,7 @@ class Service(SimpleService):
         # 2. Output is parsable (list is not empty after regex findall)
         is_parsable = self.rgx_all.findall(reply)
         if not is_parsable:
-            self.error('Cant parse output (only varnish version 4+ supported)')
+            self.error('Cant parse output...')
             return False
 
         # We need to find the right regex for backend parse
@@ -220,12 +118,11 @@ class Service(SimpleService):
             self.rgx_bck = self.rgx_bck[0]
         else:
             self.backend_list = self.rgx_bck[1].findall(reply)[::2]
-            self.rgx_bck = self.rgx_back[1]
+            self.rgx_bck = self.rgx_bck[1]
 
         # We are about to start!
         self.create_charts()
 
-        self.info('Active charts: %s' % self.order)
         self.info('Plugin was started successfully')
         return True
      
@@ -240,7 +137,7 @@ class Service(SimpleService):
         if not raw_data:
             return None
 
-        return raw_data
+        return raw_data.decode()
 
     def _get_data(self):
         """
@@ -255,10 +152,10 @@ class Service(SimpleService):
             return None
 
         # 1. ALL data from 'varnishstat -1'. t - type(MAIN, MEMPOOL etc)
-        to_netdata = {k: int(v) for t, k, v in data_all}
+        to_netdata = dict([(k, int(v)) for t, k, v in data_all])
         
         # 2. ADD backend statistics
-        to_netdata.update({'_'.join([n, k]): int(v) for n, k, v in data_backend})
+        to_netdata.update(dict([('_'.join([n, k]), int(v)) for n, k, v in data_backend]))
 
         # 3. ADD additional keys to dict
         # 3.1 Cache hit/miss/hitpass OVERALL in percent
@@ -282,36 +179,32 @@ class Service(SimpleService):
 
         self.cache_prev = [to_netdata.get('cache_hit', 0), to_netdata.get('cache_miss', 0), to_netdata.get('cache_hitpass', 0)]
 
-        # 3.2 Copy random stuff to new keys (do we need this?)
-        to_netdata['obj_per_objhead'] = find_percent(to_netdata.get('n_object', 0),
-                                                     to_netdata.get('n_objecthead', 0), 100)
-        to_netdata['backend_conn_bt'] = to_netdata.get('backend_conn', 0)
-        to_netdata['sess_conn_rr'] = to_netdata.get('sess_conn', 0)
-        to_netdata['n_lru_nuked_e'] = to_netdata.get('n_lru_nuked', 0)
-
-        for elem in ['backend_busy', 'backend_unhealthy', 'esi_errors', 'esi_warnings', 'losthdr', 'sess_drop',
-                     'sess_fail', 'sess_pipe_overflow', 'threads_destroyed', 'threads_failed', 'threads_limited']:
-            to_netdata[''.join([elem, '_b'])] = to_netdata.get(elem, 0)
+        # 3.3 Problems summary chart
+        for elem in ['backend_busy', 'backend_unhealthy', 'esi_errors', 'esi_warnings', 'losthdr', 'sess_drop', 'sc_pipe_overflow',
+                     'sess_fail', 'sess_pipe_overflow', 'threads_destroyed', 'threads_failed', 'threads_limited', 'thread_queue_len']:
+            if to_netdata.get(elem) is not None:
+                to_netdata[''.join([elem, '_b'])] = to_netdata.get(elem)
 
         # Ready steady go!
         return to_netdata
 
     def create_charts(self):
         # If 'all_charts' is true...ALL charts are displayed. If no only default + 'extra_charts'
-        if self.configuration.get('all_charts'):
-            self.order = EXTRA_ORDER
-        else:
-            try:
-                extra_charts = list(filter(lambda chart: chart in EXTRA_ORDER, self.extra_charts.split()))
-            except (AttributeError, NameError, ValueError):
-                self.error('Extra charts disabled.')
-                extra_charts = []
+        #if self.configuration.get('all_charts'):
+        #    self.order = EXTRA_ORDER
+        #else:
+        #    try:
+        #        extra_charts = list(filter(lambda chart: chart in EXTRA_ORDER, self.extra_charts.split()))
+        #    except (AttributeError, NameError, ValueError):
+        #        self.error('Extra charts disabled.')
+        #        extra_charts = []
     
-            self.order = ORDER[:]
-            self.order.extend(extra_charts)
+        self.order = ORDER[:]
+        #self.order.extend(extra_charts)
 
         # Create static charts
-        self.definitions = {chart: values for chart, values in CHARTS.items() if chart in self.order}
+        #self.definitions = {chart: values for chart, values in CHARTS.items() if chart in self.order}
+        self.definitions = CHARTS
  
         # Create dynamic backend charts
         if self.backend_list: