Skip to content

Commit 73309bd

Browse files
authored
Merge pull request #18 from elcamlost/ir-ce-rework-moschlar
Migrate to plugin api 2.0
2 parents 0d51b85 + 19eb0d0 commit 73309bd

8 files changed

Lines changed: 259 additions & 136 deletions

File tree

Makefile

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
PKG = php_fpm
22
CONTAINER = checkmk-${PKG}
3-
IMAGE = checkmk/check-mk-raw:2.0.0p21
4-
DIRS = $(shell ls -d ${PWD}/php-fpm/*/)
5-
MKP = $(shell docker exec -u cmk checkmk-php_fpm bash -c "ls -1 ~/*mkp")
3+
IMAGE = checkmk/check-mk-raw:2.3.0p23
4+
DIRS = agents checkman web
5+
MKP = $(shell docker exec -u cmk checkmk-php_fpm bash -c "ls -1 /omd/sites/cmk/var/check_mk/packages_local/*mkp")
66

77
.DEFAULT: php_fpm
88
.PHONY: _docker_run _docker_stop _copy_files _pack _copy_mkp php_fpm
@@ -15,13 +15,19 @@ _docker_stop:
1515
docker stop -t 0 checkmk-${PKG}
1616

1717
_copy_files:
18-
for dir in $$(ls -d $$PWD/php-fpm/*/); do docker cp $$dir ${CONTAINER}:/omd/sites/cmk/local/share/check_mk/; done
18+
for dir in ${DIRS}; do \
19+
docker cp php-fpm/$$dir ${CONTAINER}:/omd/sites/cmk/local/share/check_mk/; \
20+
docker exec ${CONTAINER} chown -R cmk /omd/sites/cmk/local/share/check_mk/$$dir; \
21+
done
22+
docker cp php-fpm/agent_based ${CONTAINER}:/omd/sites/cmk/local/lib/check_mk/base/plugins/
23+
docker exec ${CONTAINER} chown -R cmk /omd/sites/cmk/local/lib/check_mk/base/plugins/agent_based
1924

2025
_copy_info:
2126
docker cp ${PWD}/php-fpm/info ${CONTAINER}:/omd/sites/cmk/var/check_mk/packages/${PKG}
27+
docker exec ${CONTAINER} chown cmk /omd/sites/cmk/var/check_mk/packages/${PKG}
2228

2329
_pack:
24-
docker exec -u cmk ${CONTAINER} bash -l -c "cd ~ && mkp pack ${PKG}"
30+
docker exec -u cmk ${CONTAINER} bash -l -c "cd /omd/sites/cmk/var/check_mk/packages/ && mkp package ${PKG}"
2531

2632
_copy_mkp:
2733
docker cp ${CONTAINER}:${MKP} ./

