Module: check_mk
Branch: master
Commit: 2d49caecceb6088a65cc6c3b841e967af192388c
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=2d49caecceb608…
Author: Simon Betz <si(a)mathias-kettner.de>
Date: Mon Jun 25 13:08:59 2018 +0200
6135 mssql_backup: The check can handle situations if no backups are found
Change-Id: I1c3c5ef55a1c427794397372c3202edbdc6b38d3
---
.werks/6135 | 13 +++
agents/windows/plugins/mssql.vbs | 5 ++
checkman/mssql_backup | 2 +
checks/mssql_backup | 148 +++++++++++++++++------------------
web/plugins/wato/check_parameters.py | 2 +-
5 files changed, 95 insertions(+), 75 deletions(-)
diff --git a/.werks/6135 b/.werks/6135
new file mode 100644
index 0000000..bb63ba5
--- /dev/null
+++ b/.werks/6135
@@ -0,0 +1,13 @@
+Title: mssql_backup: The check can handle situations if no backups are found
+Level: 1
+Component: checks
+Compatible: compat
+Edition: cre
+Version: 1.6.0i1
+Date: 1529572730
+Class: feature
+
+The agent plugin {{mssql.vbs}} must be installed.
+The default state if no backup is found is WARN.
+This state is configurable via the check parameters
+{{MSSQL Time since last Backup}}.
diff --git a/agents/windows/plugins/mssql.vbs b/agents/windows/plugins/mssql.vbs
index ac9c5bc..3781217 100644
--- a/agents/windows/plugins/mssql.vbs
+++ b/agents/windows/plugins/mssql.vbs
@@ -388,6 +388,11 @@ For Each instance_id In instances.Keys: Do ' Continue trick
"END " & _
"EXEC (@SQLCommand)" ,CONN
+ If RS.Eof Then
+ addOutput("MSSQL_" & instance_id & "|" &
Replace(dbName, " ", "_") & _
+ "|-|-|-|no backup found")
+ End If
+
Do While Not RS.Eof
lastBackupDate = Trim(RS("last_backup_date"))
diff --git a/checkman/mssql_backup b/checkman/mssql_backup
index e9e8902..eca1a55 100644
--- a/checkman/mssql_backup
+++ b/checkman/mssql_backup
@@ -13,6 +13,8 @@ description:
The check has been developed with MSSQL Server 2008 R2 but should
work with other versions too.
+ The state if no backup is found is configurable.
+
This check needs the Check_MK mssql.vbs -plugin installed in
the agent. Please refer to the online documentation
for how to install that plugin.
diff --git a/checks/mssql_backup b/checks/mssql_backup
index f2ad4a4..b431173 100644
--- a/checks/mssql_backup
+++ b/checks/mssql_backup
@@ -48,112 +48,112 @@
def parse_mssql_backup(info):
-
- def get_backup_type_name(backup_type):
- return {
- "D": "database ",
- "I": "database diff ",
- "L": "log ",
- "F": "file or filegroup ",
- "G": "file diff ",
- "P": "partial ",
- "Q": "partial diff ",
- "-": "unspecific ",
- }.get(backup_type, "")
-
- parsed = []
+ def _parse_date_and_time(backup_date, backup_time):
+ try:
+ timestamp = time.mktime(time.strptime(
+ "%s %s" % (backup_date, backup_time),
+ '%Y-%m-%d %H:%M:%S'))
+ except ValueError:
+ timestamp = None
+ return timestamp
+
+ map_backup_types = {
+ "D": "database",
+ "I": "database diff",
+ "L": "log",
+ "F": "file or filegroup",
+ "G": "file diff",
+ "P": "partial",
+ "Q": "partial diff",
+ "-": "unspecific",
+ }
+
+ parsed = {}
+ Backup = collections.namedtuple("Backup", ["timestamp",
"type", "state"])
for line in info:
- if len(line) not in [3, 4, 5]:
- continue
+ backup_state = None
+ backup_type = None
+ if len(line) == 6:
+ inst, tablespace, backup_date, backup_time, backup_type, backup_state = line
+ timestamp = _parse_date_and_time(backup_date, backup_time)
- # read data
- backup_date = None
- if len(line) == 5:
+ elif len(line) == 5:
inst, tablespace, backup_date, backup_time, backup_type = line
+ timestamp = _parse_date_and_time(backup_date, backup_time)
+
elif len(line) == 4:
inst, tablespace, backup_date, backup_time = line
- backup_type = None
+ timestamp = _parse_date_and_time(backup_date, backup_time)
+
elif len(line) == 3:
inst, tablespace, backup_timestamp = line
- backup_type = None
-
- # construct content
- db_system = inst + ' ' + tablespace
+ try:
+ timestamp = int(backup_timestamp)
+ except ValueError:
+ timestamp = None
- if backup_date:
- # TODO: Timezone issue? Agent should always send UTC timestamp.
- timestamp = time.mktime(time.strptime(
- backup_date + ' ' + backup_time, '%Y-%m-%d %H:%M:%S')
- )
- else:
- timestamp = int(backup_timestamp)
-
- backup_type_name = get_backup_type_name(backup_type)
-
- if backup_type == None:
- perfkey = "seconds"
else:
- perfkey = "backup_age_%s" % backup_type_name.strip().replace("
", "_")
+ continue
- parsed.append((db_system, timestamp, backup_type_name, perfkey))
+ parsed.setdefault("%s %s" % (inst, tablespace), []).append(
+ Backup(timestamp, map_backup_types.get(backup_type), backup_state))
return parsed
def inventory_mssql_backup(parsed):
- return [ (line[0], {})
- for line in parsed
- if len(line) in [3, 4, 5] ]
+ for db_name in parsed.iterkeys():
+ yield db_name, {}
def check_mssql_backup(item, params, parsed):
- found_instance = False
- for db_system, timestamp, backup_type_name, perfkey in parsed:
- if item != db_system:
- continue
- found_instance = True
+ if item not in parsed:
+ # Assume general connection problem to the database, which is reported
+ # by the "X Instance" service and skip this check.
+ raise MKCounterWrapped("Failed to connect to database")
+
+ if not isinstance(params, dict):
+ params = {"database": params}
- if not isinstance(params, dict):
- params = {"database": params}
+ for backup in parsed[item]:
+ if backup.state == "no backup found":
+ yield params.get("not_found", 1), "State: %s" %
backup.state
+ continue
- if backup_type_name == "": # use "database" parameters as
default for old agent output
- age_warn, age_crit = params["database"]
+ if backup.type is None:
+ backup_type_var = "database"
+ perfkey = "seconds"
+ infotext = "[database] "
else:
- backup_type_var = backup_type_name.strip().replace(" ",
"_")
- age_warn, age_crit = params.get(backup_type_var, (None, None))
+ backup_type_var = backup.type.strip().replace(" ", "_")
+ perfkey = "backup_age_%s" % backup_type_var
+ infotext = "[%s] " % backup.type
state = 0
- sec_ago = time.time() - timestamp
+ age_warn, age_crit = params.get(backup_type_var, (None, None))
+ sec_ago = time.time() - backup.timestamp
if age_crit is not None and sec_ago >= age_crit:
state = 2
elif age_warn is not None and sec_ago >= age_warn:
state = 1
- perfdata = [(perfkey, sec_ago, age_warn, age_crit)]
- infotext = 'Last %sbackup was at %s (%s ago)' % (
- backup_type_name,
- time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)),
- get_age_human_readable(sec_ago)
- )
+ infotext += 'Last backup was at %s (%s ago)' % (
+ time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(backup.timestamp)),
+ get_age_human_readable(sec_ago))
- if state != 0:
+ if state:
infotext += " (warn/crit at %s/%s)" % (
- get_age_human_readable(age_warn), get_age_human_readable(age_crit)
- )
-
- yield state, infotext, perfdata
+ get_age_human_readable(age_warn), get_age_human_readable(age_crit))
- if not found_instance:
- # Assume general connection problem to the database, which is reported
- # by the "X Instance" service and skip this check.
- raise MKCounterWrapped("Failed to connect to database")
+ yield state, infotext, [(perfkey, sec_ago, age_warn, age_crit)]
check_info['mssql_backup'] = {
- 'parse_function': parse_mssql_backup,
- 'check_function': check_mssql_backup,
- 'inventory_function': inventory_mssql_backup,
- 'service_description': 'MSSQL %s Backup',
- 'has_perfdata': True,
- 'group': 'mssql_backup',
+ 'parse_function' : parse_mssql_backup,
+ 'inventory_function' : inventory_mssql_backup,
+ 'check_function' : check_mssql_backup,
+ 'default_levels_variable' : 'mssql_backup_default_levels',
+ 'service_description' : 'MSSQL %s Backup',
+ 'has_perfdata' : True,
+ 'group' : 'mssql_backup',
}
diff --git a/web/plugins/wato/check_parameters.py b/web/plugins/wato/check_parameters.py
index 68c7117..1ace68d 100644
--- a/web/plugins/wato/check_parameters.py
+++ b/web/plugins/wato/check_parameters.py
@@ -10384,7 +10384,7 @@ register_check_parameters(
Age(title = _("Warning if older than")),
Age(title = _("Critical if older than")),
])),
-
+ ("not_found", MonitoringState(title=_("State if no backup
found"))),
]
),
forth = lambda params: (params if isinstance(params, dict)