/usr/share/check_mk/checks/ps is in check-mk-server 1.2.6p12-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# | ____ _ _ __ __ _ __ |
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
# | | |___| | | | __/ (__| < | | | | . \ |
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
# | |
# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation in version 2. check_mk is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more de-
# ails. You should have received a copy of the GNU General Public
# License along with GNU Make; see the file COPYING. If not, write
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
# First generation of agents output only the process command line:
# /usr/sbin/xinetd -pidfile /var/run/xinetd.pid -stayalive -inetd_compat -inetd_ipv6
# Second generation of agents output the user in brackets in the first columns:
# (root) /usr/sbin/xinetd -pidfile /var/run/xinetd.pid -stayalive -inetd_compat -inetd_ipv6
# Third generation (from 1.1.5) output also virtual memory, resident memory and %CPU:
# (class,122376,88128,0.0) /usr/jre1.6.0_13/bin/java -Dn=Cart_16TH13 -Dmcs.node=zbgh1ca -Dmcs.mdt.redundan
# Forth generation (>=1.2.5), additional columns in bracket:
# (user, virtual_size, resident_size, %cpu, processID, pagefile_usage, usermodetime, kernelmodetime, openHandles, threadCount) name
#(\\KLAPPRECHNER\ab,29284,2948,0,3124,904,400576,901296,35,1) NOTEPAD.EXE
# The plugin "psperf.bat" is deprecated. As of version 1.2.5 all of this information
# is reported by the windows agent itself. However, we still support sections from psperf.bat
# if the agent version is lower than 1.2.5.
# Windows agent now ships a plugin "psperf.bat" that adds a section from wmic
# to the output:
# <<<ps:sep(44)>>>
# [wmic process]
# ^M
# Node,KernelModeTime,Name,PageFileUsage,ThreadCount,UserModeTime,VirtualSize,WorkingSetSize^M
# WINDOWSXP,43478281250,System Idle Process,0,2,0,0,28672^M
# WINDOWSXP,155781250,System,0,59,0,1957888,253952^M
# WINDOWSXP,468750,smss.exe,176128,3,156250,3928064,442368^M
# WINDOWSXP,56406250,csrss.exe,1863680,12,11406250,25780224,3956736^M
# WINDOWSXP,18593750,winlogon.exe,6832128,19,4843750,59314176,2686976^M
# WINDOWSXP,167500000,services.exe,1765376,16,13750000,22601728,4444160^M
# WINDOWSXP,16875000,lsass.exe,3964928,21,3906250,43462656,6647808^M
# WINDOWSXP,8750000,VBoxService.exe,1056768,8,468750,26652672,3342336^M
# New since 1.2.1i2: WATO compatible syntax
#
# Holds a list of rules which are matching hosts by names or tags and
# where each rule holds a dictionary.
#
# Each of those entries defines the following options:
#
# 1. descr: item name to be used for the service description
# 2. match: matching-definition
# 3. user: user definition
# 5. perfdata: monitor with perfdata
# 4. levels: four numbers (thresholds)
inventory_processes_rules = []
inventory_processes = []
inventory_processes_perf = []
ANY_USER = None
GRAB_USER = False
def ps_parse_info(info):
ps_result = []
lines = iter(info)
wmic_info = {}
use_wmic_info = True
cpu_cores = 1
try:
is_wmic = False
while True:
line = lines.next()
if line[-1] == '[wmic process]':
is_wmic = True
wmic_headers = ["node"] + lines.next()[1:]
continue
elif line[-1] == '[wmic process end]':
is_wmic = False
continue
if not is_wmic:
# Ignore data from the psperf.bat if the agent has this feature builtin
if use_wmic_info and len(line[1].split(",")) >= 10:
use_wmic_info = False
if not use_wmic_info:
# We need to determine the number of cpu_cores without the wmic_info
if len(line) < 3:
# On some rare instances the name of the process is missing
# This line will be ignored
continue
if line[2].lower() == "system idle process":
cpu_cores = int(line[1][1:-1].split(",")[9])
ps_result.append(line)
else:
row = dict(zip(wmic_headers, line))
wmic_info[(row["node"], row["Name"], row["ProcessId"])] = row
except StopIteration:
pass
# Add wmic_info to process table, but only if present:
if use_wmic_info and wmic_info:
def get_ps_info(node, name, processId = 0):
for key, value in wmic_info.items():
if (not processId and key[0:2] == (node, name)) or key == (node, name, processId):
# each info is only returned once!
del wmic_info[key]
return value
info = []
seen_pids = set([]) # Remove duplicate entries
for line in ps_result:
psinfo = get_ps_info(line[0], line[1])
# Get number of CPU cores from system idle process
if psinfo:
if "ThreadCount" in wmic_headers and psinfo["Name"].lower() == "system idle process":
cpu_cores = int(psinfo["ThreadCount"])
pid = int(psinfo["ProcessId"])
if pid not in seen_pids:
seen_pids.add(pid)
virt = int(psinfo["VirtualSize"]) / 1024 # Bytes -> KB
resi = int(psinfo["WorkingSetSize"]) / 1024 # Bytes -> KB
pagefile = int(psinfo["PageFileUsage"]) / 1024 # Bytes -> KB
userc = int(psinfo["UserModeTime"]) # do not resolve counter here!
kernelc = int(psinfo["KernelModeTime"]) # do not resolve counter here!
handlec = int(psinfo.get("HandleCount", 0)) # Only in newer psperf.bat versions
threadc = int(psinfo["ThreadCount"]) # do not resolve counter here!
line[1:1] = [ "(unknown,%d,%d,0,%d,%d,%d,%d,%d,%d)" %
(virt, resi, pid, pagefile, userc, kernelc, handlec, threadc) ]
info.append(line)
return cpu_cores, info
else:
return cpu_cores, info
def inventory_ps(info):
cpu_cores, info = ps_parse_info(info) # parse windows wmic information
return inventory_ps_common(inventory_processes, inventory_processes_rules, info)
def check_ps(item, params, info):
cpu_cores, info = ps_parse_info(info) # parse windows wmic information
return check_ps_common(item, params, info, cpu_cores = cpu_cores )
check_info['ps'] = {
"check_function" : check_ps,
"inventory_function" : inventory_ps,
"service_description" : "Process %s",
"includes" : [ "ps.include" ],
"has_perfdata" : True,
"node_info" : True, # add first column with actual host name
"group" : "ps",
"default_levels_variable" : "ps_default_levels",
}
# NOTE: This check is deprecated and will be removed any decade now. ps now
# does always performance data.
check_info['ps.perf'] = {
"check_function" : check_ps,
"service_description" : "Process %s",
"includes" : [ "ps.include" ],
"has_perfdata" : True,
"node_info" : True, # add first column with actual host name
"group" : "ps",
"default_levels_variable" : "ps_default_levels",
}
|