-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e057759
commit 265d656
Showing
7 changed files
with
995 additions
and
429 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
# Composite Rules | ||
|
||
Composite rules are based on rules and allow to send alert when a given set of rules triggers too much alert for a given interval. | ||
|
||
Composite rules takes an array of object in the `compositeRules` root config field. | ||
|
||
## Summary | ||
|
||
- [Example Configuration](#example-configuration) | ||
- [Schema Properties](#schema-properties) | ||
- [`name`](#name) | ||
- [`notifiers`](#notifiers) | ||
- [`include`](#include) | ||
- [`exclude`](#exclude) | ||
- [`notifCount`](#notifcount) | ||
- [`ruleCountThreshold`](#rulecountthreshold) | ||
- [`interval`](#interval) | ||
- [`template`](#template) (See [Templates](./templates.md)) | ||
- [`throttle`](#throttle) (See [Throttle](./throttle.md)) | ||
- [`muteRules`](#muteRules) | ||
- [`muteDuration`](#muteDuration) | ||
|
||
## Example configuration | ||
|
||
```json | ||
{ | ||
"compositeRules": [ | ||
{ | ||
"name": "Composite Rule", | ||
"template": { | ||
"title": "title", | ||
"content": ["content"] | ||
}, | ||
"notifCount": 6, | ||
"throttle": { | ||
"interval": "5m", | ||
"count": 3 | ||
}, | ||
"ruleCountThreshold": 2, | ||
"muteRules": true | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## Schema Properties | ||
|
||
### `name` | ||
|
||
The name of the composite rule. Must be unique between each composite rule. | ||
|
||
| Type | Required | | ||
|------------------------|----------| | ||
| `string` | ✔️ | | ||
|
||
### `notifiers` | ||
|
||
Defines the notifiers to send alerts on. | ||
|
||
| Type | Required | Default | | ||
|-----------|----------|--------------------------------| | ||
| `string[]` | ❌ | All root configured notifiers | | ||
|
||
**Examples** | ||
```json | ||
{ | ||
..., | ||
"notifiers": { | ||
"slack": { | ||
"notifier": "slack", | ||
"webhookUrl": "https://hooks.slack.com/services/aaa/bbb" | ||
}, | ||
"discord": { | ||
"notifier": "discord", | ||
"webhookUrl": "https://discord.com/api/webhooks/aaa/bbb" | ||
} | ||
}, | ||
"compositeRules": [ | ||
{ | ||
"name": "Send alerts to Slack notifier only", | ||
"notifiers": ["slack"], | ||
... | ||
}, | ||
{ | ||
"name": "notifiers are skipped: send alerts to both Slack & Discord", | ||
... | ||
} | ||
], | ||
... | ||
} | ||
``` | ||
|
||
### `include` | ||
|
||
A list of rule to monitor, you can use glob i.e `My Service -*`. | ||
By default, the composite rule is based on each rule. | ||
|
||
| Type | Required | | ||
|------------|----------| | ||
| `string[]` | ❌ | | ||
|
||
### `exclude` | ||
|
||
A list of rule to exclude from monitoring, you can use glob i.e `My Service -*`. | ||
|
||
| Type | Required | | ||
|------------|----------| | ||
| `string[]` | ❌ | | ||
|
||
### `notifCount` | ||
|
||
The minimum alert to have been sent from each rules to triggers the composite rule. | ||
|
||
| Type | Required | | ||
|----------|----------| | ||
| `number` | ✔️ | | ||
|
||
### `ruleCountThreshold` | ||
|
||
The minimum count of matching rules to triggers an alert to unlock composite rule. | ||
For instance, if you have 10 rules and `ruleCountThreshold` is 7, it means 7 rules must triggers an alert before the composite rule triggers. | ||
|
||
| Type | Required | | ||
|----------|----------| | ||
| `number` | ❌ | | ||
|
||
### `interval` | ||
|
||
A duration (i.e `1d`, `15m`) that represents the maximum interval date to count rules alerts. | ||
|
||
| Type | Required | Default | | ||
|----------|----------|---------| | ||
| `string` | ❌ | `1d` | | ||
|
||
### `template` | ||
|
||
See [Templates](./templates.md) | ||
|
||
> [!NOTE] | ||
> `template` is **required**. | ||
### `throttle` | ||
|
||
See [Throttle](./throttle.md) | ||
|
||
### `muteRules` | ||
|
||
Weither matched rules should stop trigger alert when a higher-level composite rule triggers. | ||
|
||
| Type | Required | Default | | ||
|-----------|----------|---------| | ||
| `boolean` | ❌ | `false` | | ||
|
||
### `muteDuration` | ||
|
||
Defines the duration for which rules should be muted when `muteRules` is `true`. | ||
|
||
| Type | Required | Default | | ||
|----------|----------|---------| | ||
| `string` | ❌ | `30m` | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
# Interfaces | ||
|
||
```ts | ||
interface SigynConfig { | ||
loki: LokiConfig; | ||
notifiers: Record<string, { | ||
notifier: string; | ||
[key: string]: unknown; | ||
}>; | ||
rules: SigynRule[]; | ||
templates?: Record<string, SigynAlertTemplate>; | ||
extends?: string[]; | ||
missingLabelStrategy: "ignore" | "error"; | ||
defaultSeverity: AlertSeverity; | ||
selfMonitoring?: SigynSelfMonitoring; | ||
compositeRules?: SigynCompositeRule[]; | ||
} | ||
|
||
interface SigynInitializedConfig { | ||
loki: LokiConfig; | ||
notifiers: Record<string, { | ||
notifier: string; | ||
[key: string]: unknown; | ||
}>; | ||
rules: SigynInitializedRule[]; | ||
templates?: Record<string, SigynInitializedTemplate>; | ||
extends?: string[]; | ||
missingLabelStrategy: "ignore" | "error"; | ||
defaultSeverity: AlertSeverity; | ||
selfMonitoring?: SigynInitializedSelfMonitoring; | ||
compositeRules?: SigynInitializedCompositeRule[]; | ||
} | ||
|
||
interface PartialSigynConfig { | ||
loki: LokiConfig; | ||
notifiers: Record<string, { | ||
notifier: string; | ||
[key: string]: unknown; | ||
}>; | ||
rules: PartialSigynRule[]; | ||
templates?: Record<string, SigynAlertTemplate>; | ||
extends?: string[]; | ||
missingLabelStrategy?: "ignore" | "error"; | ||
defaultSeverity?: AlertSeverity; | ||
selfMonitoring?: SigynSelfMonitoring; | ||
compositeRules?: SigynCompositeRule[]; | ||
} | ||
|
||
type ExtendedSigynConfig = Pick<SigynConfig, "templates" | "rules">; | ||
|
||
interface LokiConfig { | ||
apiUrl: string; | ||
} | ||
|
||
interface SigynRule { | ||
name: string; | ||
logql: string | { query: string; vars?: Record<string, string | string[]> }; | ||
polling: string | string[]; | ||
pollingStrategy: "bounded" | "unbounded"; | ||
alert: SigynAlert; | ||
disabled: boolean; | ||
notifiers: string[]; | ||
labelFilters?: Record<string, string[]>; | ||
} | ||
|
||
interface SigynInitializedRule { | ||
name: string; | ||
logql: string; | ||
polling: string | string[]; | ||
pollingStrategy: "bounded" | "unbounded"; | ||
alert: SigynInitializedAlert; | ||
disabled: boolean; | ||
notifiers: string[]; | ||
labelFilters?: Record<string, string[]>; | ||
} | ||
|
||
interface PartialSigynRule { | ||
name: string; | ||
logql: string | { query: string; vars?: Record<string, string | string[]> }; | ||
polling?: string | string[]; | ||
pollingStrategy?: "bounded" | "unbounded"; | ||
alert: PartialSigynAlert; | ||
disabled?: boolean; | ||
notifiers?: string[]; | ||
labelFilters?: Record<string, string[]>; | ||
} | ||
|
||
type NotifierFormattedSigynRule = Omit<SigynInitializedRule, "alert"> & { | ||
alert: Omit<SigynInitializedAlert, "template"> | ||
}; | ||
|
||
type AlertSeverity = | ||
"critical" | | ||
"error" | "major" | | ||
"warning" | "minor" | | ||
"information" | "info" | "low"; | ||
|
||
interface SigynAlert { | ||
on: { | ||
count?: string | number; | ||
interval?: string; | ||
label?: string; | ||
value?: string; | ||
valueMatch?: string; | ||
percentThreshold?: number; | ||
minimumLabelCount?: number; | ||
}, | ||
template: string | SigynAlertTemplate; | ||
severity: Extract<AlertSeverity, "critical" | "error" | "warning" | "information">; | ||
throttle?: { | ||
count: number; | ||
interval: string; | ||
activationThreshold?: number; | ||
labelScope?: string[]; | ||
}; | ||
} | ||
|
||
interface SigynInitializedAlert { | ||
on: { | ||
count?: string | number; | ||
interval?: string; | ||
label?: string; | ||
value?: string; | ||
valueMatch?: string; | ||
percentThreshold?: number; | ||
minimumLabelCount?: number; | ||
}, | ||
template: SigynInitializedTemplate; | ||
severity: Extract<AlertSeverity, "critical" | "error" | "warning" | "information">; | ||
throttle?: { | ||
count: number; | ||
interval: string; | ||
activationThreshold: number; | ||
labelScope: string[]; | ||
}; | ||
} | ||
|
||
interface PartialSigynAlert { | ||
on: { | ||
count?: string | number; | ||
interval?: string; | ||
label?: string; | ||
value?: string; | ||
valueMatch?: string; | ||
percentThreshold?: number; | ||
minimumLabelCount?: number; | ||
}, | ||
template: string | SigynAlertTemplate; | ||
severity?: AlertSeverity; | ||
throttle?: { | ||
count?: number; | ||
interval: string; | ||
activationThreshold?: number; | ||
labelScope?: string[]; | ||
}; | ||
} | ||
|
||
interface SigynAlertTemplateExtendedContent { | ||
before?: string[]; | ||
after?: string[]; | ||
} | ||
|
||
interface SigynAlertTemplate { | ||
title?: string; | ||
content?: string[] | SigynAlertTemplateExtendedContent; | ||
extends?: string; | ||
} | ||
|
||
interface SigynInitializedTemplate { | ||
title?: string; | ||
content?: string[]; | ||
} | ||
|
||
interface SigynSelfMonitoring { | ||
template: string | SigynInitializedTemplate; | ||
notifiers: string[]; | ||
errorFilters?: string[]; | ||
ruleFilters?: string[]; | ||
minimumErrorCount?: number; | ||
throttle?: { | ||
count?: number; | ||
interval: string; | ||
activationThreshold?: number; | ||
}; | ||
} | ||
|
||
interface SigynInitializedSelfMonitoring { | ||
template: SigynInitializedTemplate; | ||
notifiers: string[]; | ||
errorFilters?: string[]; | ||
ruleFilters?: string[]; | ||
minimumErrorCount?: number; | ||
throttle?: { | ||
count: number; | ||
interval: string; | ||
activationThreshold: number; | ||
}; | ||
} | ||
|
||
interface SigynCompositeRule { | ||
name: string; | ||
include?: string[]; | ||
exclude?: string[]; | ||
notifCount: number; | ||
ruleCountThreshold?: number; | ||
interval?: string; | ||
template: string | SigynAlertTemplate; | ||
notifiers?: string[]; | ||
throttle?: { | ||
count?: number; | ||
interval: string; | ||
activationThreshold?: number; | ||
}; | ||
} | ||
|
||
interface SigynInitializedCompositeRule { | ||
name: string; | ||
rules: string[]; | ||
notifCount: number; | ||
ruleCountThreshold?: number; | ||
interval: string; | ||
template: string | SigynInitializedTemplate; | ||
notifiers: string[]; | ||
throttle?: { | ||
count: number; | ||
interval: string; | ||
activationThreshold: number; | ||
}; | ||
} | ||
``` | ||
> [!NOTE] | ||
> `SigynInitializedConfig` represents the config after initialization. | ||
> For instance, given a rule with a `logql` object with `query` & `vars`, the rule is updated upon initialization then `logql` is always as **string**. | ||
> [!NOTE] | ||
> `PartialSigynConfig`, `PartialSigynRule` and `PartialSigynAlert` are the allowed types to **validate** config. | ||
> These types have extra optional fields that are set by their default values upon initialization (`initConfig()`). |
Oops, something went wrong.