Created
December 19, 2016 21:29
-
-
Save remh/7d56fa2eea1b457cd83e1e5e8d86115b to your computer and use it in GitHub Desktop.
php fpm check with SSL disabled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# (C) Datadog, Inc. 2010-2016 | |
# All rights reserved | |
# Licensed under Simplified BSD License (see LICENSE) | |
# 3p | |
import requests | |
# project | |
from checks import AgentCheck | |
from util import headers | |
class PHPFPMCheck(AgentCheck): | |
""" | |
Tracks basic php-fpm metrics via the status module | |
Requires php-fpm pools to have the status option. | |
See http://www.php.net/manual/de/install.fpm.configuration.php#pm.status-path for more details | |
""" | |
SERVICE_CHECK_NAME = 'php_fpm.can_ping' | |
GAUGES = { | |
'listen queue': 'php_fpm.listen_queue.size', | |
'idle processes': 'php_fpm.processes.idle', | |
'active processes': 'php_fpm.processes.active', | |
'total processes': 'php_fpm.processes.total', | |
} | |
MONOTONIC_COUNTS = { | |
'accepted conn': 'php_fpm.requests.accepted', | |
'max children reached': 'php_fpm.processes.max_reached', | |
'slow requests': 'php_fpm.requests.slow', | |
} | |
def check(self, instance): | |
status_url = instance.get('status_url') | |
ping_url = instance.get('ping_url') | |
ping_reply = instance.get('ping_reply') | |
auth = None | |
user = instance.get('user') | |
password = instance.get('password') | |
tags = instance.get('tags', []) | |
http_host = instance.get('http_host') | |
if user and password: | |
auth = (user, password) | |
if status_url is None and ping_url is None: | |
raise Exception("No status_url or ping_url specified for this instance") | |
pool = None | |
status_exception = None | |
if status_url is not None: | |
try: | |
pool = self._process_status(status_url, auth, tags, http_host) | |
except Exception as e: | |
status_exception = e | |
pass | |
if ping_url is not None: | |
self._process_ping(ping_url, ping_reply, auth, tags, pool, http_host) | |
# pylint doesn't understand that we are raising this only if it's here | |
if status_exception is not None: | |
raise status_exception # pylint: disable=E0702 | |
def _process_status(self, status_url, auth, tags, http_host): | |
data = {} | |
try: | |
# TODO: adding the 'full' parameter gets you per-process detailed | |
# informations, which could be nice to parse and output as metrics | |
resp = requests.get(status_url, auth=auth, | |
headers=headers(self.agentConfig, http_host=http_host), | |
params={'json': True}, verify=False) | |
resp.raise_for_status() | |
data = resp.json() | |
except Exception as e: | |
self.log.error("Failed to get metrics from {0}.\nError {1}".format(status_url, e)) | |
raise | |
pool_name = data.get('pool', 'default') | |
metric_tags = tags + ["pool:{0}".format(pool_name)] | |
for key, mname in self.GAUGES.iteritems(): | |
if key not in data: | |
self.log.warn("Gauge metric {0} is missing from FPM status".format(key)) | |
continue | |
self.gauge(mname, int(data[key]), tags=metric_tags) | |
for key, mname in self.MONOTONIC_COUNTS.iteritems(): | |
if key not in data: | |
self.log.warn("Counter metric {0} is missing from FPM status".format(key)) | |
continue | |
self.monotonic_count(mname, int(data[key]), tags=metric_tags) | |
# return pool, to tag the service check with it if we have one | |
return pool_name | |
def _process_ping(self, ping_url, ping_reply, auth, tags, pool_name, http_host): | |
if ping_reply is None: | |
ping_reply = 'pong' | |
sc_tags = ["ping_url:{0}".format(ping_url)] | |
try: | |
# TODO: adding the 'full' parameter gets you per-process detailed | |
# informations, which could be nice to parse and output as metrics | |
resp = requests.get(ping_url, auth=auth, | |
headers=headers(self.agentConfig, http_host=http_host), verify=False) | |
resp.raise_for_status() | |
if ping_reply not in resp.text: | |
raise Exception("Received unexpected reply to ping {0}".format(resp.text)) | |
except Exception as e: | |
self.log.error("Failed to ping FPM pool {0} on URL {1}." | |
"\nError {2}".format(pool_name, ping_url, e)) | |
self.service_check(self.SERVICE_CHECK_NAME, | |
AgentCheck.CRITICAL, tags=sc_tags, message=str(e)) | |
else: | |
self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK, tags=sc_tags) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment