2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
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 # tails. 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.
28 def apache_status_check_params(value
, params
, op_txt
):
29 def apply_operator(val
, param
, op_txt
):
32 elif op_txt
== "below":
36 extra_perf
= [warn
, crit
]
40 if apply_operator(value
, crit
, op_txt
):
43 elif apply_operator(value
, warn
, op_txt
):
48 levelstxt
+= " (warn/crit %s %s/%s)%s" % \
49 (op_txt
, warn
, crit
, symbol
)
51 return state
, levelstxt
, extra_perf
54 _apache_status_fields
= {
55 # key sort convert-func param_function
57 'IdleWorkers': (5, int),
58 'BusyWorkers': (6, int, apache_status_check_params
, "at"),
59 'OpenSlots': (7, int, apache_status_check_params
, "below"),
60 'TotalSlots': (8, int),
61 'Total Accesses': (9, int),
62 'CPULoad': (10, float),
63 'Total kBytes': (11, float),
64 'ReqPerSec': (12, float),
65 'BytesPerReq': (13, float),
66 'BytesPerSec': (14, float),
67 'Scoreboard': (15, str),
68 'ConnsTotal': (16, int),
69 'ConnsAsyncWriting': (17, int),
70 'ConnsAsyncKeepAlive': (18, int),
71 'ConnsAsyncClosing': (19, int),
72 'BusyServers': (20, int),
73 'IdleServers': (21, int),
76 _apache_status_stats
= {
79 'ReadingRequest': 'R',
90 def apache_status_parse(info
):
93 if len(line
) != 4 and not (len(line
) == 5 and line
[2] == 'Total'):
94 continue # Skip unexpected lines
95 label
= (' '.join(line
[2:-1])).rstrip(':')
96 if label
not in _apache_status_fields
:
99 address
, port
= line
[:2]
100 value
= _apache_status_fields
[label
][1](line
[-1])
104 item
= '%s:%s' % (address
, port
)
109 # Get statistics from scoreboard
110 if label
== 'Scoreboard':
111 for stat_label
, key
in _apache_status_stats
.items():
112 data
[item
]['State_' + stat_label
] = value
.count(key
)
113 data
[item
]['OpenSlots'] = value
.count('.')
115 data
[item
][label
] = value
117 # Count number of total slots after all needed infos are present
118 if 'OpenSlots' in data
[item
] and 'IdleWorkers' in data
[item
] \
119 and 'BusyWorkers' in data
[item
]:
120 data
[item
]['TotalSlots'] = data
[item
]['OpenSlots'] \
121 + data
[item
]['IdleWorkers'] \
122 + data
[item
]['BusyWorkers']
127 def inventory_apache_status(info
):
128 return [(item
, {}) for item
in apache_status_parse(info
)]
131 def check_apache_status(item
, params
, info
):
135 if item
.endswith(":None"):
136 # fix item name discovered before werk 2763
139 all_data
= apache_status_parse(info
)
140 if item
not in all_data
:
141 return (3, 'Unable to find instance in agent output')
142 data_dict
= all_data
[item
]
144 this_time
= int(time
.time())
146 if "Total Accesses" in data_dict
:
147 data_dict
["ReqPerSec"] = get_rate("apache_status_%s_accesses" % item
, this_time
,
148 data_dict
["Total Accesses"])
149 del data_dict
["Total Accesses"]
150 if "Total kBytes" in data_dict
:
151 data_dict
["BytesPerSec"] = get_rate("apache_status_%s_bytes" % item
, this_time
,
152 data_dict
["Total kBytes"] * 1024)
153 del data_dict
["Total kBytes"]
155 data
= data_dict
.items()
162 data
.sort(cmp=lambda x
, y
: cmp(
163 _apache_status_fields
.get(x
[0], (0, None))[0],
164 _apache_status_fields
.get(y
[0], (0, None))[0]))
166 for key
, value
in data
:
167 if key
not in _apache_status_fields
.keys():
170 # Don't process the scoreboard data directly. Print states instead
171 if key
== 'Scoreboard':
173 for stat_label
, key
in _apache_status_stats
.items():
174 val
= data_dict
.get('State_' + stat_label
, 0)
176 states
.append('%s: %d' % (stat_label
, val
))
177 perfdata
.append(('State_' + stat_label
, val
))
178 output
.append('States: (%s)' % ', '.join(states
))
182 display_value
= get_age_human_readable(value
)
183 elif isinstance(value
, float):
184 display_value
= '%0.2f' % value
186 display_value
= '%d' % value
190 apache_status_key
= _apache_status_fields
[key
]
191 if params
.get(key
) and len(apache_status_key
) > 3:
192 key_state
, extra_info
, extra_perf
= \
193 apache_status_key
[2](value
, params
.get(key
), apache_status_key
[3])
194 worst_state
= max(key_state
, worst_state
)
196 output
.append('%s: %s%s' % (key
, display_value
, extra_info
))
197 perfdata
.append(tuple([key
.replace(' ', '_'), value
] + extra_perf
))
199 return (worst_state
, ', '.join(output
), perfdata
)
202 check_info
['apache_status'] = {
203 "check_function": check_apache_status
,
204 "inventory_function": inventory_apache_status
,
205 "service_description": "Apache %s Status",
206 "has_perfdata": True,
207 "group": "apache_status"