Monitoring Guide
Monitor rate limiting activity and integrate with observability tools.
Rate Limit Events
Track rate limiting activity with event handlers:
import { hitlimit } from '@joint-ops/hitlimit'
const limiter = hitlimit({
limit: 100,
window: '1m',
onRateLimit: (req, info) => {
console.log(`Rate limited: ${info.key}`, {
count: info.count,
limit: info.limit,
resetTime: info.resetTime
})
},
onRequest: (req, info) => {
// Called on every request
metrics.increment('ratelimit.request')
}
}) Prometheus Integration
import { Counter, Gauge } from 'prom-client'
const rateLimitHits = new Counter({
name: 'ratelimit_hits_total',
help: 'Total rate limit hits',
labelNames: ['path', 'status']
})
const rateLimitRemaining = new Gauge({
name: 'ratelimit_remaining',
help: 'Remaining requests in window',
labelNames: ['key']
})
const limiter = hitlimit({
limit: 100,
window: '1m',
onRateLimit: (req, info) => {
rateLimitHits.inc({ path: req.path, status: 'limited' })
},
onRequest: (req, info) => {
rateLimitHits.inc({ path: req.path, status: 'allowed' })
rateLimitRemaining.set(
{ key: info.key },
info.limit - info.count
)
}
}) DataDog Integration
import { StatsD } from 'hot-shots'
const dogstatsd = new StatsD({
host: 'localhost',
port: 8125,
prefix: 'api.'
})
const limiter = hitlimit({
limit: 100,
window: '1m',
onRateLimit: (req, info) => {
dogstatsd.increment('ratelimit.blocked', [
`path:${req.path}`
])
},
onRequest: (req, info) => {
dogstatsd.gauge(
'ratelimit.remaining',
info.limit - info.count,
[`key:${info.key}`]
)
}
}) Structured Logging
import pino from 'pino'
const logger = pino({ level: 'info' })
const limiter = hitlimit({
limit: 100,
window: '1m',
onRateLimit: (req, info) => {
logger.warn({
event: 'rate_limit_exceeded',
key: info.key,
path: req.path,
count: info.count,
limit: info.limit,
ip: req.ip,
userAgent: req.headers['user-agent']
})
}
}) Alerting Rules
Example Prometheus alerting rules:
# prometheus/alerts.yml
groups:
- name: ratelimit
rules:
- alert: HighRateLimitRate
expr: rate(ratelimit_hits_total{status="limited"}[5m]) > 10
for: 2m
labels:
severity: warning
annotations:
summary: "High rate limit hit rate"
- alert: RateLimitSpike
expr: rate(ratelimit_hits_total{status="limited"}[1m]) > 100
for: 1m
labels:
severity: critical
annotations:
summary: "Rate limit spike detected" Dashboard Metrics
Key metrics to track:
| Metric | Type | Description |
|---|---|---|
ratelimit_hits_total | Counter | Total requests by status |
ratelimit_remaining | Gauge | Remaining quota per key |
ratelimit_latency_ms | Histogram | Rate limit check latency |
ratelimit_keys_active | Gauge | Active rate limit keys |
Health Check Endpoint
app.get('/health/ratelimit', async (req, res) => {
const store = limiter.store
try {
// Test store connectivity
await store.get('health:check')
res.json({
status: 'healthy',
store: store.constructor.name
})
} catch (err) {
res.status(503).json({
status: 'unhealthy',
error: err.message
})
}
})