diff --git a/README.md b/README.md index f4d0dd9..f8efdf8 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ _Another attempt of blogging or personal knowledge base_ ## 2026 +- 2026-02-24 - [How to Monitor Claude Code with OpenTelemetry](docs/blog/2026/2026-02-24-claude-code-mon.md) - 2026-02-18 - [How Node.js Embeds Built-in JS Modules](docs/blog/2026/2026-02-18-nodejs-embed-std-lib.md) - 2026-02-16 - [The "Silent Watcher" Regression in MkDocs 1.6.1](docs/blog/2026/2026-02-16-mkdocs-livereload-bug.md) - 2026-01-31 - [Git Doesn't Track File Renames (And How It Fakes It)](docs/blog/2026/2026-01-31-git-content-similarity.md) diff --git a/docs/blog/2025/2025-10-29-claude-code-cli-notes.md b/docs/blog/2025/2025-10-29-claude-code-cli-notes.md index 2fba709..fe8b7c2 100644 --- a/docs/blog/2025/2025-10-29-claude-code-cli-notes.md +++ b/docs/blog/2025/2025-10-29-claude-code-cli-notes.md @@ -1,5 +1,5 @@ # Claude Code CLI Prompts - +  diff --git a/docs/blog/2026/2026-02-24-claude-code-mon.md b/docs/blog/2026/2026-02-24-claude-code-mon.md new file mode 100644 index 0000000..5013bcf --- /dev/null +++ b/docs/blog/2026/2026-02-24-claude-code-mon.md @@ -0,0 +1,110 @@ +# How to Monitor Claude Code with OpenTelemetry + + + + +**TL;DR**: Claude Code is powerful but you have minimal visibility into costs, token usage, or development patterns. I pre-configured a 5-minute OpenTelemetry monitoring stack (Prometheus + Loki + Grafana) that shows exactly where your money goes and how effective prompt caching really is. + +## The Problem + +Claude Code gives you no built-in visibility into: + +- Which models are eating your budget +- Whether prompt caching is actually saving you money +- How many tokens you're burning through daily +- Development velocity metrics (lines changed, commits, PRs) + +## The Solution + +I configured an observability stack using industry-standard tools: + + + +**Architecture:** + +- **Claude Code** exports telemetry via OpenTelemetry Protocol (OTLP) +- **OTel Collector** receives metrics and logs, routes them appropriately +- **Prometheus** stores time-series metrics (costs, tokens, cache rates) +- **Loki** stores logs (session logs, real-time activity) +- **Grafana** visualizes everything with pre-built dashboards + +All configuration, automation, and dashboards are in the GitHub repo: [halyph/claude-mon](https://github.com/halyph/claude-mon). + +## Quick Demo + +One command: + +```bash +git clone https://github.com/halyph/claude-mon.git +cd claude-mon +./setup.sh +``` + + + +Wait 2 minutes for setup to complete, then open `http://localhost:3000`. Default credentials: `admin/admin`. + +## What You Get + +### Two Grafana Dashboards + +**Metrics Dashboard** + + + +16 panels: + +- **Cost tracking**: Total spend by model, cost distribution pie chart +- **Token usage**: Input/output/cache tokens over time +- **Cache effectiveness**: Hit rate gauge showing cache read/write ratios +- **Development activity**: Lines changed, commits created, PRs opened +- **Code edits**: Accept/reject decisions by tool and language + +**Logs Dashboard** + + + +Real-time log streaming with: + +- Live session activity (refreshes every 5 seconds) +- Log volume over time +- Per-session filtering +- Model-based categorization + +**NOTE**: Dashboards are pre-configured templates. Customize as needed. + +## Key Metrics Reference + +Claude Code exports these metrics (converted to Prometheus format): + +| Metric | What It Measures | Why It Matters | +|--------|-----------------|----------------| +| `claude_code_cost_usage_total` | Cost in USD by model/session | Budget tracking, model comparison | +| `claude_code_token_usage_total` | Tokens by type (input/output/cache) | Optimize prompts, track cache effectiveness | +| `claude_code_active_time_total` | Session duration (user/cli) | Understand usage patterns | +| `claude_code_lines_of_code_count` | Lines added/removed | Development velocity | +| `claude_code_commit_count` | Git commits created | Productivity metric | +| `claude_code_code_edit_tool_decision` | Accept/reject by tool/language | Quality tracking | + +All metrics include standard labels: `model`, `session_id`, `terminal_type`, `user_id`, `type`. + +## Data Persistence + +Docker volumes preserve all historical data: + +- `prometheus-data`: Metrics time-series +- `loki-data`: Log streams +- `grafana-data`: Dashboards and settings + +```bash +docker-compose down # Stops services, keeps data +docker-compose down -v # Stops services, deletes data +``` + +## References + +- **GitHub Repo**: [halyph/claude-mon](https://github.com/halyph/claude-mon) - Full setup, configuration, and dashboards +- **Claude Code Docs**: [Monitoring & Usage](https://code.claude.com/docs/en/monitoring-usage) - Official telemetry documentation +- [**OpenTelemetry**](https://opentelemetry.io/) - OTLP protocol and collectors +- [**Prometheus**](https://prometheus.io/) - Time-series metrics database +- [**Grafana**](https://grafana.com/) - Visualization and dashboards diff --git a/docs/blog/2026/2026-02-24-claude-code-mon/pic0.jpg b/docs/blog/2026/2026-02-24-claude-code-mon/pic0.jpg new file mode 100644 index 0000000..a6afe20 Binary files /dev/null and b/docs/blog/2026/2026-02-24-claude-code-mon/pic0.jpg differ diff --git a/docs/blog/2026/2026-02-24-claude-code-mon/pic1-arch.png b/docs/blog/2026/2026-02-24-claude-code-mon/pic1-arch.png new file mode 100644 index 0000000..930962f Binary files /dev/null and b/docs/blog/2026/2026-02-24-claude-code-mon/pic1-arch.png differ diff --git a/docs/blog/2026/2026-02-24-claude-code-mon/pic2_cc_monitoring.png b/docs/blog/2026/2026-02-24-claude-code-mon/pic2_cc_monitoring.png new file mode 100644 index 0000000..2ccfdfe Binary files /dev/null and b/docs/blog/2026/2026-02-24-claude-code-mon/pic2_cc_monitoring.png differ diff --git a/docs/blog/2026/2026-02-24-claude-code-mon/pic3_cc_logs.png b/docs/blog/2026/2026-02-24-claude-code-mon/pic3_cc_logs.png new file mode 100644 index 0000000..ad8e282 Binary files /dev/null and b/docs/blog/2026/2026-02-24-claude-code-mon/pic3_cc_logs.png differ diff --git a/docs/blog/2026/2026-02-24-claude-code-mon/setup_sh.jpg b/docs/blog/2026/2026-02-24-claude-code-mon/setup_sh.jpg new file mode 100644 index 0000000..0ee37d9 Binary files /dev/null and b/docs/blog/2026/2026-02-24-claude-code-mon/setup_sh.jpg differ diff --git a/docs/blog/2026/2026-02-24-claude-code-mon/telemetry-architecture.excalidraw b/docs/blog/2026/2026-02-24-claude-code-mon/telemetry-architecture.excalidraw new file mode 100644 index 0000000..4e72958 --- /dev/null +++ b/docs/blog/2026/2026-02-24-claude-code-mon/telemetry-architecture.excalidraw @@ -0,0 +1,824 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", + "elements": [ + { + "id": "claude-code-box", + "type": "rectangle", + "x": 100, + "y": 199.16796875, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#333333", + "backgroundColor": "#4a9eff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 3 + }, + "seed": 1, + "version": 6, + "versionNonce": 1966925574, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-claude-otel", + "type": "arrow" + } + ], + "updated": 1771922029351, + "link": null, + "locked": false, + "index": "a0", + "frameId": null + }, + { + "id": "claude-code-text", + "type": "text", + "x": 135, + "y": 235, + "width": 110, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 2, + "version": 2, + "versionNonce": 1773701574, + "isDeleted": false, + "boundElements": [], + "updated": 1771921984148, + "link": null, + "locked": false, + "text": "Claude Code", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 18, + "containerId": null, + "originalText": "Claude Code", + "index": "a1", + "frameId": null, + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "otel-box", + "type": "rectangle", + "x": 420, + "y": 200, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#40c057", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 3 + }, + "seed": 3, + "version": 13, + "versionNonce": 147619290, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-otel-prometheus", + "type": "arrow" + }, + { + "id": "arrow-otel-loki", + "type": "arrow" + }, + { + "id": "arrow-claude-otel", + "type": "arrow" + } + ], + "updated": 1771922183241, + "link": null, + "locked": false, + "index": "a2", + "frameId": null + }, + { + "id": "otel-text", + "type": "text", + "x": 440, + "y": 235, + "width": 140, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 4, + "version": 2, + "versionNonce": 2127520006, + "isDeleted": false, + "boundElements": [], + "updated": 1771921984148, + "link": null, + "locked": false, + "text": "OTel Collector", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 18, + "containerId": null, + "originalText": "OTel Collector", + "index": "a3", + "frameId": null, + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "prometheus-box", + "type": "rectangle", + "x": 740, + "y": 100, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#333333", + "backgroundColor": "#f9ab00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 3 + }, + "seed": 5, + "version": 3, + "versionNonce": 1797538054, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-otel-prometheus", + "type": "arrow" + }, + { + "id": "arrow-prometheus-grafana", + "type": "arrow" + } + ], + "updated": 1771922108748, + "link": null, + "locked": false, + "index": "a4", + "frameId": null + }, + { + "id": "prometheus-text", + "type": "text", + "x": 760, + "y": 125, + "width": 140, + "height": 50, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 6, + "version": 2, + "versionNonce": 1367953478, + "isDeleted": false, + "boundElements": [], + "updated": 1771921984148, + "link": null, + "locked": false, + "text": "Prometheus\n:9090", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 43, + "containerId": null, + "originalText": "Prometheus\n:9090", + "index": "a5", + "frameId": null, + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "loki-box", + "type": "rectangle", + "x": 740, + "y": 300, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#333333", + "backgroundColor": "#fab005", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 3 + }, + "seed": 7, + "version": 6, + "versionNonce": 543973146, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-otel-loki", + "type": "arrow" + }, + { + "id": "arrow-loki-grafana", + "type": "arrow" + } + ], + "updated": 1771922116488, + "link": null, + "locked": false, + "index": "a6", + "frameId": null + }, + { + "id": "loki-text", + "type": "text", + "x": 785, + "y": 325, + "width": 90, + "height": 50, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 8, + "version": 2, + "versionNonce": 1841518470, + "isDeleted": false, + "boundElements": [], + "updated": 1771921984148, + "link": null, + "locked": false, + "text": "Loki\n:3100", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 43, + "containerId": null, + "originalText": "Loki\n:3100", + "index": "a7", + "frameId": null, + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "grafana-box", + "type": "rectangle", + "x": 1060, + "y": 200.24609375, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#333333", + "backgroundColor": "#f05a28", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 3 + }, + "seed": 9, + "version": 4, + "versionNonce": 446379270, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-prometheus-grafana", + "type": "arrow" + }, + { + "id": "arrow-loki-grafana", + "type": "arrow" + } + ], + "updated": 1771922068337, + "link": null, + "locked": false, + "index": "a8", + "frameId": null + }, + { + "id": "grafana-text", + "type": "text", + "x": 1090.03515625, + "y": 225.01171875, + "width": 110, + "height": 50, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 10, + "version": 67, + "versionNonce": 761148506, + "isDeleted": false, + "boundElements": [], + "updated": 1771922081992, + "link": null, + "locked": false, + "text": "Grafana\n:3000", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 43, + "containerId": null, + "originalText": "Grafana\n:3000", + "index": "a9", + "frameId": null, + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "arrow-claude-otel", + "type": "arrow", + "x": 280.8723424999597, + "y": 249.04169707452846, + "width": 131.43879482745643, + "height": 0.3399591417828276, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 11, + "version": 84, + "versionNonce": 1901332890, + "isDeleted": false, + "boundElements": [], + "updated": 1771922130513, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 131.43879482745643, + 0.3399591417828276 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "claude-code-box", + "focus": -0.00757812499999845, + "gap": 1 + }, + "endBinding": { + "elementId": "otel-box", + "focus": 0.007578125000001426, + "gap": 8.949929257125461 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "index": "aA", + "frameId": null + }, + { + "id": "arrow-otel-prometheus", + "type": "arrow", + "x": 600.8723424999596, + "y": 242.0706346533662, + "width": 138.25531500008083, + "height": 88.97695825230119, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 13, + "version": 62, + "versionNonce": 426231834, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-label-2", + "type": "text" + } + ], + "updated": 1771922130513, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 138.25531500008083, + -88.97695825230119 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "otel-box", + "focus": 0.4684278533845762, + "gap": 1 + }, + "endBinding": { + "elementId": "prometheus-box", + "focus": 0.5132354064617818, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "index": "aC", + "frameId": null + }, + { + "id": "arrow-label-2", + "type": "text", + "x": 636.9185009719064, + "y": 207.18338403779285, + "width": 71.43992614746094, + "height": 31.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 14, + "version": 5, + "versionNonce": 1288412294, + "isDeleted": false, + "boundElements": [], + "updated": 1771922010379, + "link": null, + "locked": false, + "text": "Metrics", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 18, + "containerId": "arrow-otel-prometheus", + "originalText": "Metrics", + "index": "aD", + "frameId": null, + "autoResize": true, + "lineHeight": 1.5625 + }, + { + "id": "arrow-otel-loki", + "type": "arrow", + "x": 602.3070817269995, + "y": 267.89324682123754, + "width": 136.820575773041, + "height": 82.38577739565034, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 15, + "version": 113, + "versionNonce": 1143715034, + "isDeleted": false, + "boundElements": [ + { + "id": "arrow-label-3", + "type": "text" + } + ], + "updated": 1771922130513, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 136.820575773041, + 82.38577739565034 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "otel-box", + "focus": -0.3617225895013527, + "gap": 2.6535924999595863 + }, + "endBinding": { + "elementId": "loki-box", + "focus": -0.5278407303848756, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "index": "aE", + "frameId": null + }, + { + "id": "arrow-label-3", + "type": "text", + "x": 650.9223919630551, + "y": 261.56661596222966, + "width": 43.93995666503906, + "height": 31.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 16, + "version": 5, + "versionNonce": 1291167130, + "isDeleted": false, + "boundElements": [], + "updated": 1771922008130, + "link": null, + "locked": false, + "text": "Logs", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 18, + "containerId": "arrow-otel-loki", + "originalText": "Logs", + "index": "aF", + "frameId": null, + "autoResize": true, + "lineHeight": 1.5625 + }, + { + "id": "arrow-prometheus-grafana", + "type": "arrow", + "x": 920.8723424999595, + "y": 152.48798907547783, + "width": 142.0858327113075, + "height": 45.18582687340293, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 17, + "version": 4, + "versionNonce": 750429254, + "isDeleted": false, + "boundElements": [], + "updated": 1771922068337, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 142.0858327113075, + 45.18582687340293 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "prometheus-box", + "focus": -0.35, + "gap": 1 + }, + "endBinding": { + "elementId": "grafana-box", + "focus": 0.4, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "index": "aG", + "frameId": null + }, + { + "id": "arrow-loki-grafana", + "type": "arrow", + "x": 920.8723424999596, + "y": 347.57722277741453, + "width": 141.77926907556275, + "height": 44.906681755082104, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 18, + "version": 4, + "versionNonce": 2141858694, + "isDeleted": false, + "boundElements": [], + "updated": 1771922068337, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 141.77926907556275, + -44.906681755082104 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "loki-box", + "focus": 0.35, + "gap": 1 + }, + "endBinding": { + "elementId": "grafana-box", + "focus": -0.4, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "index": "aH", + "frameId": null + }, + { + "id": "h0dynFqBOZvZWlQ7Osm-O", + "type": "text", + "x": 292.4842987060547, + "y": 225.28125, + "width": 86.36238098144531, + "height": 18.350814943923968, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aI", + "roundness": null, + "seed": 1963988678, + "version": 339, + "versionNonce": 988404314, + "isDeleted": false, + "boundElements": null, + "updated": 1771922307169, + "link": null, + "locked": false, + "text": "OTLP gRPC", + "fontSize": 14.680651955139174, + "fontFamily": 5, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "OTLP gRPC", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "LY_1WIYCFOHAEIAQFeOgC", + "type": "text", + "x": 330.0067138671875, + "y": 253.95387255607602, + "width": 48.8399658203125, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aJ", + "roundness": null, + "seed": 74902790, + "version": 411, + "versionNonce": 409849306, + "isDeleted": false, + "boundElements": [], + "updated": 1771922331032, + "link": null, + "locked": false, + "text": ":4317", + "fontSize": 20, + "fontFamily": 5, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": ":4317", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/blog/index.md b/docs/blog/index.md index 443c4fc..2859cae 100644 --- a/docs/blog/index.md +++ b/docs/blog/index.md @@ -9,6 +9,7 @@ hide: ## 2026 +- 2026-02-24 - [How to Monitor Claude Code with OpenTelemetry](2026/2026-02-24-claude-code-mon.md) - 2026-02-18 - [How Node.js Embeds Built-in JS Modules](2026/2026-02-18-nodejs-embed-std-lib.md) - 2026-02-16 - [The "Silent Watcher" Regression in MkDocs 1.6.1](2026/2026-02-16-mkdocs-livereload-bug.md) - 2026-01-31 - [Git Doesn't Track File Renames (And How It Fakes It)](2026/2026-01-31-git-content-similarity.md) diff --git a/docs/tags/cloud.svg b/docs/tags/cloud.svg index 96132e9..c8ebbfe 100644 --- a/docs/tags/cloud.svg +++ b/docs/tags/cloud.svg @@ -1,4 +1,4 @@ - \ No newline at end of file diff --git a/docs/tags/index.md b/docs/tags/index.md index d8fcee8..07b6439 100644 --- a/docs/tags/index.md +++ b/docs/tags/index.md @@ -2,13 +2,13 @@ Browse blog posts by tag. -**📊 174 posts • 77 tags** +**📊 175 posts • 82 tags** **Top Tags**: [java (49)](#java) • [python (24)](#python) • [ruby (24)](#ruby) • [scala (20)](#scala) • [conference (14)](#conference) • [thoughts (12)](#thoughts) • [golang (10)](#golang)