Rebuild an incident timeline from Grafana and PagerDuty

By General Input

Pick a time window and see deploys, alerts, pages and acknowledgements on one merged timeline, then let an agent write the postmortem for you.

Integrations

  • Grafana
  • PagerDuty
  • Notion
  • Linear

Type

App

Categories

  • Engineering
  • Operations

I want an app for assembling an incident timeline after something breaks. Today, reconstructing what happened means tabbing between Grafana and PagerDuty and copying timestamps into a doc by hand. This is a forensic surface a person opens on demand for a specific time window and scrubs through. It is not a scheduled report and nothing in it should run on a timer or a cron schedule.

The app opens on a window picker where I set a start time and an end time, and optionally narrow to a single service. Populate the service dropdown from the PagerDuty List Services handler so I am picking a real service rather than typing a name. When I confirm the window, the app assembles one merged vertical timeline from both systems.

The Grafana lane comes from Find Annotations, scoped to the selected time range, which gives me the deploy markers and manual annotations my team already records. The PagerDuty lane comes from List Incidents filtered to the same window and, when set, the chosen service. For every incident returned, also call List Alerts for Incident to get the individual alerts that were grouped into it, and List Log Entries for Incident to get the response record: when it was triggered, when someone acknowledged it, every escalation, every reassignment, and when it was resolved. Interleave all of it into a single chronological list. This merge is the entire point of the app, so acknowledgements and escalations must sit inline on the same timeline as the deploy and alert markers, never in a separate tab or a side by side pair of columns.

Normalize timestamps carefully, because the two systems do not agree on format. Grafana annotation times come back as epoch milliseconds and PagerDuty times come back as ISO 8601 strings. Convert both to a single timezone that I can set, and display each entry with its absolute time plus an offset relative to the start of the incident, for example 'plus 4m 12s'. Those relative offsets are what make a timeline readable, so do not omit them. Every entry needs a clear source badge showing whether it came from Grafana or PagerDuty, and entries that land within the same few seconds should be visually grouped rather than stacked as if they were separate moments.

Pull the alert rules covering the affected area with List Alert Rules. Be careful how you render these: an alert rule is configuration, not something that happened at a point in time, so putting rules directly on the timeline as events would be wrong and misleading. Instead show them in a context panel beside the timeline, listing which rules were watching this area during the window. Where a Grafana annotation or a PagerDuty alert can be matched to the rule that produced it, link the two so I can click from a firing on the timeline to the rule definition behind it. Note that this returns provisioned alert rules, so if it comes back empty, say the rule context is unavailable rather than implying no rules were watching.

Clicking any Grafana entry on the timeline should take me back to its source dashboard. Resolve the dashboard from the annotation's dashboard identifier using Search Dashboards and Folders, and show me the dashboard name and folder in the detail panel with a link that opens it in Grafana at the right place. If an annotation is not attached to any dashboard, say so plainly instead of rendering a dead link.

I need to add missing context inline, because the most important detail is usually the one nobody logged. From the timeline I can record a new Grafana annotation with Create Annotation, setting the text and the timestamp it belongs at, so the correction lives in Grafana for the next person and not just inside this app. I can also push a correction back to PagerDuty against a specific incident using Create Incident Note. Both write actions should show me exactly what will be recorded and where before anything is sent, and once written, the new entry appears on the timeline immediately without making me rebuild the window. Posting a PagerDuty note requires identifying the user it is posted as, so handle that in the handler rather than asking me for it every time.

Add a Draft postmortem button that kicks off a background agent against the assembled timeline. The agent reads the merged sequence, including my inline additions, and writes a structured postmortem covering four sections: a summary of what happened and the impact, the sequence of events built from the timeline with real timestamps, contributing factors, and concrete follow up actions. Hold the agent to what the timeline actually supports. It should be specific about detection and acknowledgement timing because the PagerDuty log entries genuinely provide that, and it should be explicit about gaps rather than inventing a cause where the evidence does not show one.

The agent publishes the writeup to Notion in two steps: Create a Page under a parent page or database I choose in settings to create the page with its title and properties, then Update Page Content as Markdown to push the full body in. Writing the body as markdown rather than assembling blocks by hand keeps the formatting of the sequence of events intact.

Every follow up action the agent identified gets filed as its own Linear issue through Create Issue, into a team I pick, one issue per action so they do not get buried as bullet points inside a doc nobody reopens. Each issue description should carry a short piece of the incident context and a link back to the published Notion postmortem, so an engineer picking up the ticket in three weeks knows what it came from.

Store the resulting links back in the app. The app keeps a list of every incident review it has assembled, and each row shows the time window, the service, the headline of what happened, a link to its Notion writeup, and its follow up issues with their current open or closed state so I can see at a glance which follow ups from past incidents are still outstanding. Because the postmortem agent runs in the background, show its progress on the row while it is working and surface a clear failure state if it could not finish, rather than leaving the row looking as though it never started.

Two things to handle gracefully. Both Grafana and PagerDuty retain history for a limited period, so if I pick a window that returns nothing or only partial data, say the history is unavailable or incomplete for that range instead of rendering an empty timeline that reads like a quiet night. And if only one of the two systems is connected, still render the lane you can reach and tell me the other side is missing, rather than failing the whole view.

Related prompts

Explore more prompts
Catch feature flags that never got switched on in productionScreen chartered vessels for AIS gaps and sanctions red flagsCompare candidate store locations with drive time trade areasBrowse every competitor ad and build a Notion swipe fileWeekly alert noise review board for incident.io on-callMorning triage board for your Kernel browser agent runsTrack every half finished LaunchDarkly rollout in one boardAudience persona studio for brand and product marketersFind the customers stuck contacting support again and againArtwork desk for the Notion posts still missing an image