Alerts
Get notified when errors happen in your applications. Rustrak supports multiple notification channels and per-project alert rules.
How it works
Alerts have two components:
- Notification Channels (Global): Where to send alerts (Slack, Email, Webhooks, Custom Webhooks)
- Alert Rules (Per-Project): When to trigger alerts and which channels to use
Setting up notification channels
Channels are configured globally in Settings → Global Alerts.
Webhook
Send JSON payloads to any HTTP endpoint.
- Go to Settings → Global Alerts
- Click Configure on Webhooks
- Enter:
- Name: e.g., “Production Alerts”
- URL: Your webhook endpoint
- Secret (optional): For HMAC signature verification
- Click Create Webhook
Webhook payload
{
"alert_id": "1-550e8400-1706140800000",
"alert_type": "new_issue",
"triggered_at": "2024-01-25T12:00:00.000Z",
"project": {
"id": 1,
"name": "My Project",
"slug": "my-project"
},
"issue": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"short_id": "MY-PROJECT-42",
"title": "TypeError: Cannot read property 'x' of undefined",
"level": "error",
"first_seen": "2024-01-25T11:55:00Z",
"last_seen": "2024-01-25T12:00:00Z",
"event_count": 5
},
"issue_url": "https://rustrak.example.com/projects/1/issues/550e8400-e29b-41d4-a716-446655440000",
"actor": "Rustrak"
}Webhook headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-Rustrak-Timestamp | Unix timestamp |
X-Rustrak-Request-ID | Unique alert ID |
X-Rustrak-Signature | sha256=<hmac> (if secret configured) |
Verifying signatures
If you configure a secret, verify the X-Rustrak-Signature header:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Custom Webhook
POST a request body that you compose yourself, in whatever shape the receiving endpoint expects. The body is JSON with alert fields in it, rendered from a Minijinja template over the alert payload, so a service with its own fixed message schema can be fed without Rustrak carrying an integration per service. The plain Webhook integration is unchanged; Custom Webhook is its own provider.
- Go to Settings → Global Alerts
- Click Configure on Custom Webhook
- Enter:
- Name: what this destination is, e.g. “Ops chat bridge”
- Message body: the JSON your endpoint expects. Start from drops in the shape a known service wants; Insert field puts an alert value at the caret. The preview underneath shows what will be sent
- Webhook URL: optional, since a per-rule override can supply it
- Secret (optional): for the same HMAC header the plain Webhook sends
- Click Create Custom Webhook
{
"text": "Rustrak: {{ issue.title }} ({{ issue.short_id }})\n{{ issue_url }}"
}Values are escaped for wherever you put them. Inside a string, a title with a quote or a newline stays inside the string; standing alone, a number stays a number and a string is quoted. There is no filter to remember. The full field list, the rules and more examples are on the message body template page.
The rendered result must be valid JSON. That is checked when you save, not only when an alert fires: the template is rendered against a sample payload, once with every field populated and once with the issue level absent, and the integration is rejected if either render fails. Syntax errors and unknown fields are caught the same way.
Rendering is bounded, because a template runs on the notification worker once per delivery. A template that spends more than the instruction budget, or whose body renders past 1 MiB, fails with that reason instead of running. Response bodies larger than 64 KiB are rejected rather than buffered, and a 2xx whose body cannot be read at all is recorded as a failure rather than assumed delivered.
How a delivery is judged
By the HTTP status. A 2xx is a delivery; the response body is never interpreted. That is what Grafana’s Custom Payload, Uptime Kuma’s Custom Body and Alertmanager’s webhook receiver all do, and it means Rustrak never has to guess what a field in someone else’s response means.
Some services answer 200 even when they refuse the message and put the real
outcome in the body. Press Test after configuring: the result shows exactly
what the endpoint answered, so a refusal is visible rather than silent.
A WeCom or DingTalk bot configured with a custom keyword (自定义关键词) refuses any message whose text does not contain that keyword, so put the keyword in the body’s static text. A bot restricted by IP allowlist refuses based on the source address of the Rustrak server instead, and no template change helps there. In both cases Test shows you the refusal.
Slack
Send alerts to Slack channels.
- Create an Incoming Webhook in Slack
- Go to Settings → Global Alerts
- Click Configure on Slack
- Enter:
- Name: e.g., “Slack Alerts”
- Webhook URL: The Slack webhook URL
- Channel (optional): Override default channel
- Click Create Slack Integration
Email (SMTP)
Send alerts via email.
- Go to Settings → Global Alerts
- Click Configure on Email
- Enter:
- Name: e.g., “Email Alerts”
- Recipients: Comma-separated email addresses
- SMTP Host: e.g.,
smtp.gmail.com - Port:
587(STARTTLS) or465(SSL) - Username/Password: SMTP credentials
- From Address: Sender email
- Click Create Email Channel
Note: For Gmail, use an App Password .
Testing channels
Before creating alert rules, test your channels:
- Go to Settings → Global Alerts
- Click Configure on a channel
- Click Test
- Check that you received the test notification
Creating alert rules
Alert rules define when to send notifications for a specific project.
- Open a project
- Click the bell icon in the header
- Click Add Alert Rule
- Configure:
- Name: e.g., “Notify team on new issues”
- Trigger: When to alert
- Channels: Where to send (select one or more)
- Filters: Which issues are worth it (level, environments, number of events)
- Cooldown: Minimum time between alerts for the same issue
- Click Create Rule
Trigger types
| Trigger | Description |
|---|---|
| New Issue | When an issue is first detected |
| Regression | When a resolved issue reappears |
| Unmute | When a muted issue is unmuted |
Filters
A rule without filters fires for every issue its trigger sees. Each filter narrows it:
| Filter | Fires when |
|---|---|
| Level | The event is at least this level (error or above skips warnings and info). An event with no level counts as error. |
| Environments | The event’s environment is one of these. Empty means every environment. |
| Minimum events | New Issue rules only: the issue reaches this many events. It fires once, on the event that reaches the count, instead of on the first one. |
Minimum events: 10 together with Environments: production is what keeps a one-off error on a laptop from ever reaching anyone.
Cooldown
Prevents alert fatigue by limiting how often alerts fire for the same issue.
- 0 minutes: Alert on every event (not recommended)
- 5 minutes: Wait 5 minutes before alerting again
- 60 minutes: Good for high-traffic issues
Managing rules
Enable/disable
Toggle the switch next to a rule to enable or disable it without deleting.
Edit
Click the edit icon to modify a rule’s name, channels, or cooldown.
Delete
Click the delete icon and confirm to remove a rule.
Best practices
Channel organization
- Webhook: For custom integrations, PagerDuty, Opsgenie
- Custom Webhook: For an endpoint that expects its own message shape
- Slack: For team awareness
- Email: For on-call or compliance
Alert rules
- Create a New Issue rule for all projects
- Use Regression for production projects
- Set appropriate cooldowns to avoid alert fatigue
Testing
- Create channels with test endpoints first (e.g., webhook.site )
- Verify payloads are correct
- Update to production endpoints