Add comprehensive README

Documents mid_delay.py usage, all options, status categories,
multi-file parsing, output format, and MID lifecycle events.
This commit is contained in:
2026-04-06 14:20:50 +08:00
parent 7219647078
commit a60a6c18b3

146
README.md Normal file
View File

@@ -0,0 +1,146 @@
# ESA-Script
Utility scripts for analyzing Cisco Email Security Appliance (ESA) mail gateway log files.
## Requirements
- Python 3.8+
- No external dependencies — standard library only
## Log File Format
ESA mail logs follow the naming pattern:
```
mail.current # active log (rotated periodically)
mail.@20260303T005159.s # archived log with timestamp
```
---
## Scripts
### `mid_delay.py`
Parses ESA mail logs and reports MIDs (Message IDs) whose delivery took longer than a specified threshold. Results are sorted by delay, longest first.
#### Basic Usage
```bash
python3 mid_delay.py mail.current
python3 mid_delay.py mail.@20260303T005159.s
python3 mid_delay.py mail* # multiple files via shell glob
```
#### Options
| Option | Short | Default | Description |
|---|---|---|---|
| `--threshold` | `-t` | `0.5` | Minimum delay in minutes to report |
| `--top` | `-n` | `20` | Limit number of results shown |
| `--status` | `-s` | (all) | Filter by status category; also shows Status column |
| `--pending` | | off | Show only MIDs still in-queue (no finish event) |
| `--no-partial` | | off | Exclude MIDs with no `Start MID` line in this log |
| `--include-aborted` | | off | Include MIDs that were aborted (excluded by default) |
| `--start` | | (none) | Only include MIDs whose start time is on or after this datetime |
#### Status Categories (`--status`)
| Value | Description |
|---|---|
| `delayed` | Had an explicit `Delayed:` retry event in the log |
| `slow_done` | No retry event, but start→finish exceeded threshold; delivered successfully |
| `slow_aborted` | No retry event, but start→finish exceeded threshold; delivery aborted |
| `all` | All of the above; forces the Status column to appear |
#### `--start` Datetime Format
Accepts either:
- `YYYY-MM-DD` — matches from the start of that day
- `YYYY-MM-DD HH:MM:SS` — matches from that exact second
```bash
python3 mid_delay.py mail* --start 2026-03-03
python3 mid_delay.py mail* --start "2026-03-03 14:30:00"
```
#### Output Columns
```
MID Start End/Delayed Delay(m) Reason
```
- **MID** — Message ID
- **Start** — Time of `Start MID` event. Marked with `*` if the original `Start MID` line was not found in the parsed log(s) and a `Delivery start` event was used as a fallback — delay figures for these may be unreliable.
- **End/Delayed** — Time of `Message finished` event, or first `Delayed:` retry event if still pending
- **Delay(m)** — Delay in minutes
- **Status** — Only shown when `--status` is specified
- **Reason** — First delay reason or abort reason found for the MID
#### Multi-File Parsing
When multiple files are provided (e.g. `mail*`), they are processed in sorted order so that archived logs (`mail.@...`) are parsed before `mail.current`. All files share a single MID tracking table, so a message that starts in one file and finishes in another is tracked correctly.
```bash
python3 mid_delay.py mail*
python3 mid_delay.py mail.@20260101T000000.s mail.@20260201T000000.s mail.current
```
#### Examples
```bash
# Default: top 20 delayed MIDs, threshold 0.5 min, aborted excluded
python3 mid_delay.py mail.current
# Top 50 MIDs delayed more than 5 minutes across all log files
python3 mid_delay.py mail* -t 5 -n 50
# Only MIDs with explicit retry events, show Status column
python3 mid_delay.py mail.current -s delayed
# MIDs still pending delivery (never finished in this log)
python3 mid_delay.py mail.current --pending -t 0
# Exclude MIDs without a Start MID line (carried over from prior log)
python3 mid_delay.py mail.current --no-partial
# Include aborted MIDs in results
python3 mid_delay.py mail* --include-aborted
# Only MIDs that started on or after a specific date/time
python3 mid_delay.py mail* --start "2026-03-03 12:00:00"
# Combine filters: slow delivered MIDs after noon, top 10
python3 mid_delay.py mail* -s slow_done --start "2026-03-03 12:00:00" -n 10
```
---
### `delay.py`
Filters and prints lines containing `ERROR` from `mail.@20260303T005159.s`.
```bash
python3 delay.py
```
---
## MID Lifecycle Tracked
```
Start MID → [Delayed: retry events] → Message finished (done / aborted)
↑
Delivery start (fallback if Start MID not in log)
```
Events recognized:
| Log Event | Purpose |
|---|---|
| `Start MID <id> ICID` | Message ingestion start |
| `Delivery start DCID <d> MID <id>` | Delivery attempt start (fallback start time) |
| `Delayed: DCID <d> MID <id> ...` | Delivery retry/delay event |
| `Message finished MID <id> done\|aborted` | Final delivery outcome |
| `Message aborted MID <id> <reason>` | Abort reason capture |
| `MID <id> rewritten to MID <id>` | MID rewrite tracking |