Add an informix_transactions plugin version that works for CheckMK v2.4.
This commit is contained in:
parent
0c882e643c
commit
fed4e940c0
BIN
informix/2.4/informix_transactions-1.1.0.mkp
Executable file
BIN
informix/2.4/informix_transactions-1.1.0.mkp
Executable file
Binary file not shown.
@ -0,0 +1,220 @@
|
|||||||
|
# Copyright 2026 Spearhead Systems SRL
|
||||||
|
# Copyright (C) 2019 tribe29 GmbH
|
||||||
|
#
|
||||||
|
# Expected example input (and expect arbitrary blank lines):
|
||||||
|
#
|
||||||
|
# <<<informix_transactions>>>
|
||||||
|
# [[[1/2]]]
|
||||||
|
# a40dbb0 6 U---C-L 6 1:3263 500 372 74.40
|
||||||
|
#
|
||||||
|
# a6d8028 A---- a695028 0 - - COMMIT - 0
|
||||||
|
# a6d8348 A---- a695878 0 - - COMMIT - 0
|
||||||
|
# a6d8668 A---- a6960c8 0 - - COMMIT - 0
|
||||||
|
# a6d8988 A---- a696918 0 - - COMMIT - 0
|
||||||
|
# a6d8fc8 A---- a698208 0 - - COMMIT - 0
|
||||||
|
# a6d92e8 A---- a6979b8 0 - - COMMIT - 0
|
||||||
|
# a6d9608 A---- a698a58 0 - - COMMIT - 0
|
||||||
|
# a6d9928 A---- a6992a8 1 - - DIRTY - 0
|
||||||
|
# a6d9c48 A---- a6992a8 0 - - NOTRANS - 0
|
||||||
|
# a6d9f68 A---- a69a348 0 - - COMMIT - 0
|
||||||
|
# a6da288 A---- a69ab98 0 - - COMMIT - 0
|
||||||
|
# a6da5a8 A---- a69b3e8 0 - - COMMIT - 0
|
||||||
|
# a6da8c8 A---- a69bc38 0 - - COMMIT - 0
|
||||||
|
# a6dabe8 A---- a69c488 0 - - COMMIT - 0
|
||||||
|
# a6daf08 A---- a699af8 0 - - COMMIT - 0
|
||||||
|
# a6db228 A---- a6992a8 0 - - COMMIT - 0
|
||||||
|
# a6db548 A---- a69ccd8 1 - - DIRTY - 0
|
||||||
|
# a6db868 A---- a69d528 1 - - DIRTY - 0
|
||||||
|
# a6dbb88 A---- a69ccd8 0 - - COMMIT - 0
|
||||||
|
# a6dbea8 A---- a69dd78 0 - - COMMIT - 0
|
||||||
|
# a6dc1c8 A---- a69e5c8 0 - - COMMIT - 0
|
||||||
|
# a6dc4e8 A-B-- a69ee18 502 33:0x25018 34:0x486fc COMMIT 0
|
||||||
|
|
||||||
|
|
||||||
|
import json
|
||||||
|
from cmk.agent_based.v2 import (
|
||||||
|
Result,
|
||||||
|
Service,
|
||||||
|
Metric,
|
||||||
|
State,
|
||||||
|
CheckPlugin,
|
||||||
|
AgentSection,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# This is what the columns from the onstat -x output represent:
|
||||||
|
#
|
||||||
|
# line[0]= first line represents current log ID
|
||||||
|
# line[1]= <ignore>
|
||||||
|
# line[2]= sessionID
|
||||||
|
# line[3]= number of locks kept by sessionID
|
||||||
|
# line[4]= begin log position
|
||||||
|
# line[5]= current log position
|
||||||
|
def parse_informix_transactions(string_table):
|
||||||
|
instance = string_table[0][0][3:-3]
|
||||||
|
curr_log = ""
|
||||||
|
sessions = []
|
||||||
|
|
||||||
|
for line in string_table[1:]:
|
||||||
|
if len(line) <= 5:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "C" in line[2]:
|
||||||
|
curr_log = int(line[3])
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ":" in line[4]:
|
||||||
|
line[4] = int(line[4].split(":")[0])
|
||||||
|
else:
|
||||||
|
line[4] = None
|
||||||
|
|
||||||
|
if ":" in line[5]:
|
||||||
|
line[5] = int(line[5].split(":")[0])
|
||||||
|
else:
|
||||||
|
line[5] = None
|
||||||
|
|
||||||
|
sessions.append({
|
||||||
|
"id": line[2],
|
||||||
|
"locks": int(line[3]),
|
||||||
|
"log_start": line[4],
|
||||||
|
"log_end": line[5],
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
instance: {
|
||||||
|
"curr_log": curr_log,
|
||||||
|
"sessions": sessions,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def discover_informix_transactions(section):
|
||||||
|
for instance in section:
|
||||||
|
yield Service(item=instance)
|
||||||
|
|
||||||
|
|
||||||
|
def check_informix_locks(item, params, section):
|
||||||
|
data = section.get(item)
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
levels = params.get("levels")
|
||||||
|
infotext = ""
|
||||||
|
state = State.OK
|
||||||
|
max_locks = 0
|
||||||
|
|
||||||
|
if levels and levels[0] == "fixed":
|
||||||
|
warn, crit = levels[1]
|
||||||
|
else:
|
||||||
|
warn, crit = None, None
|
||||||
|
|
||||||
|
for session in data["sessions"]:
|
||||||
|
id = session["id"]
|
||||||
|
locks = session["locks"]
|
||||||
|
log_start = session["log_start"]
|
||||||
|
|
||||||
|
max_locks = max(max_locks, locks)
|
||||||
|
|
||||||
|
if log_start == "-":
|
||||||
|
continue
|
||||||
|
|
||||||
|
if crit and locks >= crit:
|
||||||
|
state = State.CRIT
|
||||||
|
infotext += f"Session with ID {id} has {locks} locks; "
|
||||||
|
elif warn and locks >= warn:
|
||||||
|
state = State.WARN
|
||||||
|
infotext += f"Session with ID {id} has {locks} locks; "
|
||||||
|
|
||||||
|
if state != State.OK:
|
||||||
|
infotext += f"(warn/crit at {warn}/{crit})"
|
||||||
|
else:
|
||||||
|
infotext = "There are no sessions with a high number of locks"
|
||||||
|
|
||||||
|
yield Metric(name="MaximumLocksInSession", value=max_locks)
|
||||||
|
yield Result(state=state, summary=infotext)
|
||||||
|
|
||||||
|
|
||||||
|
def check_informix_activity(item, params, section):
|
||||||
|
data = section.get(item)
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
state = State.OK
|
||||||
|
infotext = ""
|
||||||
|
curr_log = data["curr_log"]
|
||||||
|
|
||||||
|
for session in data["sessions"]:
|
||||||
|
id = session["id"]
|
||||||
|
log_start = session["log_start"]
|
||||||
|
|
||||||
|
if log_start is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if log_start < curr_log:
|
||||||
|
state = State.CRIT
|
||||||
|
infotext += f"Session {id} doesn't have activity in current log; "
|
||||||
|
|
||||||
|
if state == State.OK:
|
||||||
|
infotext = "There are no inactive sessions in current log"
|
||||||
|
|
||||||
|
yield Result(state=state, summary=infotext)
|
||||||
|
|
||||||
|
|
||||||
|
def check_informix_long_transactions(item, params, section):
|
||||||
|
data = section.get(item)
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
state = State.OK
|
||||||
|
infotext = ""
|
||||||
|
|
||||||
|
for session in data["sessions"]:
|
||||||
|
id = session["id"]
|
||||||
|
log_start = session["log_start"]
|
||||||
|
log_end = session["log_end"]
|
||||||
|
|
||||||
|
if log_start is None or log_end is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if log_end - log_start > 2:
|
||||||
|
state = State.CRIT
|
||||||
|
infotext += f"Session {id} is using more than 3 logical logs; "
|
||||||
|
|
||||||
|
if state == State.OK:
|
||||||
|
infotext = "There are no long-running transactions"
|
||||||
|
|
||||||
|
yield Result(state=state, summary=infotext)
|
||||||
|
|
||||||
|
|
||||||
|
agent_section_informix_transactions = AgentSection(
|
||||||
|
name = "informix_transactions",
|
||||||
|
parse_function = parse_informix_transactions,
|
||||||
|
)
|
||||||
|
|
||||||
|
check_plugin_informix_session_locks = CheckPlugin(
|
||||||
|
name = "informix_session_locks",
|
||||||
|
check_ruleset_name = "informix_session_locks",
|
||||||
|
service_name = "Informix session locks %s",
|
||||||
|
sections = ["informix_transactions"],
|
||||||
|
discovery_function = discover_informix_transactions,
|
||||||
|
check_function = check_informix_locks,
|
||||||
|
check_default_parameters = {},
|
||||||
|
)
|
||||||
|
|
||||||
|
check_plugin_informix_session_activity = CheckPlugin(
|
||||||
|
name = "informix_session_activity",
|
||||||
|
service_name = "Informix session activity %s",
|
||||||
|
sections = ["informix_transactions"],
|
||||||
|
discovery_function = discover_informix_transactions,
|
||||||
|
check_function = check_informix_activity,
|
||||||
|
check_default_parameters = {},
|
||||||
|
)
|
||||||
|
|
||||||
|
check_plugin_informix_session_long_transactions = CheckPlugin(
|
||||||
|
name = "informix_session_long_transactions",
|
||||||
|
service_name = "Informix session long transactions %s",
|
||||||
|
sections = ["informix_transactions"],
|
||||||
|
discovery_function = discover_informix_transactions,
|
||||||
|
check_function = check_informix_long_transactions,
|
||||||
|
check_default_parameters = {},
|
||||||
|
)
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
# Copyright 2026 Spearhead Systems SRL
|
||||||
|
|
||||||
|
from cmk.rulesets.v1.form_specs import (
|
||||||
|
Dictionary,
|
||||||
|
DictElement,
|
||||||
|
Integer,
|
||||||
|
DefaultValue,
|
||||||
|
LevelDirection,
|
||||||
|
SimpleLevels,
|
||||||
|
)
|
||||||
|
from cmk.rulesets.v1.rule_specs import (
|
||||||
|
CheckParameters,
|
||||||
|
HostAndItemCondition,
|
||||||
|
Topic,
|
||||||
|
Title,
|
||||||
|
Help,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _valuespec_informix_session_locks():
|
||||||
|
return Dictionary(
|
||||||
|
elements = {
|
||||||
|
"levels": DictElement(
|
||||||
|
parameter_form = SimpleLevels(
|
||||||
|
title = Title("Session locks"),
|
||||||
|
help_text = Help(
|
||||||
|
"You can set a limit to the number of locks for a "
|
||||||
|
"session in Informix Database application"
|
||||||
|
),
|
||||||
|
level_direction = LevelDirection.UPPER,
|
||||||
|
form_spec_template = Integer(title = Title("locks")),
|
||||||
|
prefill_fixed_levels = DefaultValue(value=(40, 70))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
rule_spec_informix_session_locks = CheckParameters(
|
||||||
|
title = Title("Informix Session Locks"),
|
||||||
|
name = "informix_session_locks",
|
||||||
|
topic = Topic.APPLICATIONS,
|
||||||
|
parameter_form = _valuespec_informix_session_locks,
|
||||||
|
condition = HostAndItemCondition(
|
||||||
|
item_title = Title("DBMS"),
|
||||||
|
),
|
||||||
|
)
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
|
||||||
|
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
|
||||||
|
# conditions defined in the file COPYING, which is part of this source code package.
|
||||||
|
|
||||||
|
# Reason for this no-op: shellcheck disable=... before the first command disables the error for the
|
||||||
|
# entire script.
|
||||||
|
:
|
||||||
|
|
||||||
|
# Disable unused variable error (needed to keep track of version)
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
CMK_VERSION="2.4.0"
|
||||||
|
|
||||||
|
# Informix
|
||||||
|
# Make ENV-VARs avail for subshells
|
||||||
|
set -a
|
||||||
|
|
||||||
|
# .--helper--------------------------------------------------------------.
|
||||||
|
# | _ _ |
|
||||||
|
# | | |__ ___| |_ __ ___ _ __ |
|
||||||
|
# | | '_ \ / _ \ | '_ \ / _ \ '__| |
|
||||||
|
# | | | | | __/ | |_) | __/ | |
|
||||||
|
# | |_| |_|\___|_| .__/ \___|_| |
|
||||||
|
# | |_| |
|
||||||
|
# '----------------------------------------------------------------------'
|
||||||
|
|
||||||
|
# BEGIN COMMON PLUGIN CODE
|
||||||
|
|
||||||
|
# check that no users other than root can change the file
|
||||||
|
only_root_can_modify() {
|
||||||
|
permissions=$1
|
||||||
|
owner=$2
|
||||||
|
group=$3
|
||||||
|
|
||||||
|
group_write_perm=$(echo "$permissions" | cut -c 6)
|
||||||
|
other_write_perm=$(echo "$permissions" | cut -c 9)
|
||||||
|
|
||||||
|
if [ "$owner" != "root" ] || [ "$other_write_perm" != "-" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "$group" = "root" ] || [ "$group_write_perm" = "-" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
get_binary_owner() {
|
||||||
|
BINARY_PATH=$1
|
||||||
|
stat -c '%U' "${BINARY_PATH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_binary_execution_mode() {
|
||||||
|
BINARY_PATH=$1
|
||||||
|
BINARY_USER=$2
|
||||||
|
|
||||||
|
# if the executable belongs to someone besides root, do not execute it as root
|
||||||
|
if needs_user_switch_before_executing "$BINARY_PATH"; then
|
||||||
|
echo "su ${BINARY_USER} -c"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "bash -c"
|
||||||
|
}
|
||||||
|
|
||||||
|
needs_user_switch_before_executing() {
|
||||||
|
BINARY_PATH=$1
|
||||||
|
|
||||||
|
[ "$(whoami)" = "root" ] && ! only_root_can_modify "$(stat -c '%A' "$BINARY_PATH")" "$(stat -c '%U' "$BINARY_PATH")" "$(stat -c '%G' "$BINARY_PATH")"
|
||||||
|
}
|
||||||
|
|
||||||
|
# END COMMON PLUGIN CODE
|
||||||
|
|
||||||
|
set_env() {
|
||||||
|
# set environment variables given in the form VARNAME1=value1;VARNAME2=value2;...
|
||||||
|
while IFS=';' read -ra parts; do
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
var_name="${part%%=*}"
|
||||||
|
var_value="${part#*=}"
|
||||||
|
export "$var_name"="$var_value"
|
||||||
|
done
|
||||||
|
done <<<"$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#.
|
||||||
|
# .--sqls----------------------------------------------------------------.
|
||||||
|
# | _ |
|
||||||
|
# | ___ __ _| |___ |
|
||||||
|
# | / __|/ _` | / __| |
|
||||||
|
# | \__ \ (_| | \__ \ |
|
||||||
|
# | |___/\__, |_|___/ |
|
||||||
|
# | |_| |
|
||||||
|
# '----------------------------------------------------------------------'
|
||||||
|
|
||||||
|
informix_transactions() {
|
||||||
|
echo "<<<informix_transactions>>>"
|
||||||
|
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
|
||||||
|
$EXECUTION_MODE "\"$INFORMIXDIR\"/bin/onstat -l" | grep C | tail -n 1
|
||||||
|
$EXECUTION_MODE "\"$INFORMIXDIR\"/bin/onstat -x" | egrep -v 'IBM|maximum|Transactions|est.|userthread|logpos' | sed 's/:[^:]*$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#.
|
||||||
|
# .--config--------------------------------------------------------------.
|
||||||
|
# | __ _ |
|
||||||
|
# | ___ ___ _ __ / _(_) __ _ |
|
||||||
|
# | / __/ _ \| '_ \| |_| |/ _` | |
|
||||||
|
# | | (_| (_) | | | | _| | (_| | |
|
||||||
|
# | \___\___/|_| |_|_| |_|\__, | |
|
||||||
|
# | |___/ |
|
||||||
|
# '----------------------------------------------------------------------'
|
||||||
|
|
||||||
|
# Config opts:
|
||||||
|
# - oninit-path; Default is empty, which means autodetection:
|
||||||
|
# ONINIT_PATH=<path to oninit-binary>
|
||||||
|
# - Excluding sections ("status sessions locks tabextents dbspaces logusage"):
|
||||||
|
# EXCLUDES="SECTION SECTION ..."
|
||||||
|
# EXCLUDES=ALL
|
||||||
|
|
||||||
|
# shellcheck source=agents/cfg_examples/informix.cfg
|
||||||
|
. "$MK_CONFDIR/informix.cfg" 2>/dev/null
|
||||||
|
|
||||||
|
if [ -z "$ONINIT_PATH" ] || [ ! -x "$ONINIT_PATH" ]; then
|
||||||
|
ONINIT=$(UNIX95=true ps ax | grep oninit | grep -v grep | head -1 | awk '{print $1 " " $5}')
|
||||||
|
if [ -z "$ONINIT" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ONINIT_PATH=${ONINIT#* }
|
||||||
|
ONINIT_PID=${ONINIT% *}
|
||||||
|
case "$ONINIT_PATH" in
|
||||||
|
/*) ;;
|
||||||
|
|
||||||
|
*) # BUG not platform independent!
|
||||||
|
ONINIT_PATH=$(readlink "/proc/$ONINIT_PID/exe")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If not set in config or not found we end up here
|
||||||
|
if [ -z "$ONINIT_PATH" ] || [ ! -f "$ONINIT_PATH" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
#.
|
||||||
|
# .--main----------------------------------------------------------------.
|
||||||
|
# | _ |
|
||||||
|
# | _ __ ___ __ _(_)_ __ |
|
||||||
|
# | | '_ ` _ \ / _` | | '_ \ |
|
||||||
|
# | | | | | | | (_| | | | | | |
|
||||||
|
# | |_| |_| |_|\__,_|_|_| |_| |
|
||||||
|
# | |
|
||||||
|
# '----------------------------------------------------------------------'
|
||||||
|
|
||||||
|
INFORMIXDIR=${ONINIT_PATH%/bin*}
|
||||||
|
|
||||||
|
if [ ! -f "$INFORMIXDIR/bin/onstat" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXECUTION_MODE="$(get_binary_execution_mode "$INFORMIXDIR/bin/onstat" "$(get_binary_owner "$INFORMIXDIR/bin/onstat")")"
|
||||||
|
|
||||||
|
for IDSENV in $(
|
||||||
|
$EXECUTION_MODE "$INFORMIXDIR/bin/onstat -g dis" |
|
||||||
|
grep -E '^Server[ ]*:|^Server Number[ ]*:|^INFORMIX|^SQLHOSTS|^ONCONFIG' |
|
||||||
|
sed -e 's/Server Number/SERVERNUM/' \
|
||||||
|
-e 's/Server/INFORMIXSERVER/' \
|
||||||
|
-e 's/SQLHOSTS/INFORMIXSQLHOSTS/' \
|
||||||
|
-e 's/[ ]*:[ ]*/=/' |
|
||||||
|
tr '\n' ';' |
|
||||||
|
sed -e 's/;$/\n/' -e 's/;\(INFORMIXSERVER=[^;]*;\)/\n\1/g'
|
||||||
|
|
||||||
|
); do
|
||||||
|
(
|
||||||
|
set_env "$IDSENV"
|
||||||
|
|
||||||
|
# try to set them via 'onstat -g env' otherwise
|
||||||
|
# DB HAS TO BE RUNNING
|
||||||
|
if [ -z "$INFORMIXSQLHOSTS" ] || [ -z "$ONCONFIG" ]; then
|
||||||
|
$EXECUTION_MODE "$INFORMIXDIR/bin/onstat -g env" | grep -E -e '^INFORMIXSQLHOSTS' \
|
||||||
|
-e '^ONCONFIG' |
|
||||||
|
sed -e 's/[ ][ ]*/=/'
|
||||||
|
fi
|
||||||
|
|
||||||
|
informix_transactions
|
||||||
|
)
|
||||||
|
done
|
||||||
Loading…
x
Reference in New Issue
Block a user