Yuvipanda has submitted this change and it was merged.

Change subject: tools: Track per tool request stats in graphite
......................................................................


tools: Track per tool request stats in graphite

Bug: T69880
Change-Id: Ie7f35a8946a4ff7cce93396964d2c2042d8017b6
---
M modules/dynamicproxy/manifests/init.pp
A modules/toollabs/files/toolsweblogster.py
M modules/toollabs/manifests/proxy.pp
3 files changed, 102 insertions(+), 16 deletions(-)

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



diff --git a/modules/dynamicproxy/manifests/init.pp 
b/modules/dynamicproxy/manifests/init.pp
index 318b1b3..7f5b41e 100644
--- a/modules/dynamicproxy/manifests/init.pp
+++ b/modules/dynamicproxy/manifests/init.pp
@@ -174,20 +174,4 @@
 
     # Also monitor local redis
     include ::redis::client::python
-
-    $graphite_metric_prefix = "${::labsproject}.${::hostname}.reqstats"
-
-    logster::job { 'proxy-requests':
-        minute          => '*/1',
-        parser          => 'LineCountLogster', # Nothing more specific yet
-        logfile         => '/var/log/nginx/access.log',
-        logster_options => "-o statsd 
--statsd-host=labmon1001.eqiad.wmnet:8125 
--metric-prefix=${graphite_metric_prefix}.all",
-    }
-
-    logster::job { 'proxy-errors':
-        minute          => '*/1',
-        parser          => 'LineCountLogster', # Nothing more specific yet
-        logfile         => '/var/log/nginx/error.log',
-        logster_options => "-o statsd 
--statsd-host=labmon1001.eqiad.wmnet:8125 
--metric-prefix=${graphite_metric_prefix}.errors",
-    }
 }
diff --git a/modules/toollabs/files/toolsweblogster.py 
b/modules/toollabs/files/toolsweblogster.py
new file mode 100644
index 0000000..0d470c3
--- /dev/null
+++ b/modules/toollabs/files/toolsweblogster.py
@@ -0,0 +1,84 @@
+"""
+A logster parser that tails nginx log files to count responses grouped by 
first segment of urls
+
+Examples:
+    1. tools.wmflabs.org/geohack/geohack.php?x=50&y=50
+        first segment: geohack
+    2. tools.wmflabs.org/testtool
+        firstsegment: testtool
+    3. tools.wmflabs.org/
+        firstsegment: /
+
+It sends metrics of the form:
+    raw.{firstsegment}.status.{status} -> For statuses!
+    raw.{firstsegment}.httpversion.{version} -> For HTTP versions used
+"""
+import re
+
+from logster.logster_helper import MetricObject, LogsterParser
+from logster.logster_helper import LogsterParsingException
+
+
+class UrlFirstSegmentLogster(LogsterParser):
+
+    def __init__(self, option_string=None):
+        '''Initialize any data structures or variables needed for keeping track
+        of the tasty bits we find in the log we are parsing.'''
+        self.status_stats = {}
+        self.httpver_stats = {}
+        # Regular expression for matching lines we are interested in, and 
capturing
+        # fields from the line (in this case, http_status_code, size and 
squid_code).
+        self.reg = re.compile(r"""
+        ^(?P<ip>(\d{1,3}\.?){4})
+        \s-\s-\s
+        \[(?P<timestamp>.*)\]\s
+        "(?P<method>\w+)\s
+        /(?P<firstsegment>[^/?]+)(?P<url>/.*?) HTTP/(?P<httpversion>\d.\d)"\s
+        (?P<status>\d{3})\s
+        (?P<len>\d+)\s
+        "(?P<referer>.*?)"\s
+        "(?P<useragent>.*?)"
+        """, re.X)
+
+    def parse_line(self, line):
+        '''This function should digest the contents of one line at a time, 
updating
+        object's state variables. Takes a single argument, the line to be 
parsed.'''
+
+        # Apply regular expression to each line and extract interesting bits.
+        regMatch = self.reg.match(line)
+
+        if regMatch:
+            bits = regMatch.groupdict()
+            firstsegment = bits['firstsegment']
+            status = bits['status']
+            httpversion = bits['httpversion'].replace('.', '_')
+
+            statuses = self.status_stats.get(firstsegment, {status: 0})
+            statuses[status] = statuses.get(status, 0) + 1
+            self.status_stats[firstsegment] = statuses
+
+            httpversions = self.httpver_stats.get(firstsegment, {httpversion: 
0})
+            httpversions[httpversion] = httpversions.get(httpversion, 0) + 1
+            self.httpver_stats[firstsegment] = httpversions
+        else:
+            raise LogsterParsingException("regmatch failed to match")
+
+    def get_state(self, duration):
+        '''Run any necessary calculations on the data collected from the logs
+        and return a list of metric objects.'''
+
+        metrics = []
+        for firstsegment, statuses in self.status_stats.items():
+            for status, count in statuses.items():
+                metric_name = 'raw.{firstsegment}.status.{status}'.format(
+                    firstsegment=firstsegment, status=status
+                )
+                metrics.append(MetricObject(metric_name, count, 'Responses'))
+        for firstsegment, httpversions in self.httpver_stats.items():
+            for httpver, count in httpversions.items():
+                metric_name = 'raw.{firstsegment}.httpver.{httpver}'.format(
+                    firstsegment=firstsegment, httpver=httpver
+                )
+                metrics.append(MetricObject(metric_name, count, 'Responses'))
+
+        return metrics
diff --git a/modules/toollabs/manifests/proxy.pp 
b/modules/toollabs/manifests/proxy.pp
index 8f032c2..ede3fb3 100644
--- a/modules/toollabs/manifests/proxy.pp
+++ b/modules/toollabs/manifests/proxy.pp
@@ -96,4 +96,22 @@
     }
 
     require_package('goaccess')  # webserver statistics, T121233
+
+    $graphite_metric_prefix = "${::labsproject}.reqstats"
+
+    file { '/usr/local/lib/python2.7/dist-packages/toolsweblogster.py':
+        source => 'puppet:///modules/toollabs/toolsweblogster.py',
+        owner  => 'root',
+        group  => 'root',
+        mode   => '0555',
+    }
+
+    logster::job { 'proxy-requests':
+        minute          => '*/1',
+        parser          => 'toolsweblogster.UrlFirstSegmentLogster', # Nothing 
more specific yet
+        logfile         => '/var/log/nginx/access.log',
+        logster_options => "-o statsd 
--statsd-host=labmon1001.eqiad.wmnet:8125 
--metric-prefix=${graphite_metric_prefix}.",
+        require         => 
File['/usr/local/lib/python2.7/dist-packages/toolsweblogster.py'],
+    }
+
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie7f35a8946a4ff7cce93396964d2c2042d8017b6
Gerrit-PatchSet: 3
Gerrit-Project: operations/puppet
Gerrit-Branch: production
Gerrit-Owner: Yuvipanda <yuvipa...@wikimedia.org>
Gerrit-Reviewer: Yuvipanda <yuvipa...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to