@od-oneapp/observability 2026.1.1301

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 (107) hide show
  1. package/README.md +523 -0
  2. package/dist/client-next.d.mts +20 -0
  3. package/dist/client-next.d.mts.map +1 -0
  4. package/dist/client-next.mjs +64 -0
  5. package/dist/client-next.mjs.map +1 -0
  6. package/dist/client.d.mts +11 -0
  7. package/dist/client.d.mts.map +1 -0
  8. package/dist/client.mjs +47 -0
  9. package/dist/client.mjs.map +1 -0
  10. package/dist/env.d.mts +15 -0
  11. package/dist/env.d.mts.map +1 -0
  12. package/dist/env.mjs +45 -0
  13. package/dist/env.mjs.map +1 -0
  14. package/dist/factory-DkY353r8.mjs +380 -0
  15. package/dist/factory-DkY353r8.mjs.map +1 -0
  16. package/dist/hooks-useObservability.d.mts +11 -0
  17. package/dist/hooks-useObservability.d.mts.map +1 -0
  18. package/dist/hooks-useObservability.mjs +174 -0
  19. package/dist/hooks-useObservability.mjs.map +1 -0
  20. package/dist/index-CpcdzWrF.d.mts +24 -0
  21. package/dist/index-CpcdzWrF.d.mts.map +1 -0
  22. package/dist/index.d.mts +88 -0
  23. package/dist/index.d.mts.map +1 -0
  24. package/dist/index.mjs +97 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/manager-BxQqOPEg.d.mts +33 -0
  27. package/dist/manager-BxQqOPEg.d.mts.map +1 -0
  28. package/dist/plugin-Bfq-o3nr.d.mts +60 -0
  29. package/dist/plugin-Bfq-o3nr.d.mts.map +1 -0
  30. package/dist/plugin-Bt-ygG1m.d.mts +254 -0
  31. package/dist/plugin-Bt-ygG1m.d.mts.map +1 -0
  32. package/dist/plugin-CLFwRERa.mjs +593 -0
  33. package/dist/plugin-CLFwRERa.mjs.map +1 -0
  34. package/dist/plugin-CP895lBx.mjs +534 -0
  35. package/dist/plugin-CP895lBx.mjs.map +1 -0
  36. package/dist/plugin-CaQxviDs.d.mts +61 -0
  37. package/dist/plugin-CaQxviDs.d.mts.map +1 -0
  38. package/dist/plugin-lPdJirTY.mjs +234 -0
  39. package/dist/plugin-lPdJirTY.mjs.map +1 -0
  40. package/dist/plugins-betterstack-env.d.mts +29 -0
  41. package/dist/plugins-betterstack-env.d.mts.map +1 -0
  42. package/dist/plugins-betterstack-env.mjs +75 -0
  43. package/dist/plugins-betterstack-env.mjs.map +1 -0
  44. package/dist/plugins-betterstack.d.mts +4 -0
  45. package/dist/plugins-betterstack.mjs +4 -0
  46. package/dist/plugins-console.d.mts +37 -0
  47. package/dist/plugins-console.d.mts.map +1 -0
  48. package/dist/plugins-console.mjs +196 -0
  49. package/dist/plugins-console.mjs.map +1 -0
  50. package/dist/plugins-sentry-env.d.mts +37 -0
  51. package/dist/plugins-sentry-env.d.mts.map +1 -0
  52. package/dist/plugins-sentry-env.mjs +79 -0
  53. package/dist/plugins-sentry-env.mjs.map +1 -0
  54. package/dist/plugins-sentry-microfrontend-env.d.mts +49 -0
  55. package/dist/plugins-sentry-microfrontend-env.d.mts.map +1 -0
  56. package/dist/plugins-sentry-microfrontend-env.mjs +80 -0
  57. package/dist/plugins-sentry-microfrontend-env.mjs.map +1 -0
  58. package/dist/plugins-sentry-microfrontend.d.mts +2 -0
  59. package/dist/plugins-sentry-microfrontend.mjs +3 -0
  60. package/dist/plugins-sentry.d.mts +5 -0
  61. package/dist/plugins-sentry.mjs +6 -0
  62. package/dist/server-edge.d.mts +15 -0
  63. package/dist/server-edge.d.mts.map +1 -0
  64. package/dist/server-edge.mjs +53 -0
  65. package/dist/server-edge.mjs.map +1 -0
  66. package/dist/server-next.d.mts +17 -0
  67. package/dist/server-next.d.mts.map +1 -0
  68. package/dist/server-next.mjs +64 -0
  69. package/dist/server-next.mjs.map +1 -0
  70. package/dist/server.d.mts +11 -0
  71. package/dist/server.d.mts.map +1 -0
  72. package/dist/server.mjs +48 -0
  73. package/dist/server.mjs.map +1 -0
  74. package/dist/utils-CuGrTcD6.d.mts +77 -0
  75. package/dist/utils-CuGrTcD6.d.mts.map +1 -0
  76. package/env.ts +67 -0
  77. package/package.json +147 -0
  78. package/src/client-next.ts +131 -0
  79. package/src/client.ts +70 -0
  80. package/src/core/index.ts +15 -0
  81. package/src/core/manager.ts +361 -0
  82. package/src/core/plugin.ts +61 -0
  83. package/src/core/types.ts +151 -0
  84. package/src/factory/builder.ts +132 -0
  85. package/src/factory/index.ts +67 -0
  86. package/src/factory/presets.ts +78 -0
  87. package/src/hooks/useObservability.ts +206 -0
  88. package/src/plugins/betterstack/env.ts +101 -0
  89. package/src/plugins/betterstack/index.ts +15 -0
  90. package/src/plugins/betterstack/plugin.ts +373 -0
  91. package/src/plugins/console/index.ts +323 -0
  92. package/src/plugins/sentry/__tests__/plugin-tracing.test.ts +511 -0
  93. package/src/plugins/sentry/env.ts +93 -0
  94. package/src/plugins/sentry/index.ts +28 -0
  95. package/src/plugins/sentry/plugin.ts +953 -0
  96. package/src/plugins/sentry/types.ts +252 -0
  97. package/src/plugins/sentry-microfrontend/env.ts +105 -0
  98. package/src/plugins/sentry-microfrontend/index.ts +12 -0
  99. package/src/plugins/sentry-microfrontend/multiplexed-transport.ts +221 -0
  100. package/src/plugins/sentry-microfrontend/plugin.ts +500 -0
  101. package/src/plugins/sentry-microfrontend/sentry-types.ts +140 -0
  102. package/src/plugins/sentry-microfrontend/types.ts +130 -0
  103. package/src/plugins/sentry-microfrontend/utils.ts +326 -0
  104. package/src/server-edge.ts +113 -0
  105. package/src/server-next.ts +114 -0
  106. package/src/server.ts +71 -0
  107. package/src/shared.ts +148 -0
package/README.md ADDED
@@ -0,0 +1,523 @@
1
+ # @repo/observability
2
+
3
+ A comprehensive, type-safe observability package for the OneApp monorepo. Provides unified logging, error tracking,
4
+ performance monitoring, and tracing across client, server, and edge environments with support for multiple providers
5
+ (Sentry, BetterStack, Console).
6
+
7
+ ## Quick Reference
8
+
9
+ - **Can build:** NO (TypeScript library, no build step required)
10
+ - **Version:** 2025.11.1201
11
+ - **License:** MIT
12
+
13
+ ### Exports
14
+
15
+ **Core:**
16
+
17
+ - `.` - Shared utilities and types
18
+ - `./client` - Browser (non-Next.js)
19
+ - `./server` - Node.js server
20
+ - `./client/next` - Next.js client components
21
+ - `./server/next` - Next.js server components
22
+ - `./server/edge` - Edge runtime
23
+ - `./env` - Environment configuration
24
+
25
+ **Plugins:**
26
+
27
+ - `./plugins/console` - Console logging plugin
28
+ - `./plugins/sentry` - Sentry error tracking
29
+ - `./plugins/betterstack` - BetterStack logging
30
+ - `./plugins/logtape` - LogTape integration
31
+ - `./plugins/sentry-microfrontend` - Micro-frontend Sentry
32
+
33
+ **Environment Configs:** Each plugin exports `./plugins/{name}/env`
34
+
35
+ ### AI Usage Hints
36
+
37
+ ```typescript
38
+ // ✅ CORRECT: Logging (Canonical)
39
+ import { logInfo, logError } from "@repo/shared/logger";
40
+
41
+ // ✅ CORRECT: Observability initialization (Next.js Server Component)
42
+ import { observability } from "@repo/observability/server/next";
43
+
44
+ // ✅ CORRECT: Observability initialization (Next.js Client Component)
45
+ import { getObservability } from "@repo/observability/client/next";
46
+
47
+ // ✅ CORRECT: Edge Runtime (Middleware, Edge API Routes)
48
+ import { observability } from "@repo/observability/server/edge";
49
+ ```
50
+
51
+ ## Features
52
+
53
+ - 🔌 **Plugin-Based**: Extensible architecture supporting multiple providers
54
+ - 🌐 **Multi-Environment**: Client, server, Next.js, edge runtime support
55
+ - 📊 **Performance Monitoring**: Web Vitals, custom metrics, distributed tracing
56
+ - 🛡️ **Type-Safe**: Full TypeScript with strict type checking
57
+ - 🔄 **Graceful Degradation**: Continues operation if providers fail
58
+ - 🎯 **Error Tracking**: Structured error reporting with breadcrumbs
59
+ - 🚀 **Zero-Config**: Auto-detection based on environment variables
60
+ - 🔐 **Security-First**: Input validation and sanitization
61
+
62
+ ## Installation
63
+
64
+ Already included in the monorepo. Add to your workspace:
65
+
66
+ ```bash
67
+ pnpm add @repo/observability
68
+ ```
69
+
70
+ ## Quick Start
71
+
72
+ ### Next.js Client Component
73
+
74
+ ```tsx
75
+ "use client";
76
+
77
+ import { logInfo, logError } from "@repo/shared/logger";
78
+
79
+ export function UserProfile() {
80
+ const handleClick = async () => {
81
+ try {
82
+ logInfo("User profile viewed", { userId: "123" });
83
+ // Your logic here
84
+ } catch (error) {
85
+ logError(error as Error, { component: "UserProfile" });
86
+ }
87
+ };
88
+
89
+ return <button onClick={handleClick}>View Profile</button>;
90
+ }
91
+ ```
92
+
93
+ ### Next.js Server Component
94
+
95
+ ```tsx
96
+ import { getObservability } from "@repo/observability/server-next";
97
+ import { logInfo, logError } from "@repo/shared/logger";
98
+
99
+ export default async function ServerPage() {
100
+ const observability = await getObservability();
101
+ logInfo("Server page rendered", { page: "/dashboard" });
102
+
103
+ try {
104
+ const data = await fetchData();
105
+ return <div>{data}</div>;
106
+ } catch (error) {
107
+ logError(error as Error);
108
+ observability.captureException(error as Error);
109
+ throw error;
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### API Route
115
+
116
+ ```typescript
117
+ import { getObservability } from "@repo/observability/server-next";
118
+ import { logInfo, logError } from "@repo/shared/logger";
119
+ import { NextRequest, NextResponse } from "next/server";
120
+
121
+ export async function POST(request: NextRequest) {
122
+ const observability = await getObservability();
123
+
124
+ try {
125
+ const body = await request.json();
126
+
127
+ observability.setUser({ id: body.userId, email: body.email });
128
+ logInfo("API request", { endpoint: "/api/users" });
129
+
130
+ const result = await processRequest(body);
131
+ return NextResponse.json({ success: true, data: result });
132
+ } catch (error) {
133
+ logError(error as Error, { endpoint: "/api/users" });
134
+ observability.captureException(error as Error, { endpoint: "/api/users" });
135
+ return NextResponse.json({ error: "Internal error" }, { status: 500 });
136
+ }
137
+ }
138
+ ```
139
+
140
+ ## Environment Variables
141
+
142
+ ### Core Configuration
143
+
144
+ ```bash
145
+ NODE_ENV=development | production
146
+ NEXT_PUBLIC_OBSERVABILITY_DEBUG=true
147
+ NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED=true
148
+ ```
149
+
150
+ ### Sentry
151
+
152
+ ```bash
153
+ SENTRY_DSN=https://key@sentry.io/project
154
+ NEXT_PUBLIC_SENTRY_DSN=https://key@sentry.io/project # Client-side
155
+ SENTRY_ENVIRONMENT=production
156
+ SENTRY_RELEASE=v1.0.0
157
+ SENTRY_ORG=your-org
158
+ SENTRY_PROJECT=your-project
159
+ SENTRY_TRACES_SAMPLE_RATE=0.1
160
+ SENTRY_PROFILES_SAMPLE_RATE=0.1
161
+ SENTRY_REPLAYS_SESSION_SAMPLE_RATE=0.1
162
+ SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE=1.0
163
+ ```
164
+
165
+ ### BetterStack (Logtail)
166
+
167
+ ```bash
168
+ BETTER_STACK_SOURCE_TOKEN=your-token
169
+ NEXT_PUBLIC_BETTER_STACK_SOURCE_TOKEN=your-token # Client-side
170
+ BETTER_STACK_INGESTING_URL=https://in.logs.betterstack.com
171
+ BETTERSTACK_STATUS_PAGE_ID=your-page-id
172
+ LOGTAIL_SOURCE_TOKEN=your-token # Legacy name
173
+ ```
174
+
175
+ ## Usage Examples
176
+
177
+ ### Basic Logging
178
+
179
+ ```typescript
180
+ import { logDebug, logInfo, logWarn, logError } from "@repo/shared/logger";
181
+
182
+ logDebug("Processing request", { requestId: "123" });
183
+ logInfo("User logged in", { userId: "user-456" });
184
+ logWarn("Rate limit approaching", { currentRate: 95 });
185
+ logError("Failed to save data", { operation: "db.save" });
186
+ ```
187
+
188
+ ### Exception Tracking
189
+
190
+ ```typescript
191
+ try {
192
+ await riskyOperation();
193
+ } catch (error) {
194
+ observability.captureException(error, {
195
+ extra: { userId: user.id, operation: "checkout" },
196
+ tags: { environment: "production", feature: "checkout" }
197
+ });
198
+ throw error;
199
+ }
200
+ ```
201
+
202
+ ### User Context
203
+
204
+ ```typescript
205
+ // Set user context (attached to all future events)
206
+ observability.setUser({
207
+ id: "user-123",
208
+ email: "john@example.com",
209
+ username: "johndoe"
210
+ });
211
+
212
+ // Clear user context (e.g., on logout)
213
+ observability.setUser(null);
214
+ ```
215
+
216
+ ### Breadcrumbs
217
+
218
+ ```typescript
219
+ // Track user journey
220
+ observability.addBreadcrumb({
221
+ message: "User clicked checkout",
222
+ category: "user-action",
223
+ level: "info",
224
+ data: { cartTotal: 99.99 }
225
+ });
226
+
227
+ // When error occurs, breadcrumbs provide context
228
+ observability.captureException(new Error("Payment failed"));
229
+ ```
230
+
231
+ ### Performance Monitoring (Sentry)
232
+
233
+ ```typescript
234
+ import { observability, SentryPlugin } from "@repo/observability/server-next";
235
+
236
+ const sentry = observability.getPlugin<SentryPlugin>("sentry");
237
+
238
+ if (sentry) {
239
+ const transaction = sentry.startTransaction({
240
+ name: "Process Order",
241
+ op: "http.server"
242
+ });
243
+
244
+ try {
245
+ const span = sentry.startSpan({ name: "Validate Cart", op: "validation" });
246
+ await validateCart(cart);
247
+ span?.finish();
248
+
249
+ transaction?.finish();
250
+ } catch (error) {
251
+ transaction?.finish();
252
+ throw error;
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### Web Vitals (Client-Side)
258
+
259
+ ```tsx
260
+ "use client";
261
+
262
+ import { getObservability, SentryPlugin } from "@repo/observability/client-next";
263
+
264
+ export function WebVitalsReporter() {
265
+ useEffect(() => {
266
+ const reportWebVitals = async (metric: any) => {
267
+ const obs = await getObservability();
268
+ const sentry = obs.getPlugin<SentryPlugin>("sentry");
269
+
270
+ if (sentry) {
271
+ sentry.recordWebVital(metric.name, metric.value, {
272
+ rating: metric.rating,
273
+ unit: "millisecond"
274
+ });
275
+ }
276
+ };
277
+
278
+ import("web-vitals").then(({ onCLS, onFID, onFCP, onLCP, onTTFB }) => {
279
+ onCLS(reportWebVitals);
280
+ onFID(reportWebVitals);
281
+ onFCP(reportWebVitals);
282
+ onLCP(reportWebVitals);
283
+ onTTFB(reportWebVitals);
284
+ });
285
+ }, []);
286
+
287
+ return null;
288
+ }
289
+ ```
290
+
291
+ ## Provider Plugins
292
+
293
+ ### Sentry
294
+
295
+ Error tracking, performance monitoring, session replay.
296
+
297
+ ```typescript
298
+ import { createSentryPlugin } from "@repo/observability/plugins/sentry";
299
+
300
+ const sentry = createSentryPlugin({
301
+ dsn: process.env.SENTRY_DSN,
302
+ environment: process.env.NODE_ENV,
303
+ tracesSampleRate: 1.0,
304
+ replaysSessionSampleRate: 0.1
305
+ });
306
+ ```
307
+
308
+ ### BetterStack
309
+
310
+ Structured logging and log aggregation.
311
+
312
+ ```typescript
313
+ import { createBetterStackPlugin } from "@repo/observability/plugins/betterstack";
314
+
315
+ const betterstack = createBetterStackPlugin({
316
+ sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN,
317
+ batchInterval: 1000,
318
+ batchSize: 100
319
+ });
320
+ ```
321
+
322
+ ### Console
323
+
324
+ Development logging to console.
325
+
326
+ ```typescript
327
+ import { createConsolePlugin } from "@repo/observability/plugins/console";
328
+
329
+ const console = createConsolePlugin({
330
+ prefix: "[MyApp]",
331
+ enabled: process.env.NODE_ENV === "development"
332
+ });
333
+ ```
334
+
335
+ ### Sentry MicroFrontend
336
+
337
+ Specialized for micro-frontend architectures.
338
+
339
+ ```typescript
340
+ import { createSentryMicroFrontendPlugin } from "@repo/observability/plugins/sentry-microfrontend";
341
+
342
+ const sentry = createSentryMicroFrontendPlugin({
343
+ isHost: true,
344
+ backstageApp: "my-app",
345
+ backstageApps: {
346
+ "my-app": "https://app-dsn@sentry.io/123"
347
+ },
348
+ globalTags: { team: "platform", version: "1.0.0" }
349
+ });
350
+ ```
351
+
352
+ ## Advanced Usage
353
+
354
+ ### Multi-Provider Setup
355
+
356
+ ```typescript
357
+ import { ObservabilityBuilder } from "@repo/observability/factory/builder";
358
+ import { createSentryPlugin } from "@repo/observability/plugins/sentry";
359
+ import { createBetterStackPlugin } from "@repo/observability/plugins/betterstack";
360
+
361
+ const observability = ObservabilityBuilder.create()
362
+ .withPlugin(createSentryPlugin({ dsn: process.env.SENTRY_DSN }))
363
+ .withPlugin(createBetterStackPlugin({ sourceToken: process.env.LOGTAIL_TOKEN }))
364
+ .withLifecycle({
365
+ onError: (error, plugin) => console.error(`${plugin.name} error:`, error),
366
+ onInitialized: (plugin) => console.log(`${plugin.name} initialized`)
367
+ })
368
+ .build();
369
+ ```
370
+
371
+ ### Custom Plugin
372
+
373
+ ```typescript
374
+ import { ObservabilityPlugin } from "@repo/observability";
375
+
376
+ class CustomPlugin implements ObservabilityPlugin {
377
+ name = "custom";
378
+ enabled = true;
379
+
380
+ getClient() {
381
+ return undefined;
382
+ }
383
+ async initialize() {
384
+ /* Setup */
385
+ }
386
+ async shutdown() {
387
+ /* Cleanup */
388
+ }
389
+
390
+ captureException(error: Error | unknown, context?: any) {
391
+ // Your implementation
392
+ }
393
+
394
+ captureMessage(message: string, level = "info", context?: any) {
395
+ // Your implementation
396
+ }
397
+
398
+ setUser(user: any) {
399
+ /* Your implementation */
400
+ }
401
+ addBreadcrumb(breadcrumb: any) {
402
+ /* Your implementation */
403
+ }
404
+ withScope(callback: any) {
405
+ callback({});
406
+ }
407
+ }
408
+ ```
409
+
410
+ ## API Reference
411
+
412
+ ### ObservabilityManager
413
+
414
+ - `addPlugin(plugin)` - Add plugin
415
+ - `getPlugin<T>(name)` - Get plugin by name
416
+ - `initialize()` - Initialize all plugins
417
+ - `shutdown()` - Shutdown all plugins
418
+ - `captureException(error, context?)` - Capture exception
419
+ - `captureMessage(message, level?, context?)` - Capture message
420
+ - `setUser(user)` - Set user context
421
+ - `addBreadcrumb(breadcrumb)` - Add breadcrumb
422
+ - `withScope(callback)` - Scoped context
423
+ - `flush(timeout?)` - Flush pending events
424
+
425
+ ### Logging (Canonical)
426
+
427
+ Logging is now handled by the `@repo/shared/logger` package.
428
+
429
+ - `logDebug(message, context?)` - Debug logging
430
+ - `logInfo(message, context?)` - Info logging
431
+ - `logWarn(message, context?)` - Warning logging
432
+ - `logError(message, context?)` - Error logging
433
+
434
+ ### ObservabilityBuilder
435
+
436
+ - `create()` - New builder instance
437
+ - `withPlugin(plugin)` - Add single plugin
438
+ - `withPlugins(plugins)` - Add multiple plugins
439
+ - `withLifecycle(lifecycle)` - Set lifecycle hooks
440
+ - `withAutoInitialize(enabled)` - Configure auto-init
441
+ - `build()` - Build manager
442
+ - `buildWithAutoInit()` - Build and initialize
443
+
444
+ ## Testing
445
+
446
+ ```bash
447
+ pnpm test # Run tests
448
+ pnpm test:coverage # With coverage
449
+ pnpm typecheck # Type checking
450
+ pnpm lint # Lint code
451
+ ```
452
+
453
+ ## Troubleshooting
454
+
455
+ ### Plugins not initializing
456
+
457
+ ```typescript
458
+ if (observability.hasInitializationError()) {
459
+ console.error("Init failed:", observability.getInitializationError());
460
+ }
461
+ console.log("Enabled:", observability.getEnabledPluginNames());
462
+ ```
463
+
464
+ ### Events not in Sentry
465
+
466
+ Check DSN, sampling rates, and debug mode:
467
+
468
+ ```bash
469
+ SENTRY_DEBUG=true
470
+ ```
471
+
472
+ ### "Accessed server variable on client"
473
+
474
+ Use `NEXT_PUBLIC_` prefix for client-side variables:
475
+
476
+ ```bash
477
+ NEXT_PUBLIC_SENTRY_DSN=https://key@sentry.io/project
478
+ ```
479
+
480
+ ## Best Practices
481
+
482
+ 1. Use environment-specific exports
483
+ 2. Set user context after authentication
484
+ 3. Add breadcrumbs for error context
485
+ 4. Use structured context objects
486
+ 5. Sample performance data in production
487
+ 6. Flush before process termination
488
+ 7. Never log sensitive data (passwords, tokens, PII)
489
+
490
+ ## Security
491
+
492
+ - ✅ User data automatically validated and sanitized
493
+ - ✅ Field length limits prevent DoS
494
+ - ✅ Unknown fields stripped for security
495
+ - ✅ Environment variables type-checked
496
+ - ⚠️ Use `beforeSend` hooks to scrub sensitive info
497
+
498
+ ## Documentation
499
+
500
+ For comprehensive documentation, see:
501
+
502
+ - **[Observability Package Overview](../apps/docs/packages/observability/overview.mdx)**
503
+ - **Architecture**: See "Architecture" section above
504
+ - **API Reference**: See "API Reference" section above
505
+
506
+ ## License
507
+
508
+ MIT
509
+
510
+ ## Support
511
+
512
+ Open an issue in the monorepo or contact the platform team.
513
+
514
+ ## 📚 Comprehensive Documentation
515
+
516
+ For detailed documentation, see:
517
+
518
+ - **[Audit Reports](../../apps/docs/content/docs/audits/observability/)** - Comprehensive audits, fixes, and security
519
+ reviews
520
+ - **[Technical Guides](../../apps/docs/content/docs/packages/observability/)** - Implementation guides and best
521
+ practices
522
+
523
+ All comprehensive documentation has been centralized in the docs app.
@@ -0,0 +1,20 @@
1
+ import { a as Breadcrumb, c as ObservabilityConfig, d as ObservabilityServer, f as ObservabilityUser, l as ObservabilityContext, o as LogLevel, s as ObservabilityClient, u as ObservabilityScope } from "./plugin-Bfq-o3nr.mjs";
2
+ import { t as ObservabilityManager } from "./manager-BxQqOPEg.mjs";
3
+ import { n as ObservabilityBuilder, t as createObservability } from "./index-CpcdzWrF.mjs";
4
+ import { n as BetterStackPluginConfig, t as BetterStackPlugin } from "./plugin-CaQxviDs.mjs";
5
+ import { Env } from "./plugins-betterstack-env.mjs";
6
+ import { ConsolePlugin, ConsolePluginConfig } from "./plugins-console.mjs";
7
+ import { n as SentryPluginConfig, t as SentryPlugin } from "./plugin-Bt-ygG1m.mjs";
8
+ import { Env as Env$1 } from "./plugins-sentry-env.mjs";
9
+ import "./plugins-sentry.mjs";
10
+ import { c as MicroFrontendMode, i as SentryMicroFrontendPlugin, l as SentryMicroFrontendConfig, s as BackstageAppConfig } from "./utils-CuGrTcD6.mjs";
11
+ import "./plugins-sentry-microfrontend.mjs";
12
+
13
+ //#region src/client-next.d.ts
14
+ declare function createClientObservability(): Promise<ObservabilityManager>;
15
+ declare function getObservability(): Promise<ObservabilityManager>;
16
+ declare const configureLogger: () => void;
17
+ type LogContext = Record<string, any>;
18
+ //#endregion
19
+ export { type BackstageAppConfig, type Env as BetterStackEnv, BetterStackPlugin, type BetterStackPluginConfig, Breadcrumb, ConsolePlugin, type ConsolePluginConfig, LogContext, LogLevel, type MicroFrontendMode, ObservabilityBuilder, ObservabilityClient, ObservabilityConfig, ObservabilityContext, ObservabilityScope, ObservabilityServer, ObservabilityUser, type Env$1 as SentryEnv, type SentryMicroFrontendConfig, SentryMicroFrontendPlugin, SentryPlugin, type SentryPluginConfig, configureLogger, createClientObservability, createObservability, getObservability };
20
+ //# sourceMappingURL=client-next.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-next.d.mts","names":[],"sources":["../src/client-next.ts"],"mappings":";;;;;;;;;;;;;iBAoBsB,yBAAA,CAAA,GAAyB,OAAA,CAAA,oBAAA;AAAA,iBAoDzB,gBAAA,CAAA,GAAoB,OAAA,CAAQ,oBAAA;AAAA,cAqDrC,eAAA;AAAA,KAKD,UAAA,GAAa,MAAA"}
@@ -0,0 +1,64 @@
1
+ import { shouldEnableConsole } from "./index.mjs";
2
+ import { env } from "./env.mjs";
3
+ import { n as ObservabilityBuilder, t as createObservability } from "./factory-DkY353r8.mjs";
4
+ import { ConsolePlugin, createConsolePlugin } from "./plugins-console.mjs";
5
+ import { env as env$1 } from "./plugins-betterstack-env.mjs";
6
+ import { n as createBetterStackPlugin, t as BetterStackPlugin } from "./plugin-lPdJirTY.mjs";
7
+ import { env as env$2 } from "./plugins-sentry-env.mjs";
8
+ import { n as createSentryPlugin, t as SentryPlugin } from "./plugin-CP895lBx.mjs";
9
+ import { t as SentryMicroFrontendPlugin } from "./plugin-CLFwRERa.mjs";
10
+
11
+ //#region src/client-next.ts
12
+ /**
13
+ * @fileoverview Next.js client-specific observability export
14
+ * Next.js client-specific observability export
15
+ */
16
+ /**
17
+ * Create auto-configured observability for Next.js client
18
+ */
19
+ async function createClientObservability() {
20
+ const builder = ObservabilityBuilder.create();
21
+ const enableConsole = shouldEnableConsole(env.NEXT_PUBLIC_NODE_ENV, env.NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED, env.NEXT_PUBLIC_OBSERVABILITY_DEBUG);
22
+ builder.withPlugin(createConsolePlugin({
23
+ prefix: "[Next.js Client]",
24
+ enabled: enableConsole
25
+ }));
26
+ if (env$2.NEXT_PUBLIC_SENTRY_DSN) builder.withPlugin(createSentryPlugin({ dsn: env$2.NEXT_PUBLIC_SENTRY_DSN }));
27
+ const clientBetterStackToken = env$1.NEXT_PUBLIC_BETTER_STACK_SOURCE_TOKEN ?? env$1.NEXT_PUBLIC_BETTERSTACK_TOKEN ?? env$1.NEXT_PUBLIC_LOGTAIL_TOKEN;
28
+ if (clientBetterStackToken) builder.withPlugin(createBetterStackPlugin({ sourceToken: clientBetterStackToken }));
29
+ return builder.build();
30
+ }
31
+ let initializationPromise = null;
32
+ /**
33
+ * Get or create the observability instance
34
+ * Uses promise-based singleton pattern to prevent race conditions in concurrent scenarios
35
+ * @returns Promise resolving to the ObservabilityManager instance
36
+ */
37
+ async function getObservability() {
38
+ if (!initializationPromise) {
39
+ initializationPromise = (async () => {
40
+ try {
41
+ return await createClientObservability();
42
+ } catch (error) {
43
+ initializationPromise = null;
44
+ throw error;
45
+ }
46
+ })();
47
+ (async () => {
48
+ try {
49
+ const { setObservabilityPromise } = await import("./hooks-useObservability.mjs");
50
+ const promise = initializationPromise;
51
+ if (promise !== null) setObservabilityPromise(promise);
52
+ } catch {}
53
+ })();
54
+ }
55
+ return initializationPromise;
56
+ }
57
+ /**
58
+ * @deprecated Configuration now happens through the observability system
59
+ */
60
+ const configureLogger = () => {};
61
+
62
+ //#endregion
63
+ export { BetterStackPlugin, ConsolePlugin, ObservabilityBuilder, SentryMicroFrontendPlugin, SentryPlugin, configureLogger, createClientObservability, createObservability, getObservability };
64
+ //# sourceMappingURL=client-next.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-next.mjs","names":["sentryEnv","betterStackEnv"],"sources":["../src/client-next.ts"],"sourcesContent":["/**\n * @fileoverview Next.js client-specific observability export\n * Next.js client-specific observability export\n */\n\nimport { env } from '../env';\n\nimport { ObservabilityBuilder } from './factory/builder';\nimport { createBetterStackPlugin } from './plugins/betterstack';\nimport { env as betterStackEnv } from './plugins/betterstack/env';\nimport { createConsolePlugin } from './plugins/console';\nimport { createSentryPlugin } from './plugins/sentry';\nimport { env as sentryEnv } from './plugins/sentry/env';\nimport { shouldEnableConsole } from './shared';\n\nimport type { ObservabilityManager } from './core/manager';\n\n/**\n * Create auto-configured observability for Next.js client\n */\nexport async function createClientObservability() {\n const builder = ObservabilityBuilder.create();\n\n // Console logging control using shared utility\n const enableConsole = shouldEnableConsole(\n env.NEXT_PUBLIC_NODE_ENV,\n env.NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED,\n env.NEXT_PUBLIC_OBSERVABILITY_DEBUG,\n );\n\n // Always add console plugin, control via enabled flag\n builder.withPlugin(\n createConsolePlugin({\n prefix: '[Next.js Client]',\n enabled: enableConsole,\n }),\n );\n\n // Auto-activate Sentry if client DSN is provided\n if (sentryEnv.NEXT_PUBLIC_SENTRY_DSN) {\n builder.withPlugin(\n createSentryPlugin({\n dsn: sentryEnv.NEXT_PUBLIC_SENTRY_DSN,\n }),\n );\n }\n\n // Auto-activate Better Stack if client token is provided\n const clientBetterStackToken =\n betterStackEnv.NEXT_PUBLIC_BETTER_STACK_SOURCE_TOKEN ??\n betterStackEnv.NEXT_PUBLIC_BETTERSTACK_TOKEN ??\n betterStackEnv.NEXT_PUBLIC_LOGTAIL_TOKEN;\n\n if (clientBetterStackToken) {\n builder.withPlugin(\n createBetterStackPlugin({\n sourceToken: clientBetterStackToken,\n }),\n );\n }\n\n return builder.build();\n}\n\n// Lazy initialization for the observability instance using promise-based singleton\nlet initializationPromise: Promise<ObservabilityManager> | null = null;\n\n/**\n * Get or create the observability instance\n * Uses promise-based singleton pattern to prevent race conditions in concurrent scenarios\n * @returns Promise resolving to the ObservabilityManager instance\n */\nexport async function getObservability(): Promise<ObservabilityManager> {\n if (!initializationPromise) {\n initializationPromise = (async () => {\n try {\n return await createClientObservability();\n } catch (error) {\n // Reset cached promise on failure so callers can retry\n initializationPromise = null;\n throw error;\n }\n })();\n\n // Set promise for React 19 hooks (dynamic import to avoid circular dependency)\n void (async () => {\n try {\n const { setObservabilityPromise } = await import('./hooks/useObservability');\n const promise = initializationPromise;\n if (promise !== null) {\n setObservabilityPromise(promise);\n }\n } catch {\n // Hooks module not available or import failed - continue without hooks\n }\n })();\n }\n return initializationPromise;\n}\n\n// Export types and utilities\nexport * from './core/types';\nexport { createObservability } from './factory';\nexport { ObservabilityBuilder } from './factory/builder';\n\n// Re-export plugins for direct access (excluding conflicting exports)\nexport { BetterStackPlugin } from './plugins/betterstack';\nexport { ConsolePlugin } from './plugins/console';\nexport { SentryPlugin } from './plugins/sentry';\nexport { SentryMicroFrontendPlugin } from './plugins/sentry-microfrontend';\n\n// Re-export plugin-specific types with aliases to avoid conflicts\nexport type { Env as BetterStackEnv, BetterStackPluginConfig } from './plugins/betterstack';\nexport type { ConsolePluginConfig } from './plugins/console';\nexport type { Env as SentryEnv, SentryPluginConfig } from './plugins/sentry';\nexport type {\n BackstageAppConfig,\n MicroFrontendMode,\n SentryMicroFrontendConfig,\n} from './plugins/sentry-microfrontend';\n\n// Legacy function for backward compatibility (no-op)\n/**\n * @deprecated Configuration now happens through the observability system\n */\nexport const configureLogger = () => {\n // No-op: Configuration now happens through the observability system\n};\n\n// Re-export type\nexport type LogContext = Record<string, any>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,eAAsB,4BAA4B;CAChD,MAAM,UAAU,qBAAqB,QAAQ;CAG7C,MAAM,gBAAgB,oBACpB,IAAI,sBACJ,IAAI,2CACJ,IAAI,gCACL;AAGD,SAAQ,WACN,oBAAoB;EAClB,QAAQ;EACR,SAAS;EACV,CAAC,CACH;AAGD,KAAIA,MAAU,uBACZ,SAAQ,WACN,mBAAmB,EACjB,KAAKA,MAAU,wBAChB,CAAC,CACH;CAIH,MAAM,yBACJC,MAAe,yCACfA,MAAe,iCACfA,MAAe;AAEjB,KAAI,uBACF,SAAQ,WACN,wBAAwB,EACtB,aAAa,wBACd,CAAC,CACH;AAGH,QAAO,QAAQ,OAAO;;AAIxB,IAAI,wBAA8D;;;;;;AAOlE,eAAsB,mBAAkD;AACtE,KAAI,CAAC,uBAAuB;AAC1B,2BAAyB,YAAY;AACnC,OAAI;AACF,WAAO,MAAM,2BAA2B;YACjC,OAAO;AAEd,4BAAwB;AACxB,UAAM;;MAEN;AAGJ,GAAM,YAAY;AAChB,OAAI;IACF,MAAM,EAAE,4BAA4B,MAAM,OAAO;IACjD,MAAM,UAAU;AAChB,QAAI,YAAY,KACd,yBAAwB,QAAQ;WAE5B;MAGN;;AAEN,QAAO;;;;;AA4BT,MAAa,wBAAwB"}
@@ -0,0 +1,11 @@
1
+ import { a as Breadcrumb, c as ObservabilityConfig, d as ObservabilityServer, f as ObservabilityUser, l as ObservabilityContext, o as LogLevel, s as ObservabilityClient, u as ObservabilityScope } from "./plugin-Bfq-o3nr.mjs";
2
+ import { t as ObservabilityManager } from "./manager-BxQqOPEg.mjs";
3
+ import { n as ObservabilityBuilder, t as createObservability } from "./index-CpcdzWrF.mjs";
4
+
5
+ //#region src/client.d.ts
6
+ declare const observability: ObservabilityManager;
7
+ declare const configureLogger: () => void;
8
+ type LogContext = Record<string, any>;
9
+ //#endregion
10
+ export { Breadcrumb, LogContext, LogLevel, ObservabilityBuilder, ObservabilityClient, ObservabilityConfig, ObservabilityContext, ObservabilityScope, ObservabilityServer, ObservabilityUser, configureLogger, createObservability, observability };
11
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;;;cAuCa,aAAA,EAA+B,oBAAA;AAAA,cAyB/B,eAAA;AAAA,KAKD,UAAA,GAAa,MAAA"}
@@ -0,0 +1,47 @@
1
+ import { shouldEnableConsole } from "./index.mjs";
2
+ import { env } from "./env.mjs";
3
+ import { n as ObservabilityBuilder, t as createObservability } from "./factory-DkY353r8.mjs";
4
+ import { createConsolePlugin } from "./plugins-console.mjs";
5
+
6
+ //#region src/client.ts
7
+ /**
8
+ * @fileoverview Auto-configuring client export for browser environments (non-Next.js)
9
+ * Auto-configuring client export for browser environments (non-Next.js)
10
+ */
11
+ /**
12
+ * Auto-configured observability for browser environments
13
+ * Automatically sets up console logging based on environment variables
14
+ */
15
+ const builder = ObservabilityBuilder.create();
16
+ const enableConsole = shouldEnableConsole(env.NEXT_PUBLIC_NODE_ENV, env.NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED, env.NEXT_PUBLIC_OBSERVABILITY_DEBUG);
17
+ builder.withPlugin(createConsolePlugin({
18
+ prefix: "[Browser]",
19
+ enabled: enableConsole
20
+ }));
21
+ /**
22
+ * Pre-configured observability instance for browser environments
23
+ * Includes console logging with automatic environment-based configuration
24
+ */
25
+ const observability = builder.build();
26
+ /**
27
+ * Synchronous logger functions for non-Next.js browser environments.
28
+ * These are bound to a pre-built observability instance at module load time.
29
+ *
30
+ * Note: For Next.js apps, use `@od-oneapp/observability/client/next` instead,
31
+ * which provides async loggers that support lazy initialization.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { logInfo, logError } from '@od-oneapp/shared/logger';
36
+ * logInfo('User logged in', { userId: '123' });
37
+ * logError('Failed to save data', { error: err });
38
+ * ```
39
+ */
40
+ /**
41
+ * @deprecated Configuration now happens through the observability system
42
+ */
43
+ const configureLogger = () => {};
44
+
45
+ //#endregion
46
+ export { ObservabilityBuilder, configureLogger, createObservability, observability };
47
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["/**\n * @fileoverview Auto-configuring client export for browser environments (non-Next.js)\n * Auto-configuring client export for browser environments (non-Next.js)\n */\n\nimport { env } from '../env';\n\nimport { ObservabilityBuilder } from './factory/builder';\nimport { createConsolePlugin } from './plugins/console';\nimport { shouldEnableConsole } from './shared';\n\n/**\n * Auto-configured observability for browser environments\n * Automatically sets up console logging based on environment variables\n */\nconst builder = ObservabilityBuilder.create();\n\n// Console logging control using shared utility\nconst enableConsole = shouldEnableConsole(\n env.NEXT_PUBLIC_NODE_ENV,\n env.NEXT_PUBLIC_OBSERVABILITY_CONSOLE_ENABLED,\n env.NEXT_PUBLIC_OBSERVABILITY_DEBUG,\n);\n\n// Always add console plugin, control via enabled flag\nbuilder.withPlugin(\n createConsolePlugin({\n prefix: '[Browser]',\n enabled: enableConsole,\n }),\n);\n\n// Note: Sentry and Better Stack would typically be configured by the app\n// This is just a fallback for non-Next.js browser usage\n\n/**\n * Pre-configured observability instance for browser environments\n * Includes console logging with automatic environment-based configuration\n */\nexport const observability = builder.build();\n\n// Export types and utilities\nexport * from './core/types';\nexport { createObservability } from './factory';\nexport { ObservabilityBuilder } from './factory/builder';\n\n/**\n * Synchronous logger functions for non-Next.js browser environments.\n * These are bound to a pre-built observability instance at module load time.\n *\n * Note: For Next.js apps, use `@repo/observability/client/next` instead,\n * which provides async loggers that support lazy initialization.\n *\n * @example\n * ```typescript\n * import { logInfo, logError } from '@repo/shared/logger';\n * logInfo('User logged in', { userId: '123' });\n * logError('Failed to save data', { error: err });\n * ```\n */\n// Legacy function for backward compatibility (no-op)\n/**\n * @deprecated Configuration now happens through the observability system\n */\nexport const configureLogger = () => {\n // No-op: Configuration now happens through the observability system\n};\n\n// Re-export type\nexport type LogContext = Record<string, any>;\n"],"mappings":";;;;;;;;;;;;;;AAeA,MAAM,UAAU,qBAAqB,QAAQ;AAG7C,MAAM,gBAAgB,oBACpB,IAAI,sBACJ,IAAI,2CACJ,IAAI,gCACL;AAGD,QAAQ,WACN,oBAAoB;CAClB,QAAQ;CACR,SAAS;CACV,CAAC,CACH;;;;;AASD,MAAa,gBAAgB,QAAQ,OAAO;;;;;;;;;;;;;;;;;;AAyB5C,MAAa,wBAAwB"}