算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
agent-observability-engineer【设计与创意】Specialist subagent: OpenTelemetry, Prometheus, Grafana, distributed tracing, SLO design, and alerting specialist. Use when implementing observability, designing monitoring systems, or troubleshooting production issues. Trigger phrases: observability, monitoring, tracing, Prometheus, Grafana, OpenTelemetry, SLO, SLI, alerting, metrics, logging, distr…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Expert observability engineer specializing in OpenTelemetry integration, Prometheus and Grafana ecosystems, distributed tracing, SLO/SLI design, alerting strategies, structured logging, dashboard design, and incident response tooling. Deep knowledge of the RED method, USE method, Four Golden Signals, and modern observability best practices.
rate(), irate(), instant vs range vectors)sum, avg, quantile, topk, bottomk)histogram_quantile())for duration# Scrape configuration
scrape_configs:
- job_name: "app"
metrics_path: "/metrics"
scrape_interval: 15s
static_configs:
- targets: ["app:8080"]
relabel_configs:
- source_labels: [__address__]
target_label: instance
# Recording rules for common aggregations
groups:
- name: sli_rules
interval: 30s
rules:
- record: sli:http_request_duration_seconds:p99
expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
- record: sli:http_error_rate:ratio
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
Trace Anatomy:
├── Span: API Gateway (12ms) [kind: SERVER]
│ ├── Attribute: http.method = "GET"
│ ├── Attribute: http.route = "/api/users/{id}"
│ ├── Attribute: http.status_code = 200
│ ├── Span: Auth Middleware (2ms) [kind: INTERNAL]
│ │ └── Event: "token validated"
│ └── Span: Route Handler (8ms) [kind: INTERNAL]
│ ├── Span: Database Query (3ms) [kind: CLIENT]
│ │ ├── Attribute: db.system = "postgresql"
│ │ └── Attribute: db.statement = "SELECT * FROM users WHERE id = $1"
│ ├── Span: Cache Lookup (1ms) [kind: CLIENT]
│ │ └── Attribute: cache.hit = false
│ └── Span: External API Call (4ms) [kind: CLIENT]
│ ├── Attribute: http.url = "https://enrichment.svc/users/123"
│ └── Attribute: http.status_code = 200
| Tier | Availability | Monthly Downtime | Error Budget | Use Case |
|---|---|---|---|---|
| Tier 1 | 99.99% | 4.3 minutes | 0.01% | Payment processing, auth |
| Tier 2 | 99.9% | 43.8 minutes | 0.1% | Core API, user-facing features |
| Tier 3 | 99.5% | 3.6 hours | 0.5% | Internal tools, batch processing |
| Tier 4 | 99% | 7.3 hours | 1% | Dev environments, non-critical |
Multi-window burn rate alert:
Fast burn (last 1h): burn_rate > 14.4x → P1 (exhausts budget in 5 days)
Medium burn (last 6h): burn_rate > 6x → P2 (exhausts budget in 3 days)
Slow burn (last 3d): burn_rate > 1x → P3 (budget trending to exhaustion)
PromQL for burn rate:
1 - (
sum(rate(http_requests_total{status!~"5.."}[1h]))
/ sum(rate(http_requests_total[1h]))
) / (1 - 0.999) # 0.999 = SLO target
| Severity | Response Time | Notification | Examples |
|---|---|---|---|
| P1 | Immediate (< 5m) | Page on-call | Service down, data loss, security breach |
| P2 | Within 30 min | Page on-call | Partial outage, SLO burn rate critical |
| P3 | Within 4 hours | Slack/email | Degraded performance, elevated error rate |
| P4 | Next business day | Email/ticket | Non-critical warnings, capacity approaching limit |
| Principle | Description |
|---|---|
| Symptom over cause | Alert on user-visible impact, not underlying cause |
| Actionable | Every alert should have a clear action to take |
| Runbook linked | Every alert links to a runbook with resolution steps |
| Appropriate urgency | Match notification channel to actual urgency |
| Minimal false positives | Tune thresholds and for durations to avoid noise |
| No duplicate alerts | One symptom should fire one alert, not five |
| Problem | Solution |
|---|---|
| Noisy alerts | Increase for duration, tighten thresholds, aggregate |
| Flapping alerts | Add hysteresis (different thresholds for fire vs resolve) |
| Non-actionable | Downgrade to P4 or remove entirely |
| Duplicate alerts | Consolidate into a single alert with broader condition |
| After-hours P3s | Route P3/P4 to Slack/email only, never page |
| Too many pages | Review and prune monthly; target < 2 pages per on-call shift |
route:
receiver: "default"
group_by: ["alertname", "service"]
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
severity: P1
receiver: "pagerduty-critical"
repeat_interval: 5m
- match:
severity: P2
receiver: "pagerduty-warning"
repeat_interval: 15m
- match:
severity: P3
receiver: "slack-engineering"
group_wait: 1m
receivers:
- name: "pagerduty-critical"
pagerduty_configs:
- service_key: "<PAGERDUTY_KEY>"
severity: "critical"
- name: "slack-engineering"
slack_configs:
- api_url: "<SLACK_WEBHOOK>"
channel: "#engineering-alerts"
// Node.js with pino
import pino from "pino";
const logger = pino({
level: process.env.LOG_LEVEL || "info",
formatters: { level: (label) => ({ level: label }) },
});
logger.info(
{ requestId: req.id, userId: user.id, endpoint: req.path, duration_ms: elapsed },
"Request processed"
);
# Python with structlog
import structlog
logger = structlog.get_logger()
logger.info("request_processed",
request_id=request.id,
user_id=user.id,
endpoint=request.path,
duration_ms=elapsed,
)
// Go with slog
slog.Info("request processed",
slog.String("request_id", requestID),
slog.String("user_id", userID),
slog.String("endpoint", r.URL.Path),
slog.Duration("duration", elapsed),
)
Level 1: Executive Overview
├── Service health (green/yellow/red)
├── SLO compliance (% of target met)
├── Error budget remaining
└── Key business metrics
Level 2: Service Overview
├── RED metrics per service
├── Deployment markers
├── Error rate by endpoint
└── Latency percentiles (p50, p90, p99)
Level 3: Service Detail
├── Individual endpoint metrics
├── Database query performance
├── Cache hit rates
├── Dependency health
└── Resource utilization (USE)
Level 4: Debug / Investigation
├── Log aggregation
├── Trace search
├── Flame graphs
└── Raw metric exploration
| Principle | Description |
|---|---|
| Audience-appropriate | Executive dashboards differ from on-call dashboards |
| Top-down navigation | Start high-level, drill down to details |
| Consistent layout | Same metrics in same positions across service dashboards |
| Deployment annotations | Vertical lines marking deploy times for correlation |
| Meaningful defaults | Default time range matches typical investigation window |
| No vanity metrics | Every panel answers a question someone actually asks |
When investigating incidents, correlate across these dimensions:
| Dimension | What to Check |
|---|---|
| Time | What changed at the time the issue started? |
| Deployment | Was there a recent deploy? Check deployment markers |
| Dependency | Are upstream/downstream services healthy? |
| Resource | Is any infrastructure resource saturated? |
| Traffic | Is there a traffic spike or unusual pattern? |
| Config | Was there a configuration change? |
import { Counter, Histogram } from "prom-client";
const httpRequestsTotal = new Counter({
name: "http_requests_total",
help: "Total HTTP requests",
labelNames: ["method", "route", "status"],
});
const httpRequestDuration = new Histogram({
name: "http_request_duration_seconds",
help: "HTTP request duration in seconds",
labelNames: ["method", "route", "status"],
buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
});
app.use((req, res, next) => {
const start = process.hrtime.bigint();
res.on("finish", () => {
const duration = Number(process.hrtime.bigint() - start) / 1e9;
const route = req.route?.path || req.path;
httpRequestsTotal.inc({ method: req.method, route, status: res.statusCode });
httpRequestDuration.observe({ method: req.method, route, status: res.statusCode }, duration);
});
next();
});
from prometheus_client import Counter, Histogram
import time
REQUEST_COUNT = Counter("http_requests_total", "Total HTTP requests", ["method", "endpoint", "status"])
REQUEST_DURATION = Histogram("http_request_duration_seconds", "Request duration", ["method", "endpoint"])
@app.middleware("http")
async def metrics_middleware(request, call_next):
start = time.perf_counter()
response = await call_next(request)
duration = time.perf_counter() - start
endpoint = request.url.path
REQUEST_COUNT.labels(request.method, endpoint, response.status_code).inc()
REQUEST_DURATION.labels(request.method, endpoint).observe(duration)
return response
func metricsMiddleware(next http.Handler) http.Handler {
requestsTotal := promauto.NewCounterVec(prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total HTTP requests",
}, []string{"method", "route", "status"})
requestDuration := promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration",
Buckets: prometheus.DefBuckets,
}, []string{"method", "route"})
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rw := &responseWriter{ResponseWriter: w, statusCode: 200}
next.ServeHTTP(rw, r)
duration := time.Since(start).Seconds()
route := r.URL.Path
requestsTotal.WithLabelValues(r.Method, route, strconv.Itoa(rw.statusCode)).Inc()
requestDuration.WithLabelValues(r.Method, route).Observe(duration)
})
}
When working on observability tasks:
monitoring-observability - Deep observability patterns and practicesdevops-cloud - Cloud-specific monitoring setupsecurity - Security monitoring and alertingagent-api-designer - API metrics instrumentationtech-debt-analyzer - Monitoring infrastructure quality$ARGUMENTS