An open API service indexing awesome lists of open source software.

https://github.com/phlx0/postmortem

Incident Timeline Builder from Git + Logs
https://github.com/phlx0/postmortem

alerts automation cli devops error-tracking git incident-management microservice monitoring observability open-source postmortem productivity python sentry site-reliability-engineering

Last synced: 11 days ago
JSON representation

Incident Timeline Builder from Git + Logs

Awesome Lists containing this project

README

          

# ๐Ÿ” postmortem

**When production breaks, stop guessing. Start knowing.**

[![CI](https://img.shields.io/github/actions/workflow/status/phlx0/postmortem/ci.yml?style=flat-square&label=CI)](https://github.com/phlx0/postmortem/actions)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue?style=flat-square&logo=python&logoColor=white)](https://python.org)
[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)

_Stitches together git history, file hotspots, and Sentry errors
into a shareable incident report โ€” in seconds._

```bash
postmortem --since 2h --output markdown --out-file incident.md
```

---

## Why postmortem?

Production is down. You need to know what changed and when โ€” fast.

That means opening GitHub, scanning commits, cross-referencing deploy times, and asking teammates "did anyone push anything?" โ€” all while the clock is ticking.

postmortem does it in one command.

```
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
๐Ÿ” postmortem ยท my-api
Since 2h ยท 19:58 UTC
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

๐Ÿ”ฅ File Hotspots

โ– โ– โ–  payments.py changed 4x risk 94%
coupled: db.py utils.py
โ– โ–  db.py changed 3x risk 71%

โ”€โ”€ Sat 07 Mar 2026 โ”€โ”€

17:58 โš  [ERROR] NullPointerException in PaymentService.charge() โ† Sentry
payments-api ยท 142 occurrences

18:21 โ— fix: patch null pointer in payment handler [3a7f2b1] โ† alice
โ†ณ src/payments/handler.py
โ†ณ tests/test_payments.py

19:08 โ‡„ Merge branch 'feature/stripe-v3' into main [9c1e4fd] โ† bob
โ†ณ src/stripe/client.py โ†ณ src/stripe/webhooks.py โ†ณ โ€ฆ +4

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
6 events ยท 2 authors ยท 1 Sentry error ยท top hotspot: payments.py
```

---

## Installation

postmortem installs into an isolated virtualenv at `~/.postmortem` and adds itself to your `$PATH` automatically. Open a new terminal and you're ready.

**Linux / macOS**

```bash
curl -sSL https://raw.githubusercontent.com/phlx0/postmortem/main/install.sh | bash
```

**Windows (PowerShell)**

```powershell
irm https://raw.githubusercontent.com/phlx0/postmortem/main/install.ps1 | iex
```

**From source** (edits apply instantly โ€” no reinstall needed)

```bash
git clone https://github.com/phlx0/postmortem
cd postmortem
bash install.sh # or: .\install.ps1 on Windows
```

**Requires:** Python 3.11+, git

```bash
postmortem --version # verify install
bash install.sh --uninstall # remove cleanly
```

---

## Commands

### Basic usage

```bash
postmortem # last 2 hours, current repo
postmortem --since 30m # last 30 minutes
postmortem --since 1d # last day
postmortem --since 4h --repo /path/to/repo # different repo
```

### Generate a shareable report

```bash
postmortem --since 2h --output markdown --out-file incident.md
```

Paste directly into a GitHub issue or Slack. The report includes a TL;DR table, file hotspot rankings, Sentry errors, and the full commit timeline with collapsible file diffs.

### Sentry integration

```bash
export SENTRY_TOKEN=sntrys_...
export SENTRY_ORG=my-org
export SENTRY_PROJECT=api # optional โ€” searches all projects if omitted

postmortem --since 2h
```

Or pass inline:

```bash
postmortem --since 2h --sentry-org my-org --sentry-token sntrys_...
```

### All flags

| Flag | Default | Description |
| ------------------ | ----------------- | --------------------------------------------- |
| `--since`, `-s` | `2h` | How far back to look: `30m`, `2h`, `1d`, `1w` |
| `--repo`, `-r` | `.` | Path to a git repository |
| `--output`, `-o` | `terminal` | Output format: `terminal` or `markdown` |
| `--out-file`, `-f` | stdout | Write output to a file |
| `--no-color` | false | Disable ANSI colours |
| `--sentry-token` | `$SENTRY_TOKEN` | Sentry auth token |
| `--sentry-org` | `$SENTRY_ORG` | Sentry organisation slug |
| `--sentry-project` | `$SENTRY_PROJECT` | Sentry project slug |
| `--version`, `-v` | | Show version and exit |

---

## What's in the report

### ๐Ÿ”ฅ File hotspots

Pure git analysis โ€” no config needed. Ranks every file touched during the window by:

- **Change frequency** โ€” how many times it was modified
- **Recency** โ€” changes in the last 25% of the window score higher
- **Coupling** โ€” files that always change together are a hidden coordination risk

The coupling column is often the most useful: if `payments.py` and `db.py` consistently appear in the same commits but aren't directly imported by each other, that's a hidden dependency worth knowing about.

### ๐Ÿ”ด Sentry errors

Surfaces issues whose _last seen_ time falls inside the incident window. Requires a read-scope auth token โ€” see [Sentry setup](#sentry-integration) above.

### ๐Ÿ“‹ Git timeline

Commits, merges, and tags in chronological order, each with author, SHA, and the list of files changed. Merges are labelled separately so you can spot integration points at a glance.

---

## Project structure

```
postmortem/
โ”œโ”€โ”€ cli.py Click entry point โ€” stays thin
โ”œโ”€โ”€ pipeline.py Wires collectors โ†’ Timeline
โ”œโ”€โ”€ models.py Event, Timeline, HotspotFile โ€” pure data
โ”œโ”€โ”€ collectors/
โ”‚ โ”œโ”€โ”€ __init__.py BaseCollector ABC
โ”‚ โ”œโ”€โ”€ git.py Commits, merges, tags
โ”‚ โ”œโ”€โ”€ hotspot.py File frequency + coupling analysis
โ”‚ โ””โ”€โ”€ sentry.py Sentry Issues API
โ”œโ”€โ”€ renderers/
โ”‚ โ”œโ”€โ”€ __init__.py BaseRenderer ABC
โ”‚ โ”œโ”€โ”€ terminal.py ANSI terminal output
โ”‚ โ””โ”€โ”€ markdown.py GitHub-flavoured incident report
โ””โ”€โ”€ utils/
โ””โ”€โ”€ time.py "2h" โ†’ datetime
```

### Adding a collector

```python
# postmortem/collectors/datadog.py
from postmortem.collectors import BaseCollector
from postmortem.models import Event, EventKind

class DatadogCollector(BaseCollector):
def collect(self) -> list[Event]:
# hit the Datadog API, return Events
...
```

Register it in `pipeline.py`. That's it.

### Planned collectors

- [ ] GitHub Actions โ€” CI run pass/fail per commit
- [ ] Datadog / Grafana โ€” annotation and alert events
- [ ] PagerDuty โ€” on-call alerts in the window
- [ ] Heroku / Railway โ€” deploy events

PRs welcome.

---

## Development

```bash
git clone https://github.com/phlx0/postmortem
cd postmortem
bash install.sh # editable install โ€” changes apply immediately

pytest # run all tests
ruff check postmortem # lint
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.

---

Made with โ˜• ยท [MIT License](LICENSE)