Imported from shipshitdev/skills (
skills/monitoring-setup/SKILL.md). Install upstream withnpx skills add shipshitdev/skills --skill monitoring-setup. Copyright stays with the author.
Monitoring Setup
Two layers: application health (errors, user behavior) and operational health (are the queues draining, is the database keeping up). An app with clean Sentry but a queue backing up or a table scan on every request is still failing its users — cover both.
When to Use
- Need to set up error tracking (Sentry)
- Want to configure Google Analytics
- Need monitoring for production applications
- Want to track application errors and user behavior
- Need operational signals: queue depth, slow queries, connection saturation, and alerts on them
Sentry Setup
NestJS Backend
- Install:
bun add @sentry/node @sentry/profiling-node - Initialize in
main.tsbefore app creation - Configure DSN via
SENTRY_DSNenvironment variable - Set appropriate sample rates for production
Next.js Frontend
- Install:
bun add @sentry/nextjs - Run:
bunx @sentry/wizard@latest -i nextjs - Configure client/server/edge configs
- Set
NEXT_PUBLIC_SENTRY_DSNfor client-side
Google Analytics Setup
Next.js Setup
- Add Google Analytics script to root layout
- Use
NEXT_PUBLIC_GA_MEASUREMENT_ID(format: G-XXXXXXXXXX) - Create analytics utility functions for event tracking
- Set up page view tracking
Common Events
- User signup/login
- Purchases/conversions
- Feature usage
- Custom business events
Operational Monitoring
Application errors tell you what threw; operational signals tell you what is quietly degrading. Instrument the three that take a product down under load.
BullMQ queue depth
A queue that fills faster than it drains is an outage in slow motion — no error fires until jobs time out.
- Track per queue: waiting (backlog), active, failed, and completed
rate.
Queue.getJobCounts()exposes these; scrape them on an interval or viabullmq-prometheus. - The signal that matters is trend: waiting climbing while completed is flat means workers cannot keep up (scale workers or the Redis connection).
- Watch the dead-letter / failed set — jobs exhausting retries are silent data loss.
Postgres slow queries & connections
- Enable
pg_stat_statements; surface the top queries by total time and by mean time. A query that is individually fast but runs 10k×/min is the real cost. - Log queries over a threshold (
log_min_duration_statement) and alert on new entrants — a slow query usually means a missing index or an N+1. - Track connection saturation (
active / max_connections). Near the ceiling on serverless means the pooler is undersized — seepostgres-ops.
Redis
- Memory usage vs
maxmemory, eviction rate, and command latency. Evictions mean the cache is too small and hit-rate is silently dropping.
Alerting
Instrumentation no one looks at is not monitoring. For each signal above, define a threshold and route it somewhere a human sees at 3am (PagerDuty, Opsgenie, a Slack channel that pages). Alert on the leading indicator (queue waiting climbing, connections near max) not just the lagging one (jobs already timing out, 500s already served). Every alert names the runbook step to take, or it is just noise.
Best Practices
- Use different DSNs for dev/prod
- Set appropriate sample rates
- Respect user privacy (GDPR/CCPA)
- Don't track sensitive data
- Alert on leading operational indicators, not only on errors after the fact
- Every alert links to a runbook action — no orphan alerts
Integration
This skill integrates with /monitoring-setup command for automated setup workflows.
Pairs with postgres-ops (pooling, DR) and nestjs-queue-architect (queue design).