[add] check_kind:file_state
This commit is contained in:
parent
a2cc43dffb
commit
c27b23d98b
|
|
@ -16,6 +16,7 @@
|
|||
"help.args.show_schema": "nur das hmdl-JSON-Schema zur Standard-Ausgabe schreiben und beenden",
|
||||
"help.args.expose_full_order": "nur den Pfad zur Datenbank-Datei zur Standard-Ausgabe schreiben und beenden (nützlich für Fehlersuche)",
|
||||
"help.args.show_version": "nur die Version zur Standard-Ausgabe schreiben und beenden",
|
||||
"help.args.verbosity": "Schwellwert für Log-Ausgaben",
|
||||
"checks.file_state.exists": "Datei existiert (soll aber nicht)",
|
||||
"checks.file_state.missing": "Datei existiert nicht (soll aber)",
|
||||
"checks.file_state.timestamp_implausible": "Datei ist scheinbar aus der Zukunft",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"help.args.show_schema": "print the hmdl JSON schema to stdout and exit",
|
||||
"help.args.expose_full_order": "only print the extended order to stdout and exit (useful for debugging)",
|
||||
"help.args.show_version": "only print the version to stdout and exit",
|
||||
"help.args.verbosity": "threshold for log outputs",
|
||||
"checks.file_state.exists": "file exists (but shall not)",
|
||||
"checks.file_state.missing": "file does not exist (but shall)",
|
||||
"checks.file_state.timestamp_implausible": "file is apparently from the future",
|
||||
|
|
|
|||
|
|
@ -102,6 +102,15 @@ namespace _heimdall
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function get_current_timestamp(
|
||||
) : int
|
||||
{
|
||||
return Math.floor(Date.now() / 1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* converts a condition to a human readable string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace _heimdall.check_kinds.file_state
|
|||
) : any
|
||||
{
|
||||
const version : string = (
|
||||
(! ("exist_mode" in node)
|
||||
(! ("exist_mode" in node))
|
||||
? "v1"
|
||||
: "v2"
|
||||
);
|
||||
|
|
@ -115,6 +115,7 @@ namespace _heimdall.check_kinds.file_state
|
|||
node
|
||||
);
|
||||
return {
|
||||
"path": node["path"],
|
||||
"exist_mode": node_["exist"],
|
||||
"exist_critical": node_["strict"],
|
||||
"age_threshold_concerning": (
|
||||
|
|
@ -171,7 +172,153 @@ namespace _heimdall.check_kinds.file_state
|
|||
parameters
|
||||
) : Promise<_heimdall.type_result>
|
||||
{
|
||||
return Promise.reject<_heimdall.type_result>(new Error("not implemented"));
|
||||
const nm_fs = require("fs");
|
||||
|
||||
let condition : _heimdall.enum_condition = _heimdall.enum_condition.ok;
|
||||
let faults : Array<string> = [];
|
||||
let data : Record<string, any> = {};
|
||||
|
||||
let exists : boolean;
|
||||
let stats : {
|
||||
ctime : float;
|
||||
size : int;
|
||||
};
|
||||
await new Promise<void>(
|
||||
(resolve, reject) => {
|
||||
nm_fs.stat(
|
||||
parameters["path"],
|
||||
{
|
||||
"bigint": false,
|
||||
},
|
||||
(err, stats_) => {
|
||||
if (err) {
|
||||
exists = false;
|
||||
stats = null;
|
||||
resolve(undefined);
|
||||
}
|
||||
else {
|
||||
exists = true;
|
||||
stats = stats_;
|
||||
resolve(undefined);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
if (! parameters["exist_mode"]) {
|
||||
if (exists) {
|
||||
condition = (
|
||||
parameters["exist_critical"]
|
||||
? _heimdall.enum_condition.concerning
|
||||
: _heimdall.enum_condition.critical
|
||||
);
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.exists"));
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (! exists) {
|
||||
condition = (
|
||||
parameters["exist_critical"]
|
||||
? _heimdall.enum_condition.concerning
|
||||
: _heimdall.enum_condition.critical
|
||||
);
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.missing"));
|
||||
}
|
||||
else {
|
||||
// age
|
||||
{
|
||||
const timestamp_this : int = _heimdall.get_current_timestamp();
|
||||
const timestamp_that : int = Math.floor(stats.ctime);
|
||||
const age : int = (timestamp_this - timestamp_that);
|
||||
if (age < 0) {
|
||||
condition = _heimdall.enum_condition.critical;
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.timestamp_implausible"));
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(parameters["age_threshold_critical"] !== null)
|
||||
&&
|
||||
(age > parameters["age_threshold_critical"])
|
||||
) {
|
||||
condition = _heimdall.enum_condition.critical;
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.too_old"));
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(parameters["age_threshold_concerning"] !== null)
|
||||
&&
|
||||
(age > parameters["age_threshold_concerning"])
|
||||
) {
|
||||
condition = _heimdall.enum_condition.critical;
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.too_old"));
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
data = Object.assign(
|
||||
data,
|
||||
{
|
||||
"timestamp_of_checking_instance": timestamp_this,
|
||||
"timestamp_of_file": timestamp_that,
|
||||
"age_value_in_seconds": age,
|
||||
"age_threshold_in_seconds_concerning": parameters["age_threshold_concerning"],
|
||||
"age_threshold_in_seconds_critical": parameters["age_threshold_critical"],
|
||||
}
|
||||
);
|
||||
}
|
||||
// size
|
||||
{
|
||||
const size : int = stats.size;
|
||||
if (size < 0) {
|
||||
condition = _heimdall.enum_condition.critical;
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.size_implausible"));
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(parameters["size_threshold_critical"] !== null)
|
||||
&&
|
||||
(size > parameters["size_threshold_critical"])
|
||||
) {
|
||||
condition = _heimdall.enum_condition.critical;
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.too_big"));
|
||||
}
|
||||
else {
|
||||
if (
|
||||
(parameters["size_threshold_concerning"] !== null)
|
||||
&&
|
||||
(size > parameters["size_threshold_concerning"])
|
||||
) {
|
||||
condition = _heimdall.enum_condition.critical;
|
||||
faults.push(lib_plankton.translate.get("checks.file_state.too_big"));
|
||||
}
|
||||
else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
data = Object.assign(
|
||||
data,
|
||||
{
|
||||
"size_value_in_bytes": size,
|
||||
"size_threshold_in_bytes": parameters["size_threshold"],
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
"condition": condition,
|
||||
"info": {
|
||||
"path": parameters["path"],
|
||||
"faults": faults,
|
||||
"data": data,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,12 @@ async function main(
|
|||
"indicators_long": ["send-ok-notifications"],
|
||||
"indicators_short": ["y"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.send_ok_notifications"),
|
||||
"info": lib_plankton.translate.get(
|
||||
"help.args.send_ok_notifications",
|
||||
{
|
||||
"condition_name": lib_plankton.translate.get("conditions.ok"),
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
"language": new lib_plankton.args.class_argument(
|
||||
|
|
@ -182,6 +187,20 @@ async function main(
|
|||
"info": lib_plankton.translate.get("help.args.time_to_live"),
|
||||
}
|
||||
),
|
||||
"verbosity": new lib_plankton.args.class_argument(
|
||||
{
|
||||
"name": "verbosity",
|
||||
"type": lib_plankton.args.enum_type.integer,
|
||||
"kind": lib_plankton.args.enum_kind.volatile,
|
||||
"mode": lib_plankton.args.enum_mode.replace,
|
||||
"default": 1,
|
||||
"parameters": {
|
||||
"indicators_long": ["verbosity"],
|
||||
"indicators_short": ["v"],
|
||||
},
|
||||
"info": lib_plankton.translate.get("help.args.verbosity"),
|
||||
}
|
||||
),
|
||||
}
|
||||
);
|
||||
const args : Record<string, any> = arg_handler.read(
|
||||
|
|
@ -189,6 +208,22 @@ async function main(
|
|||
process.argv.slice(2).join(" ")
|
||||
);
|
||||
|
||||
// setup logging
|
||||
lib_plankton.log.conf_push(
|
||||
[
|
||||
new lib_plankton.log.class_channel_minlevel(
|
||||
new lib_plankton.log.class_channel_stdout(),
|
||||
[
|
||||
lib_plankton.log.enum_level.debug,
|
||||
lib_plankton.log.enum_level.info,
|
||||
lib_plankton.log.enum_level.notice,
|
||||
lib_plankton.log.enum_level.warning,
|
||||
lib_plankton.log.enum_level.error,
|
||||
][Math.min(4, args["verbosity"])]
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
// exec
|
||||
if (args.show_help) {
|
||||
process.stdout.write(
|
||||
|
|
@ -211,6 +246,7 @@ async function main(
|
|||
};
|
||||
const check_kind_implementations : Record<string, _heimdall.check_kinds.type_check_kind> = {
|
||||
"http_request": _heimdall.check_kinds.http_request.check_kind_implementation(),
|
||||
"file_state": _heimdall.check_kinds.file_state.check_kind_implementation(),
|
||||
};
|
||||
if (args["show_schema"]) {
|
||||
process.stdout.write(
|
||||
|
|
@ -308,6 +344,13 @@ async function main(
|
|||
// do nothing
|
||||
}
|
||||
else {
|
||||
let old_item_state : (null | _heimdall.type_item_state);
|
||||
|
||||
const last_notification_timestamp : (null | int) = await _heimdall.state_repository.get_last_notification_timestamp(
|
||||
database_path,
|
||||
check.name
|
||||
);
|
||||
|
||||
const rows : Array<
|
||||
{
|
||||
timestamp : int;
|
||||
|
|
@ -319,29 +362,19 @@ async function main(
|
|||
check.name,
|
||||
(check.threshold + 1),
|
||||
);
|
||||
|
||||
// TODO: type
|
||||
let old_item_state : (null | _heimdall.type_item_state);
|
||||
|
||||
const last_notification_timestamp : (null | int) = await _heimdall.state_repository.get_last_notification_timestamp(
|
||||
database_path,
|
||||
check.name
|
||||
);
|
||||
|
||||
if (rows.length <= 0) {
|
||||
old_item_state = null;
|
||||
}
|
||||
else {
|
||||
last_notification_timestamp = null;
|
||||
let count : int = 1;
|
||||
rows.slice(1).some(
|
||||
(row) => {
|
||||
if (row.condition === rows[0].condition) {
|
||||
count += 1;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -351,17 +384,6 @@ async function main(
|
|||
else {
|
||||
// do nothing
|
||||
}
|
||||
rows.some(
|
||||
(row) => {
|
||||
if (row.notification_sent) {
|
||||
last_notification_timestamp = row.timestamp;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
old_item_state = {
|
||||
"timestamp": rows[0].timestamp,
|
||||
"condition": rows[0].condition,
|
||||
|
|
@ -369,7 +391,7 @@ async function main(
|
|||
"last_notification_timestamp": last_notification_timestamp,
|
||||
}
|
||||
|
||||
const timestamp : int = Math.floor(Date.now() / 1000);
|
||||
const timestamp : int = _heimdall.get_current_timestamp();
|
||||
const due : boolean = (
|
||||
(old_item_state === null)
|
||||
||
|
||||
|
|
|
|||
|
|
@ -519,10 +519,13 @@ namespace _heimdall.order
|
|||
throw new Error("circular dependency detected")
|
||||
}
|
||||
else {
|
||||
const order_raw = lib_plankton.json.decode(await lib_plankton.file.read(path));
|
||||
const order_raw : {
|
||||
includes ?: Array<string>;
|
||||
checks ?: Array<any>;
|
||||
} = lib_plankton.json.decode(await lib_plankton.file.read(path));
|
||||
let includes : Array<string> = (
|
||||
("includes" in order_raw)
|
||||
? order_raw["includes"]
|
||||
? order_raw.includes
|
||||
: []
|
||||
);
|
||||
for (let index = 0; index < includes.length; index += 1) {
|
||||
|
|
@ -541,9 +544,9 @@ namespace _heimdall.order
|
|||
}
|
||||
)
|
||||
if (! ("checks" in order_raw)) {
|
||||
order_raw["checks"] = [];
|
||||
order_raw.checks = [];
|
||||
}
|
||||
order_raw["checks"].extend(
|
||||
order_raw.checks = order_raw.checks.concat(
|
||||
sub_order.checks
|
||||
.map(
|
||||
check => Object.assign(
|
||||
|
|
@ -561,7 +564,7 @@ namespace _heimdall.order
|
|||
sub_order.checks
|
||||
)
|
||||
);
|
||||
order_raw["includes"] = [];
|
||||
order_raw.includes = [];
|
||||
}
|
||||
return normalize_root(
|
||||
check_kind_implementations,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
"source/logic/notification_kinds/console.ts",
|
||||
"source/logic/check_kinds/_abstract.ts",
|
||||
"source/logic/check_kinds/http_request.ts",
|
||||
"source/logic/check_kinds/file_state.ts",
|
||||
"source/logic/state_repository.ts",
|
||||
"source/logic/order.ts",
|
||||
"source/logic/main.ts"
|
||||
|
|
@ -60,6 +61,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"active": false,
|
||||
"name": "node_modules",
|
||||
"type": "copy",
|
||||
"parameters": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue