@girardmedia/bootspring 3.3.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/assets/agents/accessibility-auditor.md +39 -0
  2. package/assets/agents/api-designer.md +40 -0
  3. package/assets/agents/auth-implementer.md +64 -0
  4. package/assets/agents/bug-hunter.md +42 -0
  5. package/assets/agents/bundle-analyzer.md +40 -0
  6. package/assets/agents/cache-optimizer.md +55 -0
  7. package/assets/agents/changelog-writer.md +55 -0
  8. package/assets/agents/ci-cd-builder.md +40 -0
  9. package/assets/agents/code-explainer.md +39 -0
  10. package/assets/agents/code-reviewer.md +39 -0
  11. package/assets/agents/cost-optimizer.md +57 -0
  12. package/assets/agents/cron-scheduler.md +51 -0
  13. package/assets/agents/data-seeder.md +56 -0
  14. package/assets/agents/database-architect.md +40 -0
  15. package/assets/agents/dependency-updater.md +40 -0
  16. package/assets/agents/deploy-checker.md +40 -0
  17. package/assets/agents/docker-optimizer.md +40 -0
  18. package/assets/agents/documentation-writer.md +40 -0
  19. package/assets/agents/email-builder.md +55 -0
  20. package/assets/agents/env-setup.md +40 -0
  21. package/assets/agents/error-handler.md +40 -0
  22. package/assets/agents/eslint-fixer.md +46 -0
  23. package/assets/agents/feature-flagger.md +69 -0
  24. package/assets/agents/git-detective.md +39 -0
  25. package/assets/agents/graphql-builder.md +60 -0
  26. package/assets/agents/incident-responder.md +59 -0
  27. package/assets/agents/log-analyzer.md +39 -0
  28. package/assets/agents/migration-planner.md +41 -0
  29. package/assets/agents/monorepo-navigator.md +39 -0
  30. package/assets/agents/nextjs-expert.md +57 -0
  31. package/assets/agents/notification-builder.md +56 -0
  32. package/assets/agents/onboarding-guide.md +39 -0
  33. package/assets/agents/performance-profiler.md +40 -0
  34. package/assets/agents/prisma-expert.md +57 -0
  35. package/assets/agents/rate-limiter.md +58 -0
  36. package/assets/agents/react-expert.md +58 -0
  37. package/assets/agents/refactorer.md +42 -0
  38. package/assets/agents/regex-builder.md +46 -0
  39. package/assets/agents/release-manager.md +40 -0
  40. package/assets/agents/s3-manager.md +58 -0
  41. package/assets/agents/schema-validator.md +40 -0
  42. package/assets/agents/search-builder.md +62 -0
  43. package/assets/agents/security-auditor.md +39 -0
  44. package/assets/agents/sitemap-generator.md +53 -0
  45. package/assets/agents/stripe-integrator.md +59 -0
  46. package/assets/agents/tailwind-expert.md +55 -0
  47. package/assets/agents/tech-debt-tracker.md +39 -0
  48. package/assets/agents/test-writer.md +42 -0
  49. package/assets/agents/type-fixer.md +45 -0
  50. package/assets/agents/webhook-builder.md +54 -0
  51. package/assets/rules/cpp.md +53 -0
  52. package/assets/rules/css.md +52 -0
  53. package/assets/rules/go.md +50 -0
  54. package/assets/rules/html.md +52 -0
  55. package/assets/rules/java.md +51 -0
  56. package/assets/rules/kotlin.md +50 -0
  57. package/assets/rules/php.md +51 -0
  58. package/assets/rules/python.md +51 -0
  59. package/assets/rules/ruby.md +51 -0
  60. package/assets/rules/rust.md +49 -0
  61. package/assets/rules/shell.md +52 -0
  62. package/assets/rules/sql.md +49 -0
  63. package/assets/rules/swift.md +50 -0
  64. package/assets/rules/typescript.md +52 -0
  65. package/assets/rules/yaml-json.md +51 -0
  66. package/assets/skills/accessibility.md +210 -0
  67. package/assets/skills/agent-patterns.md +387 -0
  68. package/assets/skills/ai-integration.md +263 -0
  69. package/assets/skills/animation-patterns.md +224 -0
  70. package/assets/skills/api-design.md +218 -0
  71. package/assets/skills/api-gateway.md +341 -0
  72. package/assets/skills/api-versioning.md +226 -0
  73. package/assets/skills/astro-patterns.md +233 -0
  74. package/assets/skills/auth-patterns.md +248 -0
  75. package/assets/skills/aws-patterns.md +171 -0
  76. package/assets/skills/background-jobs.md +162 -0
  77. package/assets/skills/browser-extensions.md +309 -0
  78. package/assets/skills/caching-patterns.md +253 -0
  79. package/assets/skills/ci-cd.md +251 -0
  80. package/assets/skills/cli-development.md +296 -0
  81. package/assets/skills/code-review.md +185 -0
  82. package/assets/skills/cron-patterns.md +327 -0
  83. package/assets/skills/data-fetching.md +231 -0
  84. package/assets/skills/database-migrations.md +346 -0
  85. package/assets/skills/database-patterns.md +219 -0
  86. package/assets/skills/debugging.md +281 -0
  87. package/assets/skills/design-system.md +289 -0
  88. package/assets/skills/django-patterns.md +182 -0
  89. package/assets/skills/docker-patterns.md +235 -0
  90. package/assets/skills/e2e-testing.md +287 -0
  91. package/assets/skills/edge-computing.md +268 -0
  92. package/assets/skills/electron-patterns.md +266 -0
  93. package/assets/skills/email-templates.md +206 -0
  94. package/assets/skills/error-handling.md +265 -0
  95. package/assets/skills/event-driven.md +232 -0
  96. package/assets/skills/express-patterns.md +239 -0
  97. package/assets/skills/fastapi-patterns.md +198 -0
  98. package/assets/skills/feature-flags.md +212 -0
  99. package/assets/skills/figma-to-code.md +298 -0
  100. package/assets/skills/file-upload.md +228 -0
  101. package/assets/skills/forms-patterns.md +264 -0
  102. package/assets/skills/gcp-patterns.md +189 -0
  103. package/assets/skills/git-workflow.md +187 -0
  104. package/assets/skills/golang-patterns.md +185 -0
  105. package/assets/skills/graphql-patterns.md +244 -0
  106. package/assets/skills/i18n-patterns.md +172 -0
  107. package/assets/skills/image-processing.md +350 -0
  108. package/assets/skills/java-springboot.md +226 -0
  109. package/assets/skills/kotlin-patterns.md +207 -0
  110. package/assets/skills/kubernetes-patterns.md +326 -0
  111. package/assets/skills/laravel-patterns.md +261 -0
  112. package/assets/skills/llm-fine-tuning.md +335 -0
  113. package/assets/skills/load-testing.md +303 -0
  114. package/assets/skills/logging-observability.md +228 -0
  115. package/assets/skills/markdown-processing.md +318 -0
  116. package/assets/skills/mcp-server-patterns.md +292 -0
  117. package/assets/skills/microservices.md +272 -0
  118. package/assets/skills/migration-patterns.md +239 -0
  119. package/assets/skills/mongodb-patterns.md +189 -0
  120. package/assets/skills/monorepo-patterns.md +287 -0
  121. package/assets/skills/nextjs-app-router.md +237 -0
  122. package/assets/skills/notification-patterns.md +348 -0
  123. package/assets/skills/oauth-patterns.md +246 -0
  124. package/assets/skills/payment-integration.md +222 -0
  125. package/assets/skills/pdf-generation.md +307 -0
  126. package/assets/skills/performance-optimization.md +277 -0
  127. package/assets/skills/php-patterns.md +210 -0
  128. package/assets/skills/prisma-patterns.md +241 -0
  129. package/assets/skills/prompt-engineering.md +193 -0
  130. package/assets/skills/pwa-patterns.md +247 -0
  131. package/assets/skills/python-patterns.md +158 -0
  132. package/assets/skills/python-testing.md +172 -0
  133. package/assets/skills/queue-patterns.md +295 -0
  134. package/assets/skills/rag-patterns.md +159 -0
  135. package/assets/skills/rate-limiting.md +319 -0
  136. package/assets/skills/react-components.md +201 -0
  137. package/assets/skills/react-native-patterns.md +299 -0
  138. package/assets/skills/real-time-patterns.md +181 -0
  139. package/assets/skills/redis-patterns.md +188 -0
  140. package/assets/skills/refactoring.md +218 -0
  141. package/assets/skills/regex-patterns.md +191 -0
  142. package/assets/skills/remix-patterns.md +262 -0
  143. package/assets/skills/responsive-design.md +199 -0
  144. package/assets/skills/ruby-rails-patterns.md +178 -0
  145. package/assets/skills/rust-patterns.md +211 -0
  146. package/assets/skills/search-patterns.md +227 -0
  147. package/assets/skills/security-hardening.md +237 -0
  148. package/assets/skills/seo-patterns.md +179 -0
  149. package/assets/skills/serverless-patterns.md +223 -0
  150. package/assets/skills/sql-optimization.md +154 -0
  151. package/assets/skills/state-management.md +254 -0
  152. package/assets/skills/storybook-patterns.md +330 -0
  153. package/assets/skills/svelte-patterns.md +258 -0
  154. package/assets/skills/swift-patterns.md +227 -0
  155. package/assets/skills/tailwind-patterns.md +272 -0
  156. package/assets/skills/tdd-workflow.md +199 -0
  157. package/assets/skills/terraform-patterns.md +270 -0
  158. package/assets/skills/testing-react.md +240 -0
  159. package/assets/skills/testing-vitest.md +232 -0
  160. package/assets/skills/typescript-strict.md +159 -0
  161. package/assets/skills/video-processing.md +340 -0
  162. package/assets/skills/vue-patterns.md +247 -0
  163. package/assets/skills/web-workers.md +327 -0
  164. package/assets/skills/webhooks-patterns.md +283 -0
  165. package/assets/skills/websocket-patterns.md +306 -0
  166. package/dist/cli/index.js +941 -958
  167. package/dist/core/index.d.ts +341 -11
  168. package/dist/core.js +58 -95
  169. package/dist/mcp/index.d.ts +33 -1
  170. package/dist/mcp-server.js +177 -255
  171. package/package.json +4 -1
@@ -0,0 +1,303 @@
1
+ ---
2
+ name: load-testing
3
+ description: Load testing patterns with k6 and Artillery for scenarios, thresholds, spike testing, stress testing, and reporting.
4
+ ---
5
+
6
+ # Load Testing Patterns
7
+
8
+ ## When to Use
9
+ Run load tests before major releases, after infrastructure changes, and regularly in CI to catch performance regressions. Use k6 for script-based testing with built-in metrics, or Artillery for YAML-based declarative scenarios. These patterns cover gradual ramp-up, spike testing, soak testing, and threshold-based pass/fail criteria. Test against staging environments that mirror production, never against production directly.
10
+
11
+ ## How It Works
12
+
13
+ ### k6 Basic Load Test
14
+
15
+ ```javascript
16
+ // load-tests/api-load.js
17
+ import http from 'k6/http';
18
+ import { check, sleep } from 'k6';
19
+ import { Rate, Trend } from 'k6/metrics';
20
+
21
+ const errorRate = new Rate('errors');
22
+ const latency = new Trend('api_latency');
23
+
24
+ export const options = {
25
+ stages: [
26
+ { duration: '1m', target: 20 }, // ramp up to 20 VUs
27
+ { duration: '3m', target: 20 }, // hold at 20 VUs
28
+ { duration: '2m', target: 50 }, // ramp up to 50 VUs
29
+ { duration: '3m', target: 50 }, // hold at 50 VUs
30
+ { duration: '1m', target: 0 }, // ramp down
31
+ ],
32
+ thresholds: {
33
+ http_req_duration: ['p(95)<500', 'p(99)<1000'], // 95th < 500ms, 99th < 1s
34
+ http_req_failed: ['rate<0.01'], // error rate < 1%
35
+ errors: ['rate<0.05'], // custom error rate < 5%
36
+ },
37
+ };
38
+
39
+ const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';
40
+
41
+ export default function () {
42
+ // GET endpoint
43
+ const listRes = http.get(`${BASE_URL}/api/posts`, {
44
+ headers: { Authorization: `Bearer ${__ENV.TOKEN}` },
45
+ tags: { name: 'GET /api/posts' },
46
+ });
47
+
48
+ check(listRes, {
49
+ 'GET /api/posts status 200': (r) => r.status === 200,
50
+ 'GET /api/posts has items': (r) => JSON.parse(r.body).length > 0,
51
+ }) || errorRate.add(1);
52
+
53
+ latency.add(listRes.timings.duration);
54
+
55
+ sleep(1);
56
+
57
+ // POST endpoint
58
+ const createRes = http.post(
59
+ `${BASE_URL}/api/posts`,
60
+ JSON.stringify({ title: `Post ${Date.now()}`, body: 'Load test content' }),
61
+ {
62
+ headers: {
63
+ 'Content-Type': 'application/json',
64
+ Authorization: `Bearer ${__ENV.TOKEN}`,
65
+ },
66
+ tags: { name: 'POST /api/posts' },
67
+ }
68
+ );
69
+
70
+ check(createRes, {
71
+ 'POST /api/posts status 201': (r) => r.status === 201,
72
+ }) || errorRate.add(1);
73
+
74
+ sleep(1);
75
+ }
76
+ ```
77
+
78
+ ### k6 Spike Test
79
+
80
+ ```javascript
81
+ // load-tests/spike-test.js
82
+ export const options = {
83
+ stages: [
84
+ { duration: '30s', target: 10 }, // warm up
85
+ { duration: '10s', target: 200 }, // spike to 200 VUs
86
+ { duration: '1m', target: 200 }, // hold spike
87
+ { duration: '10s', target: 10 }, // drop back
88
+ { duration: '2m', target: 10 }, // recover
89
+ { duration: '30s', target: 0 }, // cool down
90
+ ],
91
+ thresholds: {
92
+ http_req_duration: ['p(95)<2000'], // allow higher latency during spike
93
+ http_req_failed: ['rate<0.05'], // allow up to 5% errors during spike
94
+ },
95
+ };
96
+ ```
97
+
98
+ ### k6 Soak Test
99
+
100
+ ```javascript
101
+ // load-tests/soak-test.js
102
+ export const options = {
103
+ stages: [
104
+ { duration: '2m', target: 30 }, // ramp up
105
+ { duration: '4h', target: 30 }, // hold for 4 hours
106
+ { duration: '2m', target: 0 }, // ramp down
107
+ ],
108
+ thresholds: {
109
+ http_req_duration: ['p(95)<500'],
110
+ http_req_failed: ['rate<0.01'],
111
+ },
112
+ };
113
+
114
+ // Soak tests catch:
115
+ // - Memory leaks (watch RSS growth)
116
+ // - Connection pool exhaustion
117
+ // - Log file growth
118
+ // - Certificate/token expiry during test
119
+ ```
120
+
121
+ ### Artillery YAML Scenario
122
+
123
+ ```yaml
124
+ # load-tests/artillery.yml
125
+ config:
126
+ target: "http://localhost:3000"
127
+ phases:
128
+ - duration: 60
129
+ arrivalRate: 5
130
+ name: "Warm up"
131
+ - duration: 180
132
+ arrivalRate: 20
133
+ name: "Sustained load"
134
+ - duration: 60
135
+ arrivalRate: 50
136
+ name: "Peak load"
137
+ defaults:
138
+ headers:
139
+ Content-Type: "application/json"
140
+ plugins:
141
+ expect: {}
142
+ ensure:
143
+ p95: 500
144
+ maxErrorRate: 1
145
+
146
+ scenarios:
147
+ - name: "Browse and create"
148
+ weight: 70
149
+ flow:
150
+ - get:
151
+ url: "/api/posts"
152
+ expect:
153
+ - statusCode: 200
154
+ capture:
155
+ - json: "$[0].id"
156
+ as: "postId"
157
+ - think: 2
158
+ - get:
159
+ url: "/api/posts/{{ postId }}"
160
+ expect:
161
+ - statusCode: 200
162
+
163
+ - name: "Create post"
164
+ weight: 30
165
+ flow:
166
+ - post:
167
+ url: "/api/posts"
168
+ json:
169
+ title: "Load test {{ $randomString() }}"
170
+ body: "Content for load testing"
171
+ expect:
172
+ - statusCode: 201
173
+ ```
174
+
175
+ ### Custom k6 Scenario with Lifecycle
176
+
177
+ ```javascript
178
+ // load-tests/realistic-scenario.js
179
+ import http from 'k6/http';
180
+ import { check, group, sleep } from 'k6';
181
+ import { SharedArray } from 'k6/data';
182
+
183
+ // Load test data once (shared across VUs)
184
+ const users = new SharedArray('users', function () {
185
+ return JSON.parse(open('./test-users.json'));
186
+ });
187
+
188
+ export function setup() {
189
+ // Run once before all VUs
190
+ const res = http.post(`${BASE_URL}/api/auth/login`, JSON.stringify({
191
+ email: 'admin@test.com',
192
+ password: 'admin123',
193
+ }), { headers: { 'Content-Type': 'application/json' } });
194
+
195
+ return { adminToken: JSON.parse(res.body).token };
196
+ }
197
+
198
+ export default function (data) {
199
+ const user = users[__VU % users.length];
200
+
201
+ group('Authentication', () => {
202
+ const loginRes = http.post(`${BASE_URL}/api/auth/login`, JSON.stringify({
203
+ email: user.email,
204
+ password: user.password,
205
+ }), { headers: { 'Content-Type': 'application/json' } });
206
+
207
+ check(loginRes, { 'login successful': (r) => r.status === 200 });
208
+
209
+ const token = JSON.parse(loginRes.body).token;
210
+ const headers = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' };
211
+
212
+ group('Browse content', () => {
213
+ const posts = http.get(`${BASE_URL}/api/posts`, { headers });
214
+ check(posts, { 'posts loaded': (r) => r.status === 200 });
215
+ sleep(2);
216
+ });
217
+
218
+ group('Create content', () => {
219
+ const newPost = http.post(`${BASE_URL}/api/posts`, JSON.stringify({
220
+ title: `VU${__VU} Post ${__ITER}`,
221
+ body: 'Load test generated content',
222
+ }), { headers });
223
+ check(newPost, { 'post created': (r) => r.status === 201 });
224
+ });
225
+ });
226
+
227
+ sleep(Math.random() * 3 + 1); // random think time 1-4s
228
+ }
229
+
230
+ export function teardown(data) {
231
+ // Cleanup after all VUs complete
232
+ http.del(`${BASE_URL}/api/test/cleanup`, null, {
233
+ headers: { Authorization: `Bearer ${data.adminToken}` },
234
+ });
235
+ }
236
+ ```
237
+
238
+ ### CI Integration and Reporting
239
+
240
+ ```yaml
241
+ # .github/workflows/load-test.yml
242
+ name: Load Test
243
+ on:
244
+ schedule:
245
+ - cron: '0 2 * * 1' # weekly Monday 2am
246
+ workflow_dispatch:
247
+
248
+ jobs:
249
+ load-test:
250
+ runs-on: ubuntu-latest
251
+ timeout-minutes: 30
252
+ services:
253
+ app:
254
+ image: myapp:latest
255
+ ports: ['3000:3000']
256
+ steps:
257
+ - uses: actions/checkout@v4
258
+ - uses: grafana/k6-action@v0.3.1
259
+ with:
260
+ filename: load-tests/api-load.js
261
+ flags: --out json=results.json
262
+ env:
263
+ BASE_URL: http://localhost:3000
264
+ TOKEN: ${{ secrets.LOAD_TEST_TOKEN }}
265
+ - uses: actions/upload-artifact@v4
266
+ with:
267
+ name: k6-results
268
+ path: results.json
269
+ ```
270
+
271
+ ### Analyzing Results
272
+
273
+ ```bash
274
+ # Run k6 with JSON output
275
+ k6 run --out json=results.json load-tests/api-load.js
276
+
277
+ # Run k6 with summary export
278
+ k6 run --summary-export=summary.json load-tests/api-load.js
279
+
280
+ # Run Artillery with HTML report
281
+ npx artillery run load-tests/artillery.yml --output report.json
282
+ npx artillery report report.json --output report.html
283
+ ```
284
+
285
+ ## Examples
286
+
287
+ | Test Type | VU Pattern | Purpose |
288
+ |-----------|-----------|---------|
289
+ | Load | 10 to 50 VUs, hold | Normal expected traffic |
290
+ | Stress | Ramp to breaking point | Find maximum capacity |
291
+ | Spike | Sudden jump to 10x | Test auto-scaling and recovery |
292
+ | Soak | Constant 30 VUs for 4h | Memory leaks, resource exhaustion |
293
+ | Breakpoint | Increment until failure | Absolute system limits |
294
+
295
+ ## Checklist
296
+ - [ ] Thresholds set for p95 latency, p99 latency, and error rate
297
+ - [ ] Test stages include ramp-up, hold, and ramp-down phases
298
+ - [ ] `check()` validates response status and body content
299
+ - [ ] Test data loaded via `SharedArray` to minimize memory per VU
300
+ - [ ] Think time (`sleep()`) simulates realistic user behavior
301
+ - [ ] Tests run against staging, never production
302
+ - [ ] CI pipeline runs load tests on schedule with artifact upload
303
+ - [ ] Spike and soak tests run before major releases
@@ -0,0 +1,228 @@
1
+ ---
2
+ name: logging-observability
3
+ description: Logging and observability patterns with structured logging, OpenTelemetry, distributed tracing, log levels, and dashboards.
4
+ ---
5
+
6
+ # Logging and Observability
7
+
8
+ ## When to Use
9
+ Apply to every production service. Observability is the ability to understand what your system is doing from its outputs. Use structured logging for searchable logs, OpenTelemetry for distributed tracing, metrics for dashboards and alerts, and correlation IDs to trace requests across services. Set this up before the first outage, not after.
10
+
11
+ ## How It Works
12
+
13
+ ### Structured Logging with Pino
14
+
15
+ Never use `console.log` in production. Use structured JSON logs:
16
+
17
+ ```typescript
18
+ import pino from "pino";
19
+
20
+ const logger = pino({
21
+ level: process.env.LOG_LEVEL ?? "info",
22
+ formatters: {
23
+ level: (label) => ({ level: label }),
24
+ },
25
+ redact: ["req.headers.authorization", "password", "token"],
26
+ serializers: {
27
+ err: pino.stdSerializers.err,
28
+ req: pino.stdSerializers.req,
29
+ res: pino.stdSerializers.res,
30
+ },
31
+ });
32
+
33
+ // Structured log with context -- every field is searchable
34
+ logger.info(
35
+ { userId: "u_123", orderId: "o_456", amount: 99.99 },
36
+ "Order created"
37
+ );
38
+ // Output: {"level":"info","time":1716700000,"userId":"u_123","orderId":"o_456",
39
+ // "amount":99.99,"msg":"Order created"}
40
+
41
+ // Child logger inherits context
42
+ const reqLogger = logger.child({ requestId: "req_abc", userId: "u_123" });
43
+ reqLogger.info("Processing payment");
44
+ // All logs from reqLogger include requestId and userId automatically
45
+ ```
46
+
47
+ ### Log Levels -- When to Use Each
48
+
49
+ ```typescript
50
+ logger.fatal("Database connection lost, shutting down"); // process crash imminent
51
+ logger.error({ err }, "Payment processing failed"); // operation failed, needs attention
52
+ logger.warn("Rate limit approaching: 85% capacity"); // degraded, not broken yet
53
+ logger.info("Order #456 shipped to customer"); // significant business events
54
+ logger.debug({ query, params }, "Executing SQL"); // dev-only detail
55
+ logger.trace({ headers }, "Incoming request headers"); // extremely verbose
56
+ ```
57
+
58
+ Production runs at `info`. Set `debug` only for targeted troubleshooting.
59
+
60
+ ### Request Correlation Middleware
61
+
62
+ ```typescript
63
+ import { randomUUID } from "crypto";
64
+ import { AsyncLocalStorage } from "async_hooks";
65
+ import { Request, Response, NextFunction } from "express";
66
+
67
+ interface RequestContext {
68
+ requestId: string;
69
+ userId?: string;
70
+ }
71
+
72
+ const requestContext = new AsyncLocalStorage<RequestContext>();
73
+
74
+ function correlationMiddleware(req: Request, res: Response, next: NextFunction) {
75
+ const requestId = (req.headers["x-request-id"] as string) ?? randomUUID();
76
+ res.setHeader("x-request-id", requestId);
77
+
78
+ const ctx: RequestContext = { requestId, userId: req.user?.id };
79
+ requestContext.run(ctx, () => {
80
+ const start = Date.now();
81
+ res.on("finish", () => {
82
+ logger.child(ctx).info({
83
+ method: req.method,
84
+ path: req.path,
85
+ statusCode: res.statusCode,
86
+ durationMs: Date.now() - start,
87
+ }, "Request completed");
88
+ });
89
+ next();
90
+ });
91
+ }
92
+
93
+ // Get logger anywhere in the call stack
94
+ function getLogger() {
95
+ const ctx = requestContext.getStore();
96
+ return logger.child(ctx ?? {});
97
+ }
98
+ ```
99
+
100
+ ### OpenTelemetry -- Distributed Tracing
101
+
102
+ ```typescript
103
+ import { NodeSDK } from "@opentelemetry/sdk-node";
104
+ import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
105
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
106
+
107
+ const sdk = new NodeSDK({
108
+ traceExporter: new OTLPTraceExporter({
109
+ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://localhost:4318/v1/traces",
110
+ }),
111
+ instrumentations: [
112
+ getNodeAutoInstrumentations({
113
+ "@opentelemetry/instrumentation-http": { enabled: true },
114
+ "@opentelemetry/instrumentation-express": { enabled: true },
115
+ "@opentelemetry/instrumentation-pg": { enabled: true },
116
+ }),
117
+ ],
118
+ serviceName: "order-service",
119
+ });
120
+ sdk.start();
121
+ ```
122
+
123
+ Custom spans for business logic:
124
+
125
+ ```typescript
126
+ import { trace, SpanStatusCode } from "@opentelemetry/api";
127
+
128
+ const tracer = trace.getTracer("order-service");
129
+
130
+ async function processOrder(order: Order) {
131
+ return tracer.startActiveSpan("processOrder", async (span) => {
132
+ span.setAttribute("order.id", order.id);
133
+ span.setAttribute("order.total", order.total);
134
+ try {
135
+ await validateOrder(order);
136
+ await chargePayment(order);
137
+ await sendConfirmation(order);
138
+ span.setStatus({ code: SpanStatusCode.OK });
139
+ } catch (err: any) {
140
+ span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
141
+ span.recordException(err);
142
+ throw err;
143
+ } finally {
144
+ span.end();
145
+ }
146
+ });
147
+ }
148
+ ```
149
+
150
+ ### Prometheus Metrics
151
+
152
+ ```typescript
153
+ import { Counter, Histogram, Registry } from "prom-client";
154
+
155
+ const registry = new Registry();
156
+
157
+ const httpDuration = new Histogram({
158
+ name: "http_request_duration_seconds",
159
+ help: "HTTP request duration in seconds",
160
+ labelNames: ["method", "route", "status"] as const,
161
+ buckets: [0.01, 0.05, 0.1, 0.5, 1, 5],
162
+ registers: [registry],
163
+ });
164
+
165
+ const httpTotal = new Counter({
166
+ name: "http_requests_total",
167
+ help: "Total HTTP requests",
168
+ labelNames: ["method", "route", "status"] as const,
169
+ registers: [registry],
170
+ });
171
+
172
+ function metricsMiddleware(req: Request, res: Response, next: NextFunction) {
173
+ const end = httpDuration.startTimer();
174
+ res.on("finish", () => {
175
+ const labels = {
176
+ method: req.method,
177
+ route: req.route?.path ?? req.path,
178
+ status: String(res.statusCode),
179
+ };
180
+ end(labels);
181
+ httpTotal.inc(labels);
182
+ });
183
+ next();
184
+ }
185
+
186
+ app.get("/metrics", async (_req, res) => {
187
+ res.set("Content-Type", registry.contentType);
188
+ res.end(await registry.metrics());
189
+ });
190
+ ```
191
+
192
+ ### Health Check Endpoint
193
+
194
+ ```typescript
195
+ app.get("/health", async (_req, res) => {
196
+ const checks = {
197
+ database: await checkDatabase().catch(() => false),
198
+ redis: await checkRedis().catch(() => false),
199
+ uptime: process.uptime(),
200
+ memoryMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
201
+ };
202
+ const healthy = checks.database && checks.redis;
203
+ res.status(healthy ? 200 : 503).json({
204
+ status: healthy ? "ok" : "degraded",
205
+ checks,
206
+ });
207
+ });
208
+ ```
209
+
210
+ ## Examples
211
+
212
+ | Signal | Tool | Use Case |
213
+ |--------|------|----------|
214
+ | Structured logs | Pino + ELK/Datadog | Search and filter by any field |
215
+ | Distributed traces | OpenTelemetry + Jaeger | Follow request across services |
216
+ | Metrics | Prometheus + Grafana | Dashboards, SLO tracking, alerts |
217
+ | Correlation IDs | AsyncLocalStorage | Link logs per request |
218
+ | Health checks | /health endpoint | Load balancer, K8s probes |
219
+
220
+ ## Checklist
221
+ - [ ] All logs are structured JSON, not string concatenation
222
+ - [ ] Sensitive data redacted from logs (tokens, passwords, PII)
223
+ - [ ] Correlation ID propagated across all service calls
224
+ - [ ] Log levels used correctly (fatal/error/warn/info/debug)
225
+ - [ ] OpenTelemetry traces span critical business operations
226
+ - [ ] Prometheus metrics track duration, error rate, throughput
227
+ - [ ] Health check endpoint reports dependency status
228
+ - [ ] Alerts configured for error rate and p99 latency thresholds