]> arthur.barton.de Git - netdata.git/commitdiff
Improve phpfpm module.
authorClint Armstrong <clint@clintarmstrong.net>
Wed, 21 Sep 2016 15:42:17 +0000 (11:42 -0400)
committerClint Armstrong <clint@clintarmstrong.net>
Wed, 21 Sep 2016 15:44:50 +0000 (11:44 -0400)
* Get the fpm stats in json format for easy parsing
* Get stats for each process and track maximums and averages for each.

conf.d/python.d/phpfpm.conf
python.d/phpfpm.chart.py

index 06d2367aec536e1b97edfdcff044044e05012c10..f5d067cc7dff21fbc8feaa80ca27f5ff93f1cc2f 100644 (file)
@@ -57,6 +57,7 @@
 # Additionally to the above, PHP-FPM also supports the following:
 #
 #     url: 'URL'       # the URL to fetch nginx's status stats
+#                      # Be sure and include ?full&status at the end of the url
 #
 # if the URL is password protected, the following are supported:
 #
 
 localhost:
   name : 'local'
-  url  : "http://localhost/status"
+  url  : "http://localhost/status?full&json"
 
 localipv4:
   name : 'local'
-  url  : "http://127.0.0.1/status"
+  url  : "http://127.0.0.1/status?full&json"
 
 localipv6:
   name : 'local'
-  url  : "http://::1/status"
+  url  : "http://::1/status?full&json"
 
index d1791d42eddebb021262e37a4767637329bc3486..7f2da9ccb7d08bc0bf5ee859324f30ba112e4c23 100755 (executable)
@@ -3,6 +3,7 @@
 # Author: Pawel Krupa (paulfantom)
 
 from base import UrlService
+import json
 
 # default module values (can be overridden per job in `config`)
 # update_every = 2
@@ -18,7 +19,7 @@ retries = 60
 # }}
 
 # charts order (can be overridden if you want less charts, or different order)
-ORDER = ['connections', 'requests', 'performance']
+ORDER = ['connections', 'requests', 'performance', 'request_duration', 'request_cpu', 'request_mem']
 
 CHARTS = {
     'connections': {
@@ -38,6 +39,24 @@ CHARTS = {
         'lines': [
             ["reached", 'max children reached'],
             ["slow", 'slow requests']
+        ]},
+    'request_duration': {
+        'options': [None, 'PHP-FPM Request Duration', 'milliseconds', 'phpfpm', 'phpfpm.request_duration', 'line'],
+        'lines': [
+            ["maxReqDur", 'max request duration'],
+            ["avgReqDur", 'average request duration']
+        ]},
+    'request_cpu': {
+        'options': [None, 'PHP-FPM Request CPU', 'percent', 'phpfpm', 'phpfpm.request_cpu', 'line'],
+        'lines': [
+            ["maxReqCPU", 'max request cpu'],
+            ["avgReqCPU", 'average request cpu']
+        ]},
+    'request_mem': {
+        'options': [None, 'PHP-FPM Request Memory', 'kilobytes', 'phpfpm', 'phpfpm.request_mem', 'line'],
+        'lines': [
+            ["maxReqMem", 'max request memory'],
+            ["avgReqMem", 'average request memory']
         ]}
 }
 
@@ -46,7 +65,7 @@ class Service(UrlService):
     def __init__(self, configuration=None, name=None):
         UrlService.__init__(self, configuration=configuration, name=name)
         if len(self.url) == 0:
-            self.url = "http://localhost/status"
+            self.url = "http://localhost/status?full&json"
         self.order = ORDER
         self.definitions = CHARTS
         self.assignment = {"active processes": 'active',
@@ -55,6 +74,9 @@ class Service(UrlService):
                            "accepted conn": 'requests',
                            "max children reached": 'reached',
                            "slow requests": 'slow'}
+        self.proc_assignment = {"request duration": 'ReqDur',
+                                "last request cpu": 'ReqCPU',
+                                "last request memory": 'ReqMem'}
 
     def _get_data(self):
         """
@@ -62,17 +84,34 @@ class Service(UrlService):
         :return: dict
         """
         try:
-            raw = self._get_raw_data().split('\n')
+            raw = self._get_raw_data()
         except AttributeError:
             return None
-        data = {}
-        for row in raw:
-            tmp = row.split(":")
-            if str(tmp[0]) in self.assignment:
-                try:
-                    data[self.assignment[tmp[0]]] = int(tmp[1])
-                except (IndexError, ValueError):
-                    pass
+
+        try:
+            raw_json = json.loads(raw)
+        except ValueError:
+            return None
+
+        data = {self.assignment[k]: v for k, v in raw_json.items() if k in self.assignment}
+
+        c = 0
+        for proc in raw_json['processes']:
+            if proc['state'] != 'Idle':
+                continue
+            c += 1
+            for k, v in self.proc_assignment.items():
+                d = proc[k]
+                if v == 'ReqDur':
+                    d = d/1000
+                if v == 'ReqMem':
+                    d = d/1024
+                if 'max' + v not in data or data['max' + v] < d:
+                    data['max' + v] = d
+                if 'avg' + v not in data:
+                    data['avg' + v] = 0
+                data['avg' + v] = (data['avg' + v] + d) / c
+
         if len(data) == 0:
             return None
         return data