aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2026-07-21 13:44:06 +0300
committerJan Tuomi <jan@jantuomi.fi>2026-07-21 13:44:47 +0300
commit9c54af24fb787ca505c0b6fc8abcd6f3f43d753a (patch)
treebb619eef10dc580bb852eecf417e112990bce776 /README.md
parent415f77f05ae648bb2a2640971f3268e1fae59b06 (diff)
0.4.0: Add match clustering
Diffstat (limited to 'README.md')
-rw-r--r--README.md29
1 files changed, 20 insertions, 9 deletions
diff --git a/README.md b/README.md
index 4d1ffbc..f3d6cc9 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,8 @@ previous run (tracked per-file, per-inode) and then exits.
- INI-style configuration (`pylogsentinel.conf`).
- Multiple named log sets (e.g. [logs.default], [logs.errors]) with per-set discovery via static paths or shell command
- Per-rule regular expressions with optional flags (`/pattern/i` style).
-- Per-rule or actions executed as shell commands with rich contextual environment variables.
+- Per-rule actions executed as shell commands with rich contextual environment variables.
+- Intelligent match clustering: nearby matches for the same rule are grouped into a single event to avoid redundant alerts.
- Reliable state tracking via inode-based files (`<inode>` in `state_dir`).
- Safe handling of truncation & rotation (offset reset if file shrinks).
- Strict lock file (`LOCK`) prevents concurrent overlapping runs.
@@ -128,14 +129,16 @@ Each action defines a shell `cmd` executed when a matching rule triggers. The sp
Environment variables available to the command:
-| Variable | Description |
-| ------------------ | ---------------------------------------------------------------------- |
-| `RULE_ID` | The rule identifier (e.g. `error`). |
-| `RULE_PATTERN` | The normalized pattern string (e.g. `/error/i`). |
-| `RULE_DESCRIPTION` | Description text or placeholder string if not provided. |
-| `FILE` | Absolute path of the log file where the match occurred. |
-| `LINE` | 1-based absolute line number within the file at time of scan. |
-| `CONTEXT` | Concatenated lines around the match (default radius 2 before & after). |
+| Variable | Description |
+| ------------------ | ---------------------------------------------------------------------------------------------------- |
+| `RULE_ID` | The rule identifier (e.g. `error`). |
+| `RULE_PATTERN` | The normalized pattern string (e.g. `/error/i`). |
+| `RULE_DESCRIPTION` | Description text or placeholder string if not provided. |
+| `FILE` | Absolute path of the log file where the match occurred. |
+| `LINE` | 1-based absolute line number of the first match in the cluster. |
+| `CONTEXT` | Contiguous block of lines spanning the cluster with surrounding context (default radius 5). |
+| `MATCH_COUNT` | Number of matching lines in the cluster (e.g. `1` for a single match, `3` for three grouped matches). |
+| `MATCHED_LINES` | Comma-separated 1-based line numbers of all matches in the cluster (e.g. `42` or `42,44,47`). |
Your `cmd` can reference these with typical shell expansion, for example:
@@ -144,6 +147,14 @@ Your `cmd` can reference these with typical shell expansion, for example:
cmd = printf "%s\n%s\n" "$RULE_DESCRIPTION" "$CONTEXT" | mail -s "Alert $RULE_ID: $FILE:$LINE" ops@example.com
```
+### Match Clustering
+
+When multiple lines match the same rule within a short span, they are grouped into a single cluster rather than triggering separate actions for each match. This avoids redundant alerts for cascading errors.
+
+Two matches are merged into the same cluster if the number of non-matching lines between them is at most the context radius (default 5). The cluster's context block spans from `context_radius` lines before the first match to `context_radius` lines after the last match — one contiguous block including any non-matching lines in between.
+
+Example with `context_radius = 5`: if errors appear on lines 10, 13, and 16 of a file, they form a single cluster (gaps of 2 and 2, both ≤ 5). The action fires once with `CONTEXT` covering lines 5–21, `MATCH_COUNT=3`, and `MATCHED_LINES=10,13,16`.
+
## State Tracking
For each processed file: