@modainteract/moda-interact-shared 0.2.0 → 0.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.
- package/README.md +424 -21
- package/dist/chunk-5JNEZEKV.js +374 -0
- package/dist/chunk-5JNEZEKV.js.map +1 -0
- package/dist/chunk-XH6XHKXC.js +34 -0
- package/dist/chunk-XH6XHKXC.js.map +1 -0
- package/dist/chunk-XU4XX7SD.js +27 -0
- package/dist/chunk-XU4XX7SD.js.map +1 -0
- package/dist/logging/index.js +43 -1
- package/dist/logging/index.js.map +1 -1
- package/dist/logging/node.d.ts +103 -0
- package/dist/logging/node.js +18 -0
- package/dist/logging/node.js.map +1 -0
- package/dist/observability/bullmq.d.ts +10 -0
- package/dist/observability/bullmq.js +14 -0
- package/dist/observability/bullmq.js.map +1 -0
- package/dist/observability/genai.d.ts +10 -0
- package/dist/observability/genai.js +109 -0
- package/dist/observability/genai.js.map +1 -0
- package/dist/observability/index.d.ts +6 -0
- package/dist/observability/index.js +9 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/node.d.ts +29 -0
- package/dist/observability/node.js +352 -0
- package/dist/observability/node.js.map +1 -0
- package/package.json +41 -2
package/README.md
CHANGED
|
@@ -4,8 +4,8 @@ Shared TypeScript contracts and reusable platform primitives used by multiple
|
|
|
4
4
|
Moda Interact services.
|
|
5
5
|
|
|
6
6
|
This package is a **library**, not a deployable service. It does not own
|
|
7
|
-
|
|
8
|
-
application business workflows.
|
|
7
|
+
business transports, persistence, background workers, provider SDK integration,
|
|
8
|
+
or application business workflows.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -28,10 +28,117 @@ including:
|
|
|
28
28
|
- canonical queue/job-name constants where multiple repositories must agree;
|
|
29
29
|
- deterministic correlation/job identifier helpers;
|
|
30
30
|
- small pure utilities used by more than one service;
|
|
31
|
-
- reusable structured application logging primitives
|
|
31
|
+
- reusable structured application logging primitives;
|
|
32
|
+
- the reusable base Node OpenTelemetry runtime, including tracing and metrics
|
|
33
|
+
providers, exporters, sampling, HTTP/Undici instrumentation, lifecycle, and
|
|
34
|
+
generic observability helpers.
|
|
32
35
|
|
|
33
36
|
The package deliberately keeps framework and runtime dependencies small.
|
|
34
37
|
|
|
38
|
+
## Node observability runtime
|
|
39
|
+
|
|
40
|
+
The package provides a browser-safe semantic observability entry and a
|
|
41
|
+
Node-only runtime entry:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
getActiveTraceId,
|
|
46
|
+
withObservedSpan,
|
|
47
|
+
} from "@modainteract/moda-interact-shared/observability";
|
|
48
|
+
|
|
49
|
+
import {
|
|
50
|
+
initNodeObservability,
|
|
51
|
+
} from "@modainteract/moda-interact-shared/observability/node";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Import `./observability/node` only from a process preload. It installs tracing,
|
|
55
|
+
metrics, HTTP/HTTPS and Undici/fetch instrumentation before framework or worker
|
|
56
|
+
modules load:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
node --import ./observability.mjs <framework-or-worker-entrypoint>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// observability.mjs
|
|
64
|
+
import { initNodeObservability } from
|
|
65
|
+
"@modainteract/moda-interact-shared/observability/node";
|
|
66
|
+
|
|
67
|
+
initNodeObservability({
|
|
68
|
+
serviceName: "moda-interact-messaging",
|
|
69
|
+
environment: process.env.DEPLOYMENT_ENVIRONMENT_NAME,
|
|
70
|
+
instrument: { http: true, fetch: true, prisma: false },
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Set `prisma: true` only for processes that load Prisma, and keep the preload
|
|
75
|
+
before the first Prisma application import.
|
|
76
|
+
|
|
77
|
+
The runtime uses the canonical `service.namespace`, `service.name`, and
|
|
78
|
+
`deployment.environment.name` resource attributes. It honors
|
|
79
|
+
`OTEL_TRACES_SAMPLER`, ratio arguments for ratio samplers, signal-specific or
|
|
80
|
+
generic OTLP endpoints, and bounded batch/export settings. With no trace or
|
|
81
|
+
metric endpoint those pipelines are no-ops while structured stdout logging
|
|
82
|
+
continues.
|
|
83
|
+
|
|
84
|
+
`forceFlush()` covers traces, metrics, OpenTelemetry Logs, and direct Loki.
|
|
85
|
+
Initialization, export, flush, and shutdown failures are best-effort and do not
|
|
86
|
+
become application startup or business-operation failures.
|
|
87
|
+
|
|
88
|
+
### BullMQ telemetry
|
|
89
|
+
|
|
90
|
+
Create the shared BullMQ telemetry adapter once per Queue or Worker options
|
|
91
|
+
object and pass it through BullMQ's native `telemetry` option:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { createBullMQTelemetry } from
|
|
95
|
+
"@modainteract/moda-interact-shared/observability/bullmq";
|
|
96
|
+
|
|
97
|
+
const telemetry = createBullMQTelemetry({
|
|
98
|
+
serviceName: "moda-messaging-worker",
|
|
99
|
+
enableMetrics: true,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
new Worker(queueName, processor, { connection, telemetry });
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The adapter uses the global trace and meter providers installed by the Node
|
|
106
|
+
runtime. BullMQ owns propagation metadata in its job options; applications must
|
|
107
|
+
not copy or mutate queue payloads solely to carry trace context. BullMQ metrics
|
|
108
|
+
use queue name, bounded job name, and job state dimensions, never Moda job,
|
|
109
|
+
shop, checkout, conversation, or message IDs.
|
|
110
|
+
|
|
111
|
+
### GenAI active spans
|
|
112
|
+
|
|
113
|
+
Use the GenAI helpers to model one inbound conversation turn as an independent
|
|
114
|
+
trace with active agent, tool, and automatically instrumented child spans:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import {
|
|
118
|
+
observeAgentInvocation,
|
|
119
|
+
observeAgentTool,
|
|
120
|
+
observeConversationTurn,
|
|
121
|
+
} from "@modainteract/moda-interact-shared/observability/genai";
|
|
122
|
+
|
|
123
|
+
await observeConversationTurn("whatsapp", () =>
|
|
124
|
+
observeAgentInvocation({ agentName: "commerce-agent" }, () =>
|
|
125
|
+
observeAgentTool("lookup-products", executeTool),
|
|
126
|
+
),
|
|
127
|
+
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The helpers use only the global tracer and meter providers installed by the
|
|
131
|
+
Node runtime. They create no SDK, provider, exporter, or network request, and
|
|
132
|
+
remain lightweight no-ops when providers are absent. Six module-singleton
|
|
133
|
+
instruments record turn, agent, and tool duration and operation outcomes.
|
|
134
|
+
Metric attributes are limited to `outcome=success|error`; turn metrics also use
|
|
135
|
+
the closed `channel=whatsapp|other` vocabulary. Arbitrary agent, provider,
|
|
136
|
+
model, tool, and Moda business identifiers never become metric dimensions.
|
|
137
|
+
|
|
138
|
+
Agent, provider, model, and tool names are trimmed and bounded on spans only.
|
|
139
|
+
Prompt, completion, message, and tool payload bodies are never accepted or
|
|
140
|
+
captured by default.
|
|
141
|
+
|
|
35
142
|
## What this package does not own
|
|
36
143
|
|
|
37
144
|
This package does **not** own:
|
|
@@ -42,12 +149,13 @@ This package does **not** own:
|
|
|
42
149
|
- Shopify or Meta webhook HTTP handlers;
|
|
43
150
|
- Shopify or Meta SDK integration;
|
|
44
151
|
- application recovery/business logic;
|
|
45
|
-
-
|
|
46
|
-
|
|
152
|
+
- service/domain-specific span names, business attributes, or application
|
|
153
|
+
metrics;
|
|
154
|
+
- deployment OTLP endpoint/credential wiring or observability backends;
|
|
47
155
|
- Render deployment configuration.
|
|
48
156
|
|
|
49
|
-
Those
|
|
50
|
-
runtime
|
|
157
|
+
Those service-specific semantics and deployment concerns remain in the
|
|
158
|
+
repository that owns the corresponding runtime.
|
|
51
159
|
|
|
52
160
|
---
|
|
53
161
|
|
|
@@ -302,25 +410,297 @@ traces by default.
|
|
|
302
410
|
Logging is best-effort: a logger sink or serialization failure must not alter
|
|
303
411
|
the success/failure semantics of the business operation being logged.
|
|
304
412
|
|
|
305
|
-
## Logging
|
|
413
|
+
## Logging destinations
|
|
414
|
+
|
|
415
|
+
Every call to the shared logger:
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
logger.debug(...)
|
|
419
|
+
logger.info(...)
|
|
420
|
+
logger.warn(...)
|
|
421
|
+
logger.error(...)
|
|
422
|
+
```
|
|
306
423
|
|
|
307
|
-
|
|
424
|
+
emits the same already-sanitized canonical record to up to three independent,
|
|
425
|
+
best-effort destinations:
|
|
308
426
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
427
|
+
1. canonical structured JSON to the configured sink (default: console);
|
|
428
|
+
2. the OpenTelemetry Logs API via the global `LoggerProvider`, if one has been
|
|
429
|
+
installed;
|
|
430
|
+
3. a direct Grafana Loki transport, if the Node process bootstrap has installed
|
|
431
|
+
the Loki emitter.
|
|
313
432
|
|
|
314
|
-
|
|
433
|
+
Each destination is failure-isolated: a failure in one must not suppress
|
|
434
|
+
another and must never affect application/business correctness.
|
|
435
|
+
|
|
436
|
+
The OpenTelemetry API is a no-op when no provider is installed, so stdout
|
|
437
|
+
logging continues to work in local/test environments without any backend.
|
|
438
|
+
|
|
439
|
+
The heavy Node SDK/exporter and the Winston/winston-loki transport are isolated
|
|
440
|
+
in:
|
|
441
|
+
|
|
442
|
+
```text
|
|
443
|
+
@modainteract/moda-interact-shared/logging/node
|
|
444
|
+
```
|
|
315
445
|
|
|
316
|
-
|
|
446
|
+
and must be imported and initialized only from the Node process bootstrap —
|
|
447
|
+
never through Vite/application/browser bundles.
|
|
448
|
+
|
|
449
|
+
```text
|
|
450
|
+
application module
|
|
451
|
+
|
|
|
452
|
+
v
|
|
453
|
+
@modainteract/moda-interact-shared/logging
|
|
454
|
+
|
|
|
455
|
+
+--> canonical JSON stdout
|
|
456
|
+
|
|
|
457
|
+
+--> @opentelemetry/api-logs
|
|
458
|
+
| |
|
|
459
|
+
| | global LoggerProvider
|
|
460
|
+
| v
|
|
461
|
+
| ./logging/node
|
|
462
|
+
| |
|
|
463
|
+
| +--> LoggerProvider
|
|
464
|
+
| +--> BatchLogRecordProcessor
|
|
465
|
+
| +--> OTLPLogExporter
|
|
466
|
+
| |
|
|
467
|
+
| v
|
|
468
|
+
| /v1/logs
|
|
469
|
+
|
|
|
470
|
+
+--> lightweight Loki bridge (globalThis emitter)
|
|
471
|
+
|
|
|
472
|
+
v
|
|
473
|
+
./logging/node
|
|
474
|
+
|
|
|
475
|
+
+--> Winston + winston-loki
|
|
476
|
+
|
|
|
477
|
+
v
|
|
478
|
+
Grafana Loki
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Winston and winston-loki exist **only** in the Node-only package graph. The
|
|
482
|
+
normal `./logging` entry contains no Winston, winston-loki or Node networking
|
|
483
|
+
imports.
|
|
484
|
+
|
|
485
|
+
### Node bootstrap
|
|
486
|
+
|
|
487
|
+
Process bootstrap code installs the optional destinations once:
|
|
488
|
+
|
|
489
|
+
```ts
|
|
490
|
+
import {
|
|
491
|
+
initNodeLokiLogging,
|
|
492
|
+
initNodeOpenTelemetryLogging,
|
|
493
|
+
} from "@modainteract/moda-interact-shared/logging/node";
|
|
494
|
+
|
|
495
|
+
initNodeLokiLogging({
|
|
496
|
+
serviceName: "moda-interact",
|
|
497
|
+
environment: "production",
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
initNodeOpenTelemetryLogging({
|
|
501
|
+
serviceName: "moda-interact",
|
|
502
|
+
environment: "production",
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Each destination is independently configurable, so a deployment may use:
|
|
507
|
+
|
|
508
|
+
```text
|
|
509
|
+
console only
|
|
510
|
+
|
|
511
|
+
console + Loki
|
|
512
|
+
|
|
513
|
+
console + OTel Logs
|
|
514
|
+
|
|
515
|
+
console + Loki + OTel Logs
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
Either Node destination may be omitted entirely; without an installed
|
|
519
|
+
provider/emitter the logger remains a safe stdout-only logger.
|
|
520
|
+
|
|
521
|
+
The bootstrap supports the standard OpenTelemetry environment variables:
|
|
522
|
+
|
|
523
|
+
```text
|
|
524
|
+
OTEL_SDK_DISABLED
|
|
525
|
+
|
|
526
|
+
OTEL_LOGS_EXPORTER
|
|
527
|
+
|
|
528
|
+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
|
529
|
+
OTEL_EXPORTER_OTLP_ENDPOINT
|
|
530
|
+
|
|
531
|
+
OTEL_EXPORTER_OTLP_LOGS_HEADERS
|
|
532
|
+
OTEL_EXPORTER_OTLP_HEADERS
|
|
533
|
+
|
|
534
|
+
OTEL_BLRP_MAX_QUEUE_SIZE
|
|
535
|
+
OTEL_BLRP_MAX_EXPORT_BATCH_SIZE
|
|
536
|
+
OTEL_BLRP_SCHEDULE_DELAY
|
|
537
|
+
OTEL_BLRP_EXPORT_TIMEOUT
|
|
538
|
+
|
|
539
|
+
OTEL_LOG_EXPORT_CONCURRENCY_LIMIT
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Endpoint rules:
|
|
543
|
+
|
|
544
|
+
```text
|
|
545
|
+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
|
546
|
+
exact signal endpoint; do not append /v1/logs
|
|
547
|
+
|
|
548
|
+
OTEL_EXPORTER_OTLP_ENDPOINT
|
|
549
|
+
generic endpoint; append /v1/logs
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Moda deliberately does **not** export to the OpenTelemetry default localhost
|
|
553
|
+
endpoint. Without an explicitly configured endpoint the logger remains
|
|
554
|
+
stdout-only.
|
|
555
|
+
|
|
556
|
+
### Direct Loki transport
|
|
557
|
+
|
|
558
|
+
The direct Loki transport is a lightweight bridge: the normal `./logging` entry
|
|
559
|
+
stores an emitter on `globalThis` and the Node bootstrap installs it. Records
|
|
560
|
+
still pass through the same shared redaction/sanitization used for stdout and
|
|
561
|
+
OpenTelemetry.
|
|
562
|
+
|
|
563
|
+
The Loki environment contract is:
|
|
564
|
+
|
|
565
|
+
```text
|
|
566
|
+
LOKI_ENABLED
|
|
567
|
+
|
|
568
|
+
LOKI_URL
|
|
569
|
+
|
|
570
|
+
LOKI_USERNAME
|
|
571
|
+
LOKI_PASSWORD
|
|
572
|
+
|
|
573
|
+
LOKI_BATCHING
|
|
574
|
+
LOKI_BATCH_INTERVAL_SECONDS
|
|
575
|
+
LOKI_TIMEOUT_MS
|
|
576
|
+
LOKI_CLEAR_ON_ERROR
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Rules:
|
|
580
|
+
|
|
581
|
+
```text
|
|
582
|
+
no LOKI_URL
|
|
583
|
+
-> direct Loki disabled
|
|
584
|
+
|
|
585
|
+
LOKI_ENABLED=false
|
|
586
|
+
-> direct Loki disabled
|
|
587
|
+
|
|
588
|
+
LOKI_URL present
|
|
589
|
+
-> direct Loki enabled by default
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Credentials are Node-bootstrap configuration only. Never log `LOKI_URL`
|
|
593
|
+
credentials, `LOKI_USERNAME`, `LOKI_PASSWORD`, Basic Auth values or connection
|
|
594
|
+
headers.
|
|
595
|
+
|
|
596
|
+
Default transport behavior:
|
|
597
|
+
|
|
598
|
+
```text
|
|
599
|
+
batching=true
|
|
600
|
+
bounded timeout (LOKI_TIMEOUT_MS)
|
|
601
|
+
clearOnError=true
|
|
602
|
+
replaceTimestamp=true
|
|
603
|
+
gracefulShutdown=false
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
The owning process bootstrap is responsible for explicit flush/shutdown via the
|
|
607
|
+
returned runtime (`forceFlush`/`shutdown`). If Loki is unavailable, log records
|
|
608
|
+
may be dropped but application processing must continue. Connection errors are
|
|
609
|
+
not recursively written back through the shared logger.
|
|
610
|
+
|
|
611
|
+
### Loki labels and cardinality
|
|
612
|
+
|
|
613
|
+
Moda explicitly configures exactly three canonical low-cardinality labels:
|
|
614
|
+
|
|
615
|
+
```text
|
|
616
|
+
service_namespace
|
|
617
|
+
service_name
|
|
618
|
+
environment
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
`winston-loki@6.1.7` additionally adds its own low-cardinality `level` label
|
|
622
|
+
to every pushed stream, so a stream carries the three Moda labels plus
|
|
623
|
+
`level`. This is transport-library behaviour and does not change Moda's label
|
|
624
|
+
configuration.
|
|
625
|
+
|
|
626
|
+
Dynamic/high-cardinality identifiers must **not** be promoted to Loki stream
|
|
627
|
+
labels. The implementation explicitly retains
|
|
628
|
+
`useWinstonMetaAsLabels: false`, so winston metadata is never promoted to
|
|
629
|
+
labels. In particular, do not label by:
|
|
630
|
+
|
|
631
|
+
```text
|
|
632
|
+
traceId
|
|
633
|
+
spanId
|
|
634
|
+
requestId
|
|
635
|
+
jobId
|
|
636
|
+
deliveryId
|
|
637
|
+
eventId
|
|
638
|
+
recoveryId
|
|
639
|
+
checkoutToken
|
|
640
|
+
cartToken
|
|
641
|
+
shop
|
|
642
|
+
shopDomain
|
|
643
|
+
customerId
|
|
644
|
+
phone
|
|
645
|
+
email
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Safe high-cardinality operational identifiers may remain in the sanitized JSON
|
|
649
|
+
log body where justified, but they must never become indexed stream labels.
|
|
650
|
+
|
|
651
|
+
### Duplicate-delivery warning
|
|
652
|
+
|
|
653
|
+
Do not route the OpenTelemetry Logs destination back into the same Loki
|
|
654
|
+
instance while direct Loki is also enabled, unless duplicate storage is
|
|
655
|
+
intentional:
|
|
656
|
+
|
|
657
|
+
```text
|
|
658
|
+
direct Loki ON
|
|
659
|
+
+
|
|
660
|
+
OTel Logs ultimately routed to same Loki
|
|
661
|
+
=
|
|
662
|
+
duplicate log storage
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
The library does not guess backend topology; deployment configuration owns this
|
|
666
|
+
choice.
|
|
667
|
+
|
|
668
|
+
### Log-signal data safety and correlation
|
|
669
|
+
|
|
670
|
+
- The OpenTelemetry log body is `JSON.stringify` of the same canonical
|
|
671
|
+
sanitized `LogRecord` written to stdout, so the same redaction boundary
|
|
672
|
+
applies to both destinations.
|
|
673
|
+
- Queryable OTel attributes are limited to:
|
|
674
|
+
|
|
675
|
+
```text
|
|
676
|
+
event.name
|
|
677
|
+
log.level
|
|
678
|
+
service.namespace
|
|
679
|
+
service.name
|
|
680
|
+
deployment.environment.name
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
- The shared logger never manufactures trace IDs. If an active
|
|
684
|
+
trace/span context exists, the OpenTelemetry Logs SDK associates the emitted
|
|
685
|
+
record with that active context automatically.
|
|
686
|
+
- stdout and OpenTelemetry emission are isolated and best-effort: a failure in
|
|
687
|
+
either must not change application/business correctness.
|
|
688
|
+
|
|
689
|
+
### Tracing/metrics ownership
|
|
690
|
+
|
|
691
|
+
The shared logger does **not** create spans, counters or histograms.
|
|
692
|
+
|
|
693
|
+
The shared observability runtime owns the generic Node SDK, tracing and metrics
|
|
694
|
+
provider mechanics, exporters, sampling, HTTP/Undici instrumentation, generic
|
|
695
|
+
helpers, and lifecycle. Service repositories own their span names, business
|
|
696
|
+
attributes, application-specific metrics, and domain semantics, for example:
|
|
317
697
|
|
|
318
698
|
```text
|
|
319
699
|
Shopify operation
|
|
320
700
|
|
|
|
321
|
-
+--> shared structured logger
|
|
701
|
+
+--> shared structured logger (stdout + OTel Logs)
|
|
322
702
|
|
|
|
323
|
-
+--> Shopify-specific OpenTelemetry
|
|
703
|
+
+--> Shopify-specific OpenTelemetry (spans/metrics)
|
|
324
704
|
```
|
|
325
705
|
|
|
326
706
|
This separation is intentional. Fields that are useful in diagnostic logs can
|
|
@@ -344,6 +724,25 @@ The public package exposes independent entry points.
|
|
|
344
724
|
|
|
345
725
|
@modainteract/moda-interact-shared/logging
|
|
346
726
|
reusable structured logging API
|
|
727
|
+
(stdout + OTel Logs + direct Loki fan-out)
|
|
728
|
+
|
|
729
|
+
@modainteract/moda-interact-shared/logging/node
|
|
730
|
+
Node-only logging bootstrap
|
|
731
|
+
(OpenTelemetry LoggerProvider, batching, OTLP HTTP exporter;
|
|
732
|
+
Winston + winston-loki direct transport)
|
|
733
|
+
|
|
734
|
+
@modainteract/moda-interact-shared/observability
|
|
735
|
+
browser-safe generic observability helpers
|
|
736
|
+
|
|
737
|
+
@modainteract/moda-interact-shared/observability/node
|
|
738
|
+
reusable Node OpenTelemetry SDK, tracing/metrics providers, exporters,
|
|
739
|
+
sampling, HTTP/Undici instrumentation, and lifecycle
|
|
740
|
+
|
|
741
|
+
@modainteract/moda-interact-shared/observability/bullmq
|
|
742
|
+
Node-only BullMQ native telemetry adapter
|
|
743
|
+
|
|
744
|
+
@modainteract/moda-interact-shared/observability/genai
|
|
745
|
+
Node/runtime GenAI conversation-turn, agent, and tool active-span helpers
|
|
347
746
|
```
|
|
348
747
|
|
|
349
748
|
Consumers should prefer the narrowest appropriate subpath.
|
|
@@ -360,27 +759,31 @@ Examples of repository ownership:
|
|
|
360
759
|
- normalizes/validates Shopify events;
|
|
361
760
|
- publishes the appropriate queue jobs;
|
|
362
761
|
- uses the shared structured logger for generic log mechanics;
|
|
363
|
-
-
|
|
762
|
+
- uses the shared observability runtime for generic OpenTelemetry mechanics;
|
|
763
|
+
- owns Shopify-specific observability semantics and application metrics.
|
|
364
764
|
|
|
365
765
|
**moda-interact-background**
|
|
366
766
|
|
|
367
767
|
- parses shared cross-service contracts before acting;
|
|
368
768
|
- runs BullMQ workers and recovery workflows;
|
|
369
769
|
- uses the shared logger for generic structured logging;
|
|
370
|
-
-
|
|
770
|
+
- uses the shared observability runtime for generic OpenTelemetry mechanics;
|
|
771
|
+
- owns worker/recovery observability semantics and application metrics.
|
|
371
772
|
|
|
372
773
|
**moda-interact-messaging**
|
|
373
774
|
|
|
374
775
|
- owns Meta/WhatsApp ingress;
|
|
375
776
|
- uses the shared logger for generic structured logging;
|
|
376
|
-
-
|
|
777
|
+
- uses the shared observability runtime for generic OpenTelemetry mechanics;
|
|
778
|
+
- owns Meta/WhatsApp-specific observability semantics and application metrics.
|
|
377
779
|
|
|
378
780
|
**moda-interact-admin**
|
|
379
781
|
|
|
380
782
|
- owns the internal admin application;
|
|
381
783
|
- may use the same shared logger where server-side operational logging is
|
|
382
784
|
required;
|
|
383
|
-
-
|
|
785
|
+
- uses the shared observability runtime for generic OpenTelemetry mechanics;
|
|
786
|
+
- owns admin-specific observability semantics and application metrics.
|
|
384
787
|
|
|
385
788
|
**moda-interact-database**
|
|
386
789
|
|