php-fpm/Changes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2.0 2025-05-15
2+
- migrate to plugin 2.0 api (Thx @moschlar)
3+
- add levels (Thx @moschlar)
4+
15
1.0 2022-03-04
26
- add autodiscovery
37
- fix cmk2 compatibility
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8; py-indent-offset: 4 -*-
3+
# +------------------------------------------------------------------+
4+
# | ____ _ _ __ __ _ __ |
5+
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
6+
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7+
# | | |___| | | | __/ (__| < | | | | . \ |
8+
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9+
# | |
10+
# | Copyright Mathias Kettner 2016 mk@mathias-kettner.de |
11+
# +------------------------------------------------------------------+
12+
#
13+
# This file is part of Check_MK.
14+
# The official homepage is at http://mathias-kettner.de/check_mk.
15+
#
16+
# check_mk is free software; you can redistribute it and/or modify it
17+
# under the terms of the GNU General Public License as published by
18+
# the Free Software Foundation in version 2. check_mk is distributed
19+
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20+
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21+
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
22+
# ails. You should have received a copy of the GNU General Public
23+
# License along with GNU Make; see the file COPYING. If not, write
24+
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25+
# Boston, MA 02110-1301 USA.
26+
27+
# <<<php_fpm_pools>>>
28+
# www dynamic active_processes 1
29+
# www dynamic accepted_conn 726
30+
# www dynamic listen_queue 0
31+
# www dynamic start_since 79602
32+
# www dynamic idle_processes 1
33+
# www dynamic start_time 1545257568
34+
# www dynamic slow_requests 0
35+
# www dynamic max_active_processes 2
36+
# www dynamic max_children_reached 0
37+
# www dynamic max_listen_queue 0
38+
# www dynamic total_processes 2
39+
40+
41+
from typing import Any, Mapping
42+
from .agent_based_api.v1.type_defs import CheckResult, DiscoveryResult, StringTable
43+
44+
import time
45+
46+
from cmk.base.plugins.agent_based.agent_based_api.v1 import (
47+
check_levels,
48+
get_rate,
49+
get_value_store,
50+
GetRateError,
51+
register,
52+
render,
53+
Service,
54+
)
55+
56+
57+
Section = Mapping[str, Any]
58+
59+
60+
def parse_php_fpm_pools(string_table: StringTable) -> Section:
61+
data = {}
62+
for line in string_table:
63+
if len(line) != 4:
64+
continue # Skip unexpected lines
65+
pool_name, pm_type, metric, value = line
66+
item = '%s [%s]' % (pool_name, pm_type)
67+
if item not in data:
68+
data[item] = {}
69+
70+
data[item][metric] = int(value)
71+
72+
return data
73+
74+
75+
register.agent_section(
76+
name='php_fpm_pools',
77+
parse_function=parse_php_fpm_pools,
78+
)
79+
80+
81+
def discover_php_fpm_pools(section: Section) -> DiscoveryResult:
82+
for item in section.keys():
83+
yield Service(item=item)
84+
85+
86+
def check_php_fpm_pools(
87+
item: str,
88+
params: Mapping[str, Any],
89+
section: Section,
90+
) -> CheckResult:
91+
if item not in section:
92+
return
93+
94+
if params is None:
95+
params = {}
96+
97+
data = dict(section[item])
98+
99+
lower_perfkeys = ['idle_processes']
100+
upper_perfkeys = [
101+
'active_processes', 'max_active_processes', 'max_children_reached',
102+
'slow_requests', 'listen_queue', 'max_listen_queue',
103+
]
104+
perfkeys = lower_perfkeys + upper_perfkeys
105+
106+
# Add some more values, derived from the raw ones...
107+
this_time = int(time.time())
108+
for key in ['accepted_conn', 'max_children_reached', 'slow_requests']:
109+
try:
110+
per_sec = get_rate(
111+
get_value_store(),
112+
"php_fpm_status.%s" % key,
113+
this_time,
114+
data[key],
115+
raise_overflow=True
116+
)
117+
except GetRateError:
118+
pass
119+
else:
120+
data['%s_per_sec' % key] = per_sec
121+
perfkeys.append('%s_per_sec' % key)
122+
123+
for key in perfkeys:
124+
if key in lower_perfkeys:
125+
levels_lower = params.get(key)
126+
levels_upper = None
127+
else:
128+
levels_lower = None
129+
levels_upper = params.get(key)
130+
yield from check_levels(
131+
value=data[key],
132+
metric_name=key,
133+
levels_lower=levels_lower,
134+
levels_upper=levels_upper,
135+
label=key.replace('_', ' ').title(),
136+
render_func=(
137+
render.timespan if key == 'start_since'
138+
else (lambda x: "%0.2f/s" % x) if key.endswith("_per_sec")
139+
else (lambda x: "%d" % x)
140+
),
141+
notice_only=key not in (
142+
'active_processes',
143+
'idle_processes',
144+
'listen_queue',
145+
'start_since',
146+
'accepted_conn_per_sec',
147+
),
148+
)
149+
150+
151+
register.check_plugin(
152+
name='php_fpm_pools',
153+
service_name='PHP-FPM Pool %s Status',
154+
discovery_function=discover_php_fpm_pools,
155+
check_function=check_php_fpm_pools,
156+
check_ruleset_name='php_fpm_pools',
157+
check_default_parameters={},
158+
)

