算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
pagerduty-escalation-architect【设计与创意】Design PagerDuty escalation policies, schedules, services, response plays, and incident workflows that handle real on-call traffic without burning out the rotation. Covers follow-the-sun rotations, primary/secondary patterns, weekly handoffs, escalation timeouts matched to severity, business-hour vs always-on services, override patterns for vacations…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Design and tune PagerDuty escalation policies, schedules, services, and response plays. Acts as a senior SRE who has built on-call programs across three continents, run the fairness audits when engineers complain about uneven pages, and rebuilt the routing during a merger that combined two PagerDuty tenants with conflicting taxonomies.
This skill builds the routing — schedules, escalation policies, services, response plays, business-hour rules, overrides, and the math behind on-call comp. It does not write your detection logic (that's the monitoring stack), and it does not run incidents (that's the incident commander). It assumes your alert sources are already wiring into PagerDuty; the job is what happens after the alert lands.
Invoke when:
Basic invocations:
Build escalation policies for our 12 services, T0 to T2 We're going follow-the-sun across US/EU/APAC — design the schedule Audit our PD tenant; 80 services, 120 schedules, no idea what's used Generate the on-call fairness report for Q1 Compose response plays so a P1 auto-creates a Slack channel and Zoom bridge
Audit the existing tenant. API calls: GET /services, /escalation_policies, /schedules, /users, /teams, /response_plays. Tag each object with last-used date (incidents API, last 90 days). Anything unused for 90+ days is a deletion candidate, with the exception of compliance-required services.
Build the team roster. Each engineer needs: time zone, on-call eligibility (probation? training shadow? full?), vacation windows for the next 6 months, language/region constraints. This drives schedule design.
Map services to tiers. Cross-reference the service catalog. Each PD service must have tier in its name or description and a team association. Untiered services go to a triage list.
Design schedules per team using a documented pattern (see Schedule Design Patterns). Most teams pick: weekly handoff Mon 09:00 local, primary + secondary, follow-the-sun if multi-region.
Build escalation policies tied to severity. Tier dictates timeouts: T0 escalates fast (5 min → 10 min → 15 min); T2 slow (30 min → 60 min → out-of-hours suppress). Document each policy's intent in its description field.
Wire services to escalation policies. Each PD service points to one escalation policy. Use Event Rules and Service Orchestration for routing fan-out (one alert source → multiple services based on payload).
Build response plays. Each tier has a baseline play that fires on incident trigger: post Slack channel, create Zoom, post Statuspage placeholder, page secondary on critical, link runbook. Plays are composable; build a library.
Set business-hour rules. Some services should never page at 3am (internal tools, marketing site). Use schedule "layers" — restricted to business hours — that fall through to a digest queue out-of-hours.
Configure overrides for vacation. Calendar integration (Google Calendar) auto-overrides; manual overrides are a backup. Document the swap process in the runbook so engineers don't manually edit schedules.
Set up training shadow rotations. New on-call engineers shadow for 4-8 weeks: get the same pages, no notification responsibility, debrief with primary. Implement as a parallel layer that doesn't escalate.
Wire integrations. Slack: incident channels auto-created, status posts on state changes. Zoom: bridge auto-created on P0/P1. Statuspage: incident drafts on customer-facing services. Jira/Linear: post-incident ticket auto-created with timeline.
Wire incident workflows. PagerDuty Incident Workflows trigger on conditions (priority, service, payload field). Use them to fork response plays, auto-add stakeholders, run command-line tools.
Generate the fairness report. Per-engineer page count, page count outside business hours, weekend page count, escalations missed. Ship monthly. See Fairness Math section.
Schedule audits. Monthly: stale-services pruning, override audit, fairness review. Quarterly: tier reassignment, schedule pattern review. Annually: compliance evidence export.
The biggest source of on-call pain is the schedule. Pick one of these patterns deliberately; mixing patterns inside one team breaks fairness math.
The default for teams of 6-12 engineers in one time zone. Each engineer is primary one week per N weeks; secondary the week before and after primary.
Schedule: <team>-primary
Layer 1: rotation 7 days, Mon 09:00 local, members [A, B, C, D, E, F]
Schedule: <team>-secondary
Layer 1: rotation 7 days, Mon 09:00 local, members [B, C, D, E, F, A] # offset by 1
Pages first hit primary (5 min) → secondary (10 min) → manager (20 min). Comp: flat rate per primary week; secondary at 0.3x rate.
For 24/7 critical services with engineers in three regions. Each region holds the rotation during their business day.
Schedule: <team>-fts
Layer 1: members [A_us, B_us, C_us], 09:00–17:00 PT, Mon–Fri
Layer 2: members [D_eu, E_eu, F_eu], 09:00–17:00 CET, Mon–Fri
Layer 3: members [G_apac, H_apac, I_apac], 09:00–17:00 SGT, Mon–Fri
Final layer: weekend rotation across all members
Each engineer is on-call only during their business day. Weekend rotation rotates fairly across all 9. Pages between regions auto-handoff at layer boundaries — no engineer is paged at 3am unless the weekend rotation is on them.
Caveat: requires all three regions to be staffed. If APAC has 1 engineer, you're back to a single-point rotation. Start with US+EU follow-the-sun, add APAC when staffing supports it.
For teams of 3-5 where weekly is too long (one engineer is "on" 25% of all weeks). Daily rotation flattens load.
Schedule: <team>-daily
Layer 1: rotation 1 day, Mon–Fri 09:00 local, members [A, B, C, D]
Layer 2 (weekend): rotation 2 days, Sat 09:00 local, members [A, B, C, D]
Comp tracked daily. Trade-off: more handoffs = more dropped context. Document handoff in a daily on-call log.
For T2 services that genuinely don't need 24/7 coverage. Pages route to schedule during business hours; out-of-hours pages go to a digest queue or higher-tier rotation.
Schedule: <team>-bh
Layer 1: rotation 7 days, members [A, B, C, D], 08:00–20:00 local, Mon–Fri
No final layer (out-of-hours = no on-call)
Escalation policy: <team>-bh-policy
Step 1: <team>-bh schedule (10 min)
Step 2: <platform>-fallback schedule (20 min)
Step 3: drop to digest queue (no further escalation)
If out-of-hours coverage is needed, the platform team's always-on rotation absorbs it.
Higher-severity pages route to a tighter schedule; lower-severity to a more relaxed one. Useful when one team owns both T0 and T2 services.
Schedule: <team>-critical
Layer 1: weekly rotation, only senior engineers
Schedule: <team>-standard
Layer 1: weekly rotation, full team including juniors
Service routing:
T0 services → <team>-critical
T1/T2 services → <team>-standard
Escalation timeouts must match severity. Generic 30-30-30 timeouts mean T0 outages escalate to nobody for 90 minutes.
Step 1: Primary on-call (5 min ack timeout)
Step 2: Secondary on-call (10 min ack timeout)
Step 3: Team lead (15 min)
Step 4: Engineering manager + Director on-call (no further timeout)
Loop: re-trigger from Step 1 every 30 min if not resolved
Notification rules per user: at Step 1, push + SMS + voice. SMS-only for international teammates without push.
Step 1: Primary on-call (10 min)
Step 2: Secondary on-call (20 min)
Step 3: Team lead (30 min)
No re-trigger loop (let humans drive)
Step 1: Primary on-call (30 min)
Step 2: Team digest channel (no escalation, just notify)
For known-noisy services or non-business-hour T2 services:
Step 1: Primary on-call (business hours only via schedule layer)
Step 2: Out-of-hours: append to incident digest queue, no notification
Hard rules:
How does an incoming alert reach the right service / escalation policy / responder?
Alert source (Datadog, Sentry, CloudWatch, custom)
→ Integration sends to PD Service or Global Event Orchestration
Decide where the routing logic lives:
1. Source-side routing (e.g. one Datadog @pagerduty-<service> per service)
✅ Simple, debuggable
✅ Works for 1:1 source-to-service mapping
❌ Doesn't scale when one source feeds many services with conditions
2. PD Service Orchestration (per-service rules)
✅ Conditions on payload fields
✅ Mute, suppress, or transform
❌ Per-service silos; can't share rules across services
3. PD Global Event Orchestration
✅ Org-wide rules; route by service/team/severity tag in the payload
✅ Catch-all for misrouted events
❌ Can be a tangle if not maintained
Recommendation:
- Source-side routing for clean 1:1 cases (90% of services)
- Service Orchestration for service-specific suppression / transformation
- Global Event Orchestration for catch-all and cross-cutting rules (priority mapping, dedupe)
Fan-out patterns:
<service>-<alert_id>, never timestamps.Response plays are reusable bundles of "things that happen when an incident triggers." Build a library of named plays. Each service references the plays it needs.
play_war_room_criticalFor P0/P1 incidents.
Actions:
- Create Slack channel #inc-{{ incident.id }}
- Post Slack channel notification to #incidents
- Create Zoom bridge; post URL to channel
- Add responders: incident commander on-call, scribe on-call
- Post Statuspage incident draft (if customer-facing service)
- Add status update template to incident
play_silent_trackFor P2 incidents — tracked, not war-roomed.
Actions:
- Post Slack thread to #team-oncall
- Add a Linear issue with timeline link
- No Zoom, no Statuspage, no extra responders
play_security_incidentFor security-tagged incidents.
Actions:
- Create private Slack channel #sec-inc-{{ incident.id }}
- Add security on-call + CISO + legal counsel
- DO NOT post to public Slack channels or Statuspage
- Add evidence preservation reminder
play_data_corruptionFor data-loss-suspected incidents.
Actions:
- Page DBA on-call + data engineering lead
- Lock affected dataset (action via runbook link)
- Snapshot current backups
- War room (#inc-{{ incident.id }}) with read-only access for stakeholders
play_release_regressionWhen deploy regression alert triggers.
Actions:
- Add release engineer on-call
- Link to deploy dashboard with last 5 deploys
- Suggested action: "rollback first, debug after" — link to rollback runbook
play_dependency_outageWhen upstream dependency (Stripe, Auth0, AWS) is down.
Actions:
- Post to #vendor-status channel
- Suppress related child incidents (mute_status_handle)
- Post Statuspage with dependency status
- Skip secondary escalation (waiting on vendor, no human action)
play_business_hours_onlyFor T2 services that page only during business hours.
Actions:
- If outside business hours: snooze incident until next business day 09:00
- If inside: standard notify
play_postmortem_kickoffTriggered on incident resolution (workflow, not response play, but related).
Actions:
- Create postmortem doc from PD timeline
- Auto-fill: incident summary, timeline, responders, services affected, duration
- Assign to incident commander
- Set due date: 5 business days
When engineers feel on-call is uneven, you need numbers. Build a monthly fairness report that scores each engineer.
Inputs (PD API: GET /incidents filtered by service, time, responder):
Compute fairness scores:
weighted_pages = pages
+ 1.5 * out_of_hours_pages
+ 2.0 * weekend_pages
+ 3.0 * holiday_pages
pages_per_oncall_hour = weighted_pages / on_call_hours
team_median = median(pages_per_oncall_hour for each engineer)
fairness_index = pages_per_oncall_hour / team_median
- 1.0 = exactly fair
- >1.5 = significantly above median (investigate)
- <0.5 = significantly below (training opportunity, or schedule gap)
Comp formulas (pick one, document, stick to it):
Flat rate (simplest):
comp_per_week = $X for primary, $X * 0.3 for secondary, $X * 2 for holidays
Per-page (incentivizes silencing noise):
comp = base_oncall_rate + (pages * per_page_rate)
⚠ Risk: incentivizes acking & dismissing; only use with strict ack-quality audit
Hour-based (most defensible):
comp = on_call_hours * hourly_rate
+ actual_response_hours * response_hourly_rate (1.5x base)
Action thresholds (when the fairness report flags an outlier):
SOC2 / compliance evidence: