Skip to main content
Per una guida più dettagliata sull’integrazione con PagerDuty, fai clic qui.
1

Distribuire un bridge per webhook

Crea un piccolo servizio che rimanga in ascolto degli eventi PagerDuty incident.resolved e avvii una sessione Devin per scrivere il postmortem. Distribuiscilo come funzione serverless (AWS Lambda, Cloudflare Worker) o come container leggero:
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());

function verifySignature(req) {
  const secret = Buffer.from(req.headers['x-webhook-secret'] || '');
  const expected = Buffer.from(process.env.WEBHOOK_SECRET || '');
  if (!expected.length) throw new Error('WEBHOOK_SECRET environment variable is not set');
  if (secret.length !== expected.length) return false;
  return crypto.timingSafeEqual(secret, expected);
}

app.post('/pagerduty-resolved', async (req, res) => {
  if (!verifySignature(req)) return res.status(401).send('Bad signature');

  const event = req.body?.event;
  if (!event || event.event_type !== 'incident.resolved') {
    return res.sendStatus(200);
  }

  const incident = event.data;
  const title = incident.title || 'Unknown incident';
  const service = incident.service?.summary || 'unknown-service';
  const urgency = incident.urgency || 'high';
  const incidentUrl = incident.html_url || '';
  const createdAt = incident.created_at || '';
  const resolvedAt = incident.resolved_at || new Date().toISOString();

  const orgId = process.env.DEVIN_ORG_ID;
  const response = await fetch(
    `https://api.devin.ai/v3/organizations/${orgId}/sessions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      prompt: [
        `A PagerDuty incident has been resolved. Draft a postmortem.`,
        ``,
        `Incident: "${title}"`,
        `Service: ${service}`,
        `Urgency: ${urgency}`,
        `Created: ${createdAt}`,
        `Resolved: ${resolvedAt}`,
        `Incident URL: ${incidentUrl}`,
        ``,
        `Write a structured postmortem:`,
        `1. Use the Datadog MCP to pull logs and metrics for ${service} during the incident window`,
        `2. Identify the root cause — check for deploys, config changes, or upstream failures`,
        `3. Build a detailed timeline from first alert to resolution`,
        `4. List action items to prevent recurrence`,
        `5. Post the postmortem as a PR to our docs/postmortems/ directory`,
      ].join('\n'),
      tags: ['pagerduty-postmortem', `service:${service}`],
    }),
  });

  const { session_id } = await response.json();
  console.log(`Started postmortem session ${session_id} for: ${title}`);
  res.sendStatus(200);
});

app.listen(3000);
Crea un utente di servizio in Settings > Service Users su app.devin.ai con l’autorizzazione ManageOrgSessions. Copia il token API mostrato dopo la creazione e salvalo come DEVIN_API_KEY sul tuo servizio bridge. Imposta DEVIN_ORG_ID con l’ID della tua organizzazione — puoi ottenerlo chiamando GET https://api.devin.ai/v3/enterprise/organizations con il tuo token. Imposta WEBHOOK_SECRET su un segreto condiviso che configurerai anche in PagerDuty.
2

Configura PagerDuty

  1. In PagerDuty, vai a Services > [il tuo servizio] > Integrations
  2. Fai clic su Add Integration e seleziona Generic Webhooks (v3)
  3. Imposta Webhook URL sull’endpoint del bridge (ad esempio, https://your-bridge.example.com/pagerduty-resolved)
  4. In Custom Headers, aggiungi X-Webhook-Secret con lo stesso valore che hai salvato come WEBHOOK_SECRET
  5. In Event Subscription, filtra per il tipo di evento incident.resolved in modo che il postmortem venga attivato solo dopo la chiusura dell’incidente
Puoi anche sottoscrivere incident.acknowledged se vuoi che Devin inizi a raccogliere dati mentre l’incidente è ancora in corso, per poi finalizzare il postmortem alla risoluzione.
3

Collega gli MCP di osservabilità (facoltativo)

Devin scrive analisi post-mortem migliori quando può accedere ai tuoi dati di telemetria. Abilita uno o più MCP in modo che Devin possa recuperare dati reali per la finestra temporale dell’incidente:Datadog MCP — Vai a Settings > MCP Marketplace, trova Datadog, fai clic su Enable e inserisci le chiavi API/Application. Devin interrogherà log, metriche, eventi di deploy e cronologia dei monitor.Sentry MCP — Trova Sentry nel MCP Marketplace, fai clic su Enable e completa il flusso OAuth. Devin recupererà dettagli sugli errori, stack trace e tag di release.Una volta connesso, Devin correla automaticamente la telemetria con la timeline dell’incidente per creare un’analisi post-mortem basata su evidenze. Scopri di più su come connettere i server MCP.
4

Cosa genera Devin

Quando un incidente PagerDuty si risolve, Devin analizza l’intervallo dell’incidente e prepara un postmortem strutturato:Esempio di postmortem prodotto da Devin:
# Postmortem: Database Connection Pool Exhaustion — orders-service
**Date:** 2026-02-10 | **Duration:** 46 minutes | **Severity:** P1

## Summary
orders-service experienced connection pool exhaustion between
14:32 and 15:18 UTC, causing 502 errors for ~12% of order
placement requests.

## Timeline
- 14:15 UTC — Deploy #387 released (commit e4f29a1)
- 14:28 UTC — Connection pool usage climbed from 60% to 92%
- 14:32 UTC — Pool exhausted; PagerDuty incident triggered
- 14:38 UTC — On-call engineer acknowledged
- 14:45 UTC — Identified Deploy #387 added a new inventory
              check that opens a DB connection per line item
              without releasing it in the finally block
- 15:02 UTC — Rollback to Deploy #386 initiated
- 15:18 UTC — Connection pool recovered; incident resolved

## Root Cause
Deploy #387 introduced `checkInventoryAvailability()` in
`src/services/orders.ts:142`. The function opens a new DB
connection for each line item in an order but only releases
it on the success path. When inventory checks fail (timeout
or stock unavailable), connections leak.

Orders with 5+ line items reliably exhausted the pool within
15 minutes of the deploy.

## Action Items
- [ ] Fix connection leak: add `finally` block to release
      connection (PR #388 opened)
- [ ] Add connection pool usage monitor with alert at 80%
- [ ] Add integration test for multi-item orders with
      simulated inventory failures
- [ ] Review other DB access patterns for similar leak risks
5

Personalizza il resoconto post-incidente

Adatta la pipeline al processo di postmortem del tuo team:Usa un Playbook per definire il modello di postmortem: sezioni, classificazione della gravità, campi obbligatori e dove archiviare l’output. Passa un playbook_id nella richiesta API per standardizzare ogni postmortem.Instrada in base alla gravità. Aggiungi logica nel tuo bridge per generare postmortem solo per incidenti P1/P2. Gli incidenti meno gravi potrebbero non richiedere un resoconto completo.Aggiungi Knowledge sulla tua architettura, sui responsabili dei servizi e sugli incidenti passati, così Devin può collegare i vari elementi — ad esempio, “orders-service dipende da inventory-service, che è noto per problemi di timeout sotto carico.”Pubblica sul tuo wiki. Invece di fare il commit su una repo, fai in modo che Devin pubblichi il postmortem su Confluence, Notion o sul tuo wiki interno tramite il prompt della session.