Skip to content

Commit

Permalink
feat(agent): add label-rules variables to alerts (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreDemailly authored Apr 9, 2024
1 parent 756000e commit a2745e8
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 6 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 MyUnisoft
Copyright (c) 2023-2024 MyUnisoft

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion src/agent/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,5 @@ export function cleanRulesInDb(
export function getOldestLabelTimestamp(ruleId: number, label: string) {
return (getDB()
.prepare("SELECT timestamp FROM ruleLabels WHERE key = ? AND ruleId = ? ORDER BY timestamp ASC LIMIT 1")
.get(label, ruleId) as Pick<DbRuleLabel, "timestamp">).timestamp;
.get(label, ruleId) as Pick<DbRuleLabel, "timestamp">)?.timestamp;
}
13 changes: 11 additions & 2 deletions src/agent/src/notifiers/rules.notifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ import * as utils from "../utils";
const kIdentifier = Symbol("ruleNotifier");

export interface RuleNotifierAlert extends Alert {
rule: DbRule & { labels: Record<string, string>; oldestLabelTimestamp: number | null };
rule: DbRule & {
labels: Record<string, string>;
oldestLabelTimestamp: number | null;
labelCount: number;
labelMatchCount: number;
labelMatchPercent: number | undefined;
};
notif: Pick<DbAlertNotif, "alertId" | "notifierId">;
error?: Error;
}
Expand Down Expand Up @@ -131,7 +137,10 @@ export class RuleNotifier extends Notifier<RuleNotifierAlert> {
interval: ruleConfig.alert.on.interval,
label: { ...new StreamSelector(ruleConfig.logql).kv(), ...rule.labels },
severity: ruleConfig.alert.severity,
lokiUrl: await utils.getLokiUrl(rule, ruleConfig)
lokiUrl: await utils.getLokiUrl(rule, ruleConfig),
labelCount: rule.labelCount,
labelMatchCount: rule.labelMatchCount,
labelMatchPercent: rule.labelMatchPercent
};
}
}
13 changes: 12 additions & 1 deletion src/agent/src/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export class Rule {
#logger: Logger;
#lastFetchedStream: Record<string, string> | null = null;
#now: number;
#labelCount: number = 0;
#labelMatchCount: number = 0;
#labelMatchPercent: number | undefined;

constructor(rule: SigynInitializedRule, options: RuleOptions) {
const { logger } = options;
Expand Down Expand Up @@ -70,7 +73,10 @@ export class Rule {
return {
...rule,
labels: formattedLabels,
oldestLabelTimestamp: this.config.alert.on.label ? getOldestLabelTimestamp(rule.id, this.config.alert.on.label) : null
oldestLabelTimestamp: this.config.alert.on.label ? getOldestLabelTimestamp(rule.id, this.config.alert.on.label) : null,
labelCount: this.#labelCount,
labelMatchCount: this.#labelMatchCount,
labelMatchPercent: this.#labelMatchPercent
};
}

Expand Down Expand Up @@ -236,7 +242,12 @@ export class Rule {

this.#logger.info(`[${rule.name}](state: reached|actual: ${labels.length}|count: ${count ?? "x"}|thresholdCount: ${labelMatchCount}|percentThreshold: ${percentThreshold}|actualPercent: ${labelMatchCount / labels.length * 100})`);

this.#labelCount = labels.length;
this.#labelMatchCount = labelMatchCount;

if (percentThreshold) {
this.#labelMatchPercent = labelMatchCount / labels.length * 100;

return labelMatchCount / labels.length * 100 >= percentThreshold!;
}

Expand Down
5 changes: 4 additions & 1 deletion src/config/docs/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ Both can be setting up with an object as following:
## Variables

You can use any of theses variables (both for `title` & `content`), surrounding with `{}` (see example below):
You can use any of theses variables (both in `title` & `content`), surrounding with `{}` (see example below):
- `ruleName`
- `logql`
- `count` (count of logs retrievied within the interval)
- `counter`
- `threshold` (`alert.on.count`)
- `interval`
- `lokiUrl`
- `labelCount` (count label based rules)
- `labelMatchCount` (label based rules)
- `labelMatchPercent` (percent label based rules)

> [!NOTE]
> You can use hyperlink with Markdown i.e. `[See logs]({lokiUrl})`.
Expand Down
3 changes: 3 additions & 0 deletions src/notifiers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@ export interface ExecuteWebhookData {
rules: string;
}
rules?: string;
labelCount: number;
labelMatchCount: number;
labelMatchPercent?: number;
}

0 comments on commit a2745e8

Please sign in to comment.