Ema has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/330668 )

Change subject: varnishstatsd: port to cachestats.CacheStatsSender
......................................................................


varnishstatsd: port to cachestats.CacheStatsSender

Port varnishstatsd to cachestats.CacheStatsSender. Drop support for
specifying the varnish instance name given that we only monitor varnish
backends.

Bug: T151643
Change-Id: Icc1478d720dee461daf6418e8d5707e92735019c
---
M modules/varnish/files/varnishstatsd
1 file changed, 39 insertions(+), 117 deletions(-)

Approvals:
  Ema: Verified; Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/varnish/files/varnishstatsd 
b/modules/varnish/files/varnishstatsd
index 41965a2..6778c2d 100755
--- a/modules/varnish/files/varnishstatsd
+++ b/modules/varnish/files/varnishstatsd
@@ -5,17 +5,15 @@
   ~~~~~~~~~~~~~
   Report backend response times and request counts aggregated by status.
 
-  Usage: varnishstatsd [--varnish-name NAME] [--statsd-server SERVER]
-                       [--key-prefix PREFIX]
+  Usage: varnishstatsd [--statsd-server SERVER] [--key-prefix PREFIX]
 
-    --varnish-name NAME     varnish name
     --statsd-server SERVER  statsd server
     --key-prefix PREFIX     metric key prefix
 
   If no statsd server is specified, prints stats to stdout instead.
 
   Copyright 2015-2016 Ori Livneh <[email protected]>
