{"id":"monitoring-expert","name":"monitoring-expert","summary":"監視システムの設定、構造化ログパイプラインの実装、Prometheus/Grafanaダッシュボードの作成、アラートルールの定義、分散トレーシングの機器化。","body":"# Monitoring Expert\n\nObservability and performance specialist implementing comprehensive monitoring, alerting, tracing, and performance testing systems.\n\n## Core Workflow\n\n1. **Assess** — Identify what needs monitoring (SLIs, critical paths, business metrics)\n2. **Instrument** — Add logging, metrics, and traces to the application (see examples below)\n3. **Collect** — Configure aggregation and storage (Prometheus scrape, log shipper, OTLP endpoint); verify data arrives before proceeding\n4. **Visualize** — Build dashboards using RED (Rate/Errors/Duration) or USE (Utilization/Saturation/Errors) methods\n5. **Alert** — Define threshold and anomaly alerts on critical paths; validate no false-positive flood before shipping\n\n## Quick-Start Examples\n\n### Structured Logging (Node.js / Pino)\n```js\nimport pino from 'pino';\n\nconst logger = pino({ level: 'info' });\n\n// Good — structured fields, includes correlation ID\nlogger.info({ requestId: req.id, userId: req.user.id, durationMs: elapsed }, 'order.created');\n\n// Bad — string interpolation, no correlation\nconsole.log(`Order created for user ${userId}`);\n```\n\n### Prometheus Metrics (Node.js)\n```js\nimport { Counter, Histogram, register } from 'prom-client';\n\nconst httpRequests = new Counter({\n  name: 'http_requests_total',\n  help: 'Total HTTP requests',\n  labelNames: ['method', 'route', 'status'],\n});\n\nconst httpDuration = new Histogram({\n  name: 'http_request_duration_seconds',\n  help: 'HTTP request latency',\n  labelNames: ['method', 'route'],\n  buckets: [0.05, 0.1, 0.3, 0.5, 1, 2, 5],\n});\n\n// Instrument a route\napp.use((req, res, next) => {\n  const end = httpDuration.startTimer({ method: req.method, route: req.path });\n  res.on('finish', () => {\n    httpRequests.inc({ method: req.method, route: req.path, status: res.statusCode });\n    end();\n  });\n  next();\n});\n\n// Expose scrape endpoint\napp.get('/metrics', async (req, res) => {\n  res.set('Content-Type', register.contentType);\n  res.end(await register.metrics());\n});\n```\n\n### OpenTelemetry Tracing (Node.js)\n```js\nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { trace } from '@opentelemetry/api';\n\nconst sdk = new NodeSDK({\n  traceExporter: new OTLPTraceExporter({ url: 'http://jaeger:4318/v1/traces' }),\n});\nsdk.start();\n\n// Manual span around a critical operation\nconst tracer = trace.getTracer('order-service');\nasync function processOrder(orderId) {\n  const span = tracer.startSpan('order.process');\n  span.setAttribute('order.id', orderId);\n  try {\n    const result = await db.saveOrder(orderId);\n    span.setStatus({ code: SpanStatusCode.OK });\n    return result;\n  } catch (err) {\n    span.recordException(err);\n    span.setStatus({ code: SpanStatusCode.ERROR });\n    throw err;\n  } finally {\n    span.end();\n  }\n}\n```\n\n### Prometheus Alerting Rule\n```yaml\ngroups:\n  - name: api.rules\n    rules:\n      - alert: HighErrorRate\n        expr: |\n          rate(http_requests_total{status=~\"5..\"}[5m])\n          / rate(http_requests_total[5m]) > 0.05\n        for: 2m\n        labels:\n          severity: critical\n        annotations:\n          summary: \"Error rate above 5% on {{ $labels.route }}\"\n```\n\n### k6 Load Test\n```js\nimport http from 'k6/http';\nimport { check, sleep } from 'k6';\n\nexport const options = {\n  stages: [\n    { duration: '1m', target: 50 },   // ramp up\n    { duration: '5m', target: 50 },   // sustained load\n    { duration: '1m', target: 0 },    // ramp down\n  ],\n  thresholds: {\n    http_req_duration: ['p(95)<500'],  // 95th percentile < 500 ms\n    http_req_failed:   ['rate<0.01'],  // error rate < 1%\n  },\n};\n\nexport default function () {\n  const res = http.get('https://api.example.com/orders');\n  check(res, { 'status is 200': (r) => r.status === 200 });\n  sleep(1);\n}\n```\n\n## Reference Guide\n\nLoad detailed guidance based on context:\n\n| Topic | Reference | Load When |\n|-------|-----------|-----------|\n| Logging | `references/structured-logging.md` | Pino, JSON logging |\n| Metrics | `references/prometheus-metrics.md` | Counter, Histogram, Gauge |\n| Tracing | `references/opentelemetry.md` | OpenTelemetry, spans |\n| Alerting | `references/alerting-rules.md` | Prometheus alerts |\n| Dashboards | `references/dashboards.md` | RED/USE method, Grafana |\n| Performance Testing | `references/performance-testing.md` | Load testing, k6, Artillery, benchmarks |\n| Profiling | `references/application-profiling.md` | CPU/memory profiling, bottlenecks |\n| Capacity Planning | `references/capacity-planning.md` | Scaling, forecasting, budgets |\n\n## Constraints\n\n### MUST DO\n- Use structured logging (JSON)\n- Include request IDs for correlation\n- Set up alerts for critical paths\n- Monitor business metrics, not just technical\n- Use appropriate metric types (counter/gauge/histogram)\n- Implement health check endpoints\n\n### MUST NOT DO\n- Log sensitive data (passwords, tokens, PII)\n- Alert on every error (alert fatigue)\n- Use string interpolation in logs (use structured fields)\n- Skip correlation IDs in distributed systems\n\n[Documentation](https://jeffallan.github.io/claude-skills/skills/devops/monitoring-expert/)","author":"@Jeffallan","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Jeffallan/claude-skills/tree/main/skills/monitoring-expert","license":"MIT","category":"productivity","lang":"en","tokens":1311,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/alerting-rules.md","size":3452,"sha256":"0b8d94c81c09ce121ad00e399f204db9d7603ea08277e7587cbf2965940bb8c1"},{"path":"references/application-profiling.md","size":6376,"sha256":"db873957f8268ca329e86bdc216de556be68ff231d8b4147b65168333af5a51f"},{"path":"references/capacity-planning.md","size":8269,"sha256":"8f9cdd499931ab20fffbc89f7325ba3b1336463fbfacaf6d7bb754fc40a9c716"},{"path":"references/dashboards.md","size":3812,"sha256":"283607d4b1b94c4abdb8d1ed09668442ea048620f741127367ae52c9cacbcc9c"},{"path":"references/opentelemetry.md","size":3345,"sha256":"2f2cf89ca63ed14f9db16a64865e31114134de10e5f9e45ea598a51acaf4623c"},{"path":"references/performance-testing.md","size":5900,"sha256":"35ba1c05287ccb5fe6b2f62704cd9b99a90a6882c6bc94b8873af54f9f86dc55"},{"path":"references/prometheus-metrics.md","size":3108,"sha256":"f1c5d9271a599d5e34ac5e06ee2efddd20d08fc327f08a44722da1e51563321e"},{"path":"references/structured-logging.md","size":2852,"sha256":"2d17ee1782d39cd07add6961dcba3ee24bd8a6fc0d88e7a8643941b433fdcf80"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["api.example.com","hooks.slack.com","jeffallan.github.io","wiki.example.com"]}}