php-fpm/agents/plugins/php_fpm_pools

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class FCGIStatusClient:
130130

131131
def print_status(self):
132132
if hasattr(self, 'status_data'):
133-
data = json.loads(self.status_data.split(b"\r\n\r\n", 1)[1])
133+
data = json.loads(self.status_data.split(b"\r\n\r\n", 1)[1].decode('ascii'))
134134
pool_name = data.pop('pool', None)
135135
pm_type = data.pop('process manager', None)
136136
for key in data:
@@ -156,18 +156,19 @@ def parse_fpm_config(f):
156156
"""
157157
Parse php-fpm config, yielding dicts with status socket info
158158
"""
159-
config = configparser.ConfigParser()
159+
config = configparser.ConfigParser(strict=False)
160160
config.read_file(f)
161+
strip_from_listen = "'\""
161162

162163
for name in config.sections():
163164
section = config[name]
164165
if 'listen' not in section:
165166
continue
166167

167-
listen = section['listen']
168+
listen = section['listen'].strip(strip_from_listen)
168169
if listen and not listen.startswith('/'):
169170
if 'prefix' in section:
170-
listen = os.path.join(section['prefix'], listen)
171+
listen = os.path.join(section['prefix'].strip(strip_from_listen), listen)
171172
else:
172173
# we cannot infer the relative listen anchor
173174
continue
@@ -177,7 +178,11 @@ def parse_fpm_config(f):
177178

178179
yield {
179180
"socket": listen,
180-
"path": section.get('pm.status_path'),
181+
"path": (
182+
section['pm.status_path'].strip(strip_from_listen)
183+
if 'pm.status_path' in section
184+
else None
185+
),
181186
}
182187

183188

php-fpm/checkman/php_fpm_pools

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ description:
1212
Please note that the information provided only affect the configured pools within the server.
1313

1414
By default the check is always OK and outputs performance indicators including graphs.
15+
However, levels can be configured via ruleset for many of these indicators.
1516

1617
First you need to set up 'pm.status_path' in pool settings to make it accessible, at least from localhost.
1718
We recommend to do it like follows.

php-fpm/checks/php_fpm_pools

Lines changed: 0 additions & 114 deletions
This file was deleted.

php-fpm/info

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{'author': 'Ilya Rassadin elcamlost at gmail dot com',
22
'description': 'This check monitors performance indicators of php-fpm pools. See changes here https://raw.githubusercontent.com/elcamlost/checkmk-php-fpm-plugin/master/php-fpm/Changes',
33
'download_url': 'https://github.com/elcamlost/checkmk-php-fpm-plugin',
4-
'files': {'agents': ['plugins/php_fpm_pools'],
4+
'files': {'agent_based': ['php_fpm_pools.py'],
5+
'agents': ['plugins/php_fpm_pools'],
56
'alert_handlers': [],
67
'bin': [],
78
'checkman': ['php_fpm_pools'],
8-
'checks': ['php_fpm_pools'],
99
'doc': [],
1010
'inventory': [],
1111
'lib': [],
@@ -18,7 +18,7 @@
1818
'name': 'php_fpm',
1919
'num_files': 5,
2020
'title': 'PHP-FPM monitoring',
21-
'version': '1.0',
21+
'version': '2.0.0',
2222
'version.min_required': '2.0.0p1',
23-
'version.packaged': '2.0.0p21',
23+
'version.packaged': '2.3.0p23',
2424
'version.usable_until': None}

0 commit comments

Comments
 (0)