This file is indexed.

/usr/share/check_mk/checks/job 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
#!/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.

#<<<job>>>
#==> asd ASD <==
#start_time 1389355839
#exit_code 0
#real_time 0:00.00
#user_time 0.00
#system_time 0.00
#reads 0
#writes 0
#max_res_kbytes 1968
#avg_mem_kbytes 0
#
#
#==> test <==
#start_time 1389352839
#exit_code 0
#real_time 0:00.00
#user_time 0.00
#system_time 0.00
#reads 0
#writes 0
#max_res_kbytes 1984
#avg_mem_kbytes 0

factory_settings["job_default_levels"] = {
        "age": ( 0, 0 ) # disabled as default
}

def inventory_job(info):
    inventory = []
    for line in info:
        if line[0] == '==>':
            item = ' '.join(line[1:-1])
            if not item.endswith('.running'):
                inventory.append( (item, {} ) )
    return inventory

def job_parse_real_time(s):
    parts = s.split(':')
    min_sec, hour_sec = 0, 0
    if len(parts) == 3:
        hour_sec = int(parts[0]) * 60 * 60
    if len(parts) >= 2:
        min_sec = int(parts[-2]) * 60
    return float(parts[-1]) + min_sec + hour_sec

def job_parse(item, info):
    data = {}
    prefix = None
    for line in info:
        if line[0] == '==>':

            if ' '.join(line[1:-1]) == item:
                prefix = ''

            elif ' '.join(line[1:-1]) == item + '.running':
                # There might be a second section per job, the contents of the
                # <ident>.running file which exists during execution of the job.
                # We use the start_time from this file.
                prefix = 'running_'

            elif 'start_time' in data.keys() and 'running_start_time' in data.keys():
                break # both sections completed => we are done here

            else:
                prefix = None

        elif len(line) == 2 and prefix is not None:
            key, val = line
            # Convert several keys/values
            if key == 'real_time':
                val = job_parse_real_time(val)
            elif key in [ 'user_time', 'system_time' ]:
                val = float(val)
            elif key in [ 'exit_code', 'invol_context_switches', 'vol_context_switches', 'start_time' ]:
                val = int(val)
            elif key in [ 'max_res_kbytes', 'avg_mem_kbytes' ]:
                key = key.replace('kbytes', 'bytes')
                val = int(val) * 1000
            data[prefix+key] = val

    return data

def check_job(item, params, info):
    warn, crit = params.get('age')
    job = job_parse(item, info)
    if not job:
        return 3, 'Got no information for this job'

    def process_start_time(value, state, warn, crit):
        display_value = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(value) )
        job_age = time.time() - value
        if crit > 0 and job_age >= crit:
            state = max(state, 2)
            display_value += "(!!) (more than %s ago)" % get_age_human_readable(crit)
        elif warn > 0 and job_age >= warn:
            state = max(state, 1)
            display_value += "(!!) (more than %s ago)" % get_age_human_readable(warn)
        return state, display_value

    state = 0
    output = []
    perfdata = []

    if 'running_start_time' in job:
        output.append('Currently running')
        state, display_value = process_start_time(job['running_start_time'], state, warn, crit)
        output.append('(Started: %s)' % display_value)
        return state, ' '.join(output)

    txt = 'Exit-Code: %d' % job['exit_code']
    if job['exit_code'] != 0:
        state = max(state, 2)
        txt += ' (!!)'
    output.append(txt)

    for key, title, value in [
        ('start_time',             'Started',                 job['start_time']),
        ('real_time',              'Real-Time',               job['real_time']),
        ('user_time',              'User-Time',               job['user_time']),
        ('system_time',            'System-Time',             job['system_time']),
        ('reads',                  'Filesystem Reads',        job['reads']),
        ('writes',                 'Filesystem Writes',       job['writes']),
        ('max_res_bytes',          'Max. Memory',             job['max_res_bytes']),
        ('avg_mem_bytes',          'Avg. Memory',             job['avg_mem_bytes']),
        ('vol_context_switches',   'Vol. Context Switches',   job['vol_context_switches']),
        ('invol_context_switches', 'Invol. Context Switches', job['invol_context_switches']),
      ]:
        if key in [ 'max_res_bytes', 'avg_mem_bytes' ]:
            display_value = get_bytes_human_readable(value, 1000)
        elif key in [ 'real_time', 'user_time', 'system_time' ]:
            display_value = get_age_human_readable(value)
        elif key == 'start_time':
            state, display_value = process_start_time(value, state, warn, crit)
        else:
            display_value = value

        output.append('%s: %s' % (title, display_value))
        perfdata.append((key, value))

    return state, ', '.join(output), perfdata

check_info["job"] = {
    'check_function'          : check_job,
    'inventory_function'      : inventory_job,
    'service_description'     : 'Job %s',
    'default_levels_variable' : 'job_default_levels',
    'group'                   : 'job',
    'has_perfdata'            : True,
}