-                 2016 Emanuele Rocca <[email protected]>
+            2016-2017 Emanuele Rocca <[email protected]>
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -30,134 +28,58 @@
   limitations under the License.
 
 """
-import argparse
-import collections
 import io
-import socket
-import urlparse
-from varnishlog import varnishlog
+import sys
 
+from cachestats import CacheStatsSender
 
 METRIC_FORMAT = (
-    '%(key_prefix)s%(backend)s.%(method)s:%(ttfb)d|ms\n'
-    '%(key_prefix)s%(backend)s.%(status)s:1|c\n'
+    '%(key_prefix)s.%(backend)s.%(method)s:%(ttfb)d|ms\n'
+    '%(key_prefix)s.%(backend)s.%(status)sxx:1|c\n'
 )
 
 UDP_MTU_BYTES = 1472
 
-vsl_args = [
-    # Skip PURGE requests
-    ('q', 'ReqMethod ne "PURGE"'),
-    # Backend HTTP response status code (eg: 200, 404)
-    ('i', 'BerespStatus'),
-    # Backend HTTP request method (eg: GET, POST)
-    ('i', 'BereqMethod'),
-    # The following two tags are logged when a new backend connection is opened
-    # or put up for reuse by a later connection. We need those to get the
-    # backend name
-    ('i', 'BackendOpen'),
-    ('i', 'BackendReuse'),
-    # Timestamp to compute TTFB (BerespBody)
-    ('i', 'Timestamp'),
-]
 
-sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+class StatsdStatsSender(CacheStatsSender):
+    cmd = ['/usr/bin/varnishncsa', '-b',
+           '-q', 'BereqMethod ne "PURGE"',
+           '-F', '%m\t%s\t%{VSL:BackendOpen[2]}x\t%{Varnish:time_firstbyte}x']
 
+    description = 'Varnish backend response time metric logger'
+    key_prefix = 'varnish.backends'
 
-def parse_statsd_server_string(server_string):
-    parsed = urlparse.urlparse('//' + server_string)
-    return parsed.hostname, parsed.port or 8125
+    def __init__(self, argument_list):
+        super(StatsdStatsSender, self).__init__(argument_list)
+        self.buf = io.BytesIO()
 
+    def handle_record(self, record):
+        method, status_code, backend, ttfb = record.split('\t')
+        ttfb = round(1000 * float(ttfb))
+        backend = backend.split('.')[-1]
 
-def parse_key_prefix(key_prefix):
-    return key_prefix.strip('.') + '.'
-
-
-ap = argparse.ArgumentParser(
-    description='Varnish backend response time metric logger',
-    epilog='If no statsd server is specified, prints stats to stdout instead.'
-)
-ap.add_argument('--varnish-name', help='varnish name')
-ap.add_argument('--statsd-server', help='statsd server',
-                type=parse_statsd_server_string, default=None)
-ap.add_argument('--key-prefix', help='metric key prefix',
-                default='varnish.backends',
-                type=parse_key_prefix)
-args = ap.parse_args()
-
-if args.varnish_name:
-    vsl_args.append(('n', args.varnish_name))
-
-# Maximum number of log records to keep in memory.
-MAX_BACKLOG = 100
-
-# Map of transaction ID: request method ('GET', 'POST', etc.)
-tids = collections.OrderedDict()
-
-# Map of backend XID: transaction ID
-xids = collections.OrderedDict()
-
-# Map of transaction ID: backend name
-backends = collections.OrderedDict()
-
-# Map of transaction ID: response status code (200, 404, etc.)
-statuses = collections.OrderedDict()
-
-buf = io.BytesIO()
-
-
-def vsl_callback(transaction_id, tag, record, remote_party):
-    global buf
-
-    if tag in ("BackendOpen", "BackendReuse"):
-        # Associate the transaction ID with the backend name.
-        backend_fullname = record.split()[1]
-        backend_name = backend_fullname.split('.')[-1]
-
-        backends[transaction_id] = backend_name
-        if len(backends) > MAX_BACKLOG:
-            backends.popitem(last=False)
-
-    elif tag == "BereqMethod":
-        # Associate the transaction ID with the request method.
-        tids[transaction_id] = record
-        if len(tids) > MAX_BACKLOG:
-            tids.popitem(last=False)
-
-    elif tag == "BerespStatus":
-        # Associate the transaction ID with the response status code.
-        if record[0] in '12345':
-            statuses[transaction_id] = record[0] + 'xx'
-        if len(statuses) > MAX_BACKLOG:
-            statuses.popitem(last=False)
-
-    # For our purposes this is like ReqEnd
-    elif tag == "Timestamp" and record.startswith('BerespBody:'):
-        # Collate data and emit metric.
-        parts = record.split()
-
-        try:
-            fields = {
-                'key_prefix': args.key_prefix,
-                'method': tids.pop(transaction_id),
-                'backend': backends.pop(transaction_id),
-                'status': statuses.pop(transaction_id),
-                'ttfb': round(1000 * float(parts[2])),
-            }
-        except KeyError:
-            return 0
+        fields = {
+            'key_prefix': self.args.key_prefix,
+            'method': method,
+            'backend': backend,
+            'status': status_code[0],
+            'ttfb': ttfb
+        }
 
         metric_string = (METRIC_FORMAT % fields).encode('utf-8')
-        if buf.tell() + len(metric_string) >= UDP_MTU_BYTES:
-            buf.seek(io.SEEK_SET)
-            if args.statsd_server:
-                sock.sendto(buf.read(), args.statsd_server)
-            else:
-                print(buf.read().decode('utf-8', errors='replace').rstrip())
-            buf = io.BytesIO()
-        buf.write(metric_string)
+        if self.buf.tell() + len(metric_string) >= UDP_MTU_BYTES:
+            self.buf.seek(io.SEEK_SET)
 
-    return 0
+            data = self.buf.read()
+
+            if self.args.statsd_server:
+                self.sock.sendto(data, self.args.statsd_server)
+            else:
+                print(data.decode('utf-8', errors='replace').rstrip())
+
+            self.buf = io.BytesIO()
+
+        self.buf.write(metric_string)
 
 if __name__ == "__main__":
-    varnishlog(vsl_args, vsl_callback)
+    StatsdStatsSender(sys.argv[1:]).main()

-- 
To view, visit https://gerrit.wikimedia.org/r/330668
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Icc1478d720dee461daf6418e8d5707e92735019c
Gerrit-PatchSet: 4
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Ema <[email protected]>
Gerrit-Reviewer: BBlack <[email protected]>
Gerrit-Reviewer: Ema <[email protected]>
Gerrit-Reviewer: Volans <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to