Skip to content

Commit

Permalink
docs(config): improve docs (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreDemailly authored Nov 20, 2023
1 parent e057759 commit 265d656
Show file tree
Hide file tree
Showing 7 changed files with 995 additions and 429 deletions.
434 changes: 5 additions & 429 deletions src/config/README.md

Large diffs are not rendered by default.

160 changes: 160 additions & 0 deletions src/config/docs/composite-rules.md
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` |
237 changes: 237 additions & 0 deletions src/config/docs/interfaces.md
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()`).
Loading

0 comments on commit 265d656

Please sign in to comment.