- Create /chinh-sach-bao-mat (Privacy Policy) with 10 sections - Create /dieu-khoan-su-dung (Terms of Service) with 11 sections - Add legal link group to footer (vi + en i18n) - Add legalLinks prop to Footer for bottom-bar display - Wire links into public layout Co-Authored-By: Paperclip <noreply@paperclip.ing>
160 lines
6.3 KiB
Markdown
160 lines
6.3 KiB
Markdown
# Sentry Alert Routing — Runbook
|
|
|
|
> Audience: SRE on-call & platform engineers.
|
|
> Scope: How Sentry P1/P2 alerts are wired into Slack & email for the GoodGo platform, and how to verify routing end-to-end.
|
|
> Related ticket: [GOO-178](/GOO/issues/GOO-178) (gap surfaced by [GOO-117](/GOO/issues/GOO-117) audit).
|
|
|
|
---
|
|
|
|
## 1. Sentry projects & SDK wiring
|
|
|
|
The SDK is initialised in three Next.js entrypoints (server, client, edge):
|
|
|
|
| File | DSN env | Notes |
|
|
|------|---------|-------|
|
|
| `apps/web/sentry.server.config.ts` | `SENTRY_DSN` | Server-side errors, traces (`tracesSampleRate=0.2` in prod). |
|
|
| `apps/web/sentry.client.config.ts` | `NEXT_PUBLIC_SENTRY_DSN` | Browser errors + session replay on error. |
|
|
| `apps/web/sentry.edge.config.ts` | `SENTRY_DSN` | Edge runtime. |
|
|
|
|
Required env (see `.env.example`):
|
|
|
|
- `SENTRY_DSN`, `NEXT_PUBLIC_SENTRY_DSN`
|
|
- `SENTRY_AUTH_TOKEN` (CI source-map upload)
|
|
- `SENTRY_ORG`, `SENTRY_PROJECT`
|
|
- `SENTRY_RELEASE` / `NEXT_PUBLIC_SENTRY_RELEASE` (set per deploy by CI)
|
|
|
|
`environment` is set from `NODE_ENV` on every init call, so all events are tagged `production` / `staging` / `development` automatically.
|
|
|
|
---
|
|
|
|
## 2. Severity model
|
|
|
|
We classify Sentry events into two routing tiers using event tags. Tag `severity` is set either by the SDK (`Sentry.setTag('severity', 'P1')`) at capture time, or via Sentry **Issue tagging rules** based on event.level / fingerprint.
|
|
|
|
| Tier | Trigger criteria | Routing target | SLA |
|
|
|------|------------------|----------------|-----|
|
|
| **P1** | `level:fatal` OR `tags[severity]=P1` OR fingerprint in critical group (payments, auth, data loss) | Slack `#alerts-p1-sentry` (immediate) + email to `oncall@goodgo.vn` | Page on-call within 5 min |
|
|
| **P2** | `level:error` AND `environment:production` AND not P1 | Slack `#alerts-p2-sentry` (digest, every 30 min) | Triage within 4 business hours |
|
|
| Below P2 (warn / info / staging-only) | Everything else | No paging — visible only in Sentry UI dashboards | Best effort |
|
|
|
|
---
|
|
|
|
## 3. Required Sentry integrations
|
|
|
|
Verify in **Sentry → Settings → Integrations**:
|
|
|
|
- [ ] **Slack** — workspace `goodgo`, channels `#alerts-p1-sentry` and `#alerts-p2-sentry` authorised.
|
|
- [ ] **Email** — built-in; `oncall@goodgo.vn` is a verified team mailing list and a member of the GoodGo team for the project.
|
|
|
|
If either integration is missing, install it before configuring rules below.
|
|
|
|
---
|
|
|
|
## 4. Alert rule configuration
|
|
|
|
Configure under **Sentry → Alerts → Create Alert → Issues**.
|
|
|
|
### 4.1 P1 — immediate page
|
|
|
|
- **Name:** `P1 — immediate page`
|
|
- **Environment:** `production`
|
|
- **When:** "An issue is first seen" **OR** "An event is captured"
|
|
- **If (all):**
|
|
- `event.level` equals `fatal`
|
|
- **OR** `event.tags[severity]` equals `P1`
|
|
- **Then:**
|
|
- Send a Slack notification to `#alerts-p1-sentry`
|
|
- Send an email notification to Team `oncall`
|
|
- **Frequency:** every 1 minute (no batching)
|
|
- **Owner:** SRE team
|
|
|
|
### 4.2 P2 — production errors digest
|
|
|
|
- **Name:** `P2 — production errors`
|
|
- **Environment:** `production`
|
|
- **When:** "An issue changes state from resolved to unresolved" OR "A new issue is created"
|
|
- **If (all):**
|
|
- `event.level` equals `error`
|
|
- `event.tags[severity]` does not equal `P1`
|
|
- **Then:**
|
|
- Send a Slack notification to `#alerts-p2-sentry`
|
|
- **Frequency:** every 30 minutes (batched/digest)
|
|
|
|
### 4.3 Noise control
|
|
|
|
- Suppress alerts for environments other than `production` (a separate `staging` rule may post to `#alerts-staging` only).
|
|
- Use **Inbound filters** to drop browser extension errors, ResizeObserver loops, and known third-party noise.
|
|
- Per-issue **Mute → ignore until** for known-noisy fingerprints.
|
|
|
|
---
|
|
|
|
## 5. Test fire procedure (`Sentry.captureException`)
|
|
|
|
Use this whenever rules change or a quarterly verification is due.
|
|
|
|
### 5.1 Staging fire
|
|
|
|
1. Deploy the staging branch with `SENTRY_DSN` populated.
|
|
2. Trigger the dedicated test endpoint (or via curl in staging shell):
|
|
```ts
|
|
// apps/web/app/api/_debug/sentry-test/route.ts (staging only — guard with env)
|
|
import * as Sentry from '@sentry/nextjs';
|
|
export async function GET() {
|
|
Sentry.captureException(new Error('GOO-178 routing test — P1'), {
|
|
tags: { severity: 'P1', source: 'manual_routing_test' },
|
|
});
|
|
return Response.json({ ok: true });
|
|
}
|
|
```
|
|
```bash
|
|
curl -fsS https://staging.goodgo.vn/api/_debug/sentry-test
|
|
```
|
|
3. **Expected:**
|
|
- Event appears in Sentry within ~30s tagged `severity:P1`, `source:manual_routing_test`.
|
|
- Slack `#alerts-p1-sentry` receives the notification.
|
|
- Email lands at `oncall@goodgo.vn` within ~2 min.
|
|
4. Repeat without the `severity:P1` tag and with `level:error` to validate the P2 batched route (expect Slack message in next 30-min digest).
|
|
|
|
### 5.2 CLI alternative (no deploy)
|
|
|
|
```bash
|
|
SENTRY_DSN=$STAGING_SENTRY_DSN npx -y @sentry/cli send-event \
|
|
--message "GOO-178 routing test (P1)" \
|
|
--level fatal \
|
|
--tag severity:P1 \
|
|
--tag source:manual_routing_test \
|
|
--release "$(git rev-parse --short HEAD)"
|
|
```
|
|
|
|
### 5.3 Cleanup
|
|
|
|
- Resolve the test issue in Sentry.
|
|
- Add `source:manual_routing_test` to the inbound filter ignore list if it generates additional noise.
|
|
|
|
---
|
|
|
|
## 6. Verification checklist (run quarterly)
|
|
|
|
- [ ] Slack integration shows "Connected" in Sentry → Integrations.
|
|
- [ ] Email integration: open one P1 alert, confirm `oncall@goodgo.vn` received it.
|
|
- [ ] Both rules listed under Alerts with correct environment/scope.
|
|
- [ ] Test fire produces messages in `#alerts-p1-sentry` AND `#alerts-p2-sentry` per tier.
|
|
- [ ] On-call rotation in PagerDuty / Slack matches Sentry team membership.
|
|
- [ ] Inbound filters review — drop new noise sources surfaced since last review.
|
|
|
|
Record verification results as a comment on a tracking issue and update the **last verified** date in section 7.
|
|
|
|
---
|
|
|
|
## 7. Change log
|
|
|
|
| Date | Author | Change |
|
|
|------|--------|--------|
|
|
| 2026-04-23 | SRE Engineer ([GOO-178](/GOO/issues/GOO-178)) | Initial runbook documenting P1/P2 routing model, alert rule definitions, and test fire procedure. |
|
|
|
|
---
|
|
|
|
## 8. Outstanding
|
|
|
|
- **Sentry org/project access not yet provisioned for the agent.** Live verification of integrations + a real test fire is blocked until `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT` are provided to staging and to the SRE agent. See [GOO-178](/GOO/issues/GOO-178) for the open blocker.
|