@smthrs/observability 0.35.0 → 1.0.0-rc.4
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/CHANGELOG.md +56 -0
- package/LICENSE +1 -1
- package/README.md +84 -0
- package/dist/cjs/BrowserOtel.d.ts +37 -0
- package/dist/cjs/BrowserOtel.d.ts.map +1 -0
- package/dist/cjs/BrowserOtel.js +47 -0
- package/dist/cjs/BrowserOtel.js.map +7 -0
- package/dist/cjs/Endpoint.d.ts +70 -0
- package/dist/cjs/Endpoint.d.ts.map +1 -0
- package/dist/cjs/Endpoint.js +85 -0
- package/dist/cjs/Endpoint.js.map +7 -0
- package/dist/cjs/JournalLogger.d.ts +232 -0
- package/dist/cjs/JournalLogger.d.ts.map +1 -0
- package/dist/cjs/JournalLogger.js +388 -0
- package/dist/cjs/JournalLogger.js.map +7 -0
- package/dist/cjs/Logger.d.ts +55 -0
- package/dist/cjs/Logger.d.ts.map +1 -0
- package/dist/cjs/Logger.js +72 -0
- package/dist/cjs/Logger.js.map +7 -0
- package/dist/cjs/Metric.d.ts +67 -0
- package/dist/cjs/Metric.d.ts.map +1 -0
- package/dist/cjs/Metric.js +68 -0
- package/dist/cjs/Metric.js.map +7 -0
- package/dist/cjs/NodeOtel.d.ts +42 -0
- package/dist/cjs/NodeOtel.d.ts.map +1 -0
- package/dist/cjs/NodeOtel.js +78 -0
- package/dist/cjs/NodeOtel.js.map +7 -0
- package/dist/cjs/Otel.d.ts +62 -0
- package/dist/cjs/Otel.d.ts.map +1 -0
- package/dist/cjs/Otel.js +75 -0
- package/dist/cjs/Otel.js.map +7 -0
- package/dist/cjs/Otlp.d.ts +200 -0
- package/dist/cjs/Otlp.d.ts.map +1 -0
- package/dist/cjs/Otlp.js +235 -0
- package/dist/cjs/Otlp.js.map +7 -0
- package/dist/cjs/Resource.d.ts +162 -0
- package/dist/cjs/Resource.d.ts.map +1 -0
- package/dist/cjs/Resource.js +186 -0
- package/dist/cjs/Resource.js.map +7 -0
- package/dist/cjs/index.d.ts +61 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +47 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/schemaIssuePath.d.ts +31 -0
- package/dist/cjs/internal/schemaIssuePath.d.ts.map +1 -0
- package/dist/cjs/internal/schemaIssuePath.js +49 -0
- package/dist/cjs/internal/schemaIssuePath.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/BrowserOtel.d.ts +37 -0
- package/dist/esm/BrowserOtel.d.ts.map +1 -0
- package/dist/esm/BrowserOtel.js +24 -0
- package/dist/esm/BrowserOtel.js.map +1 -0
- package/dist/esm/Endpoint.d.ts +70 -0
- package/dist/esm/Endpoint.d.ts.map +1 -0
- package/dist/esm/Endpoint.js +110 -0
- package/dist/esm/Endpoint.js.map +1 -0
- package/dist/esm/JournalLogger.d.ts +232 -0
- package/dist/esm/JournalLogger.d.ts.map +1 -0
- package/dist/esm/JournalLogger.js +482 -0
- package/dist/esm/JournalLogger.js.map +1 -0
- package/dist/esm/Logger.d.ts +55 -0
- package/dist/esm/Logger.d.ts.map +1 -0
- package/dist/esm/Logger.js +60 -0
- package/dist/esm/Logger.js.map +1 -0
- package/dist/esm/Metric.d.ts +67 -0
- package/dist/esm/Metric.d.ts.map +1 -0
- package/dist/esm/Metric.js +80 -0
- package/dist/esm/Metric.js.map +1 -0
- package/dist/esm/NodeOtel.d.ts +42 -0
- package/dist/esm/NodeOtel.d.ts.map +1 -0
- package/dist/esm/NodeOtel.js +56 -0
- package/dist/esm/NodeOtel.js.map +1 -0
- package/dist/esm/Otel.d.ts +62 -0
- package/dist/esm/Otel.d.ts.map +1 -0
- package/dist/esm/Otel.js +51 -0
- package/dist/esm/Otel.js.map +1 -0
- package/dist/esm/Otlp.d.ts +200 -0
- package/dist/esm/Otlp.d.ts.map +1 -0
- package/dist/esm/Otlp.js +350 -0
- package/dist/esm/Otlp.js.map +1 -0
- package/dist/esm/Resource.d.ts +162 -0
- package/dist/esm/Resource.d.ts.map +1 -0
- package/dist/esm/Resource.js +237 -0
- package/dist/esm/Resource.js.map +1 -0
- package/dist/esm/index.d.ts +61 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +61 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/schemaIssuePath.d.ts +31 -0
- package/dist/esm/internal/schemaIssuePath.d.ts.map +1 -0
- package/dist/esm/internal/schemaIssuePath.js +59 -0
- package/dist/esm/internal/schemaIssuePath.js.map +1 -0
- package/docs/README.md +162 -0
- package/docs/api.md +768 -0
- package/docs/concepts/instrumentation-and-export.md +68 -0
- package/docs/concepts/layer-map.md +72 -0
- package/docs/concepts/validated-acquisition.md +105 -0
- package/docs/guides/export-to-a-collector.md +167 -0
- package/docs/guides/forward-logs-to-the-journal.md +226 -0
- package/docs/guides/install-a-logger.md +111 -0
- package/docs/guides/read-runtime-metrics.md +83 -0
- package/docs/guides/testing.md +134 -0
- package/docs/guides/wire-an-opentelemetry-sdk.md +220 -0
- package/docs/installation.md +98 -0
- package/docs/quickstart.md +145 -0
- package/docs/troubleshooting.md +168 -0
- package/package.json +221 -32
- package/src/BrowserOtel.ts +51 -0
- package/src/Endpoint.ts +131 -0
- package/src/JournalLogger.ts +596 -0
- package/src/Logger.ts +106 -0
- package/src/Metric.ts +88 -0
- package/src/NodeOtel.ts +90 -0
- package/src/Otel.ts +117 -0
- package/src/Otlp.ts +477 -0
- package/src/Resource.ts +324 -0
- package/src/index.ts +67 -0
- package/src/internal/schemaIssuePath.ts +65 -0
- package/docker-compose.otel.yml +0 -104
- package/grafana/dashboards/smithers-dashboard.json +0 -453
- package/grafana/provisioning/dashboards/dashboards.yml +0 -12
- package/grafana/provisioning/datasources/datasources.yml +0 -49
- package/loki/loki-config.yaml +0 -35
- package/otel-collector-config.yml +0 -38
- package/prometheus/prometheus.yml +0 -8
- package/src/MetricName.ts +0 -1
- package/src/MetricsServiceLive.js +0 -9
- package/src/README.md +0 -28
- package/src/ResolvedSmithersObservabilityOptions.ts +0 -12
- package/src/SmithersEvent.ts +0 -843
- package/src/SmithersLogFormat.ts +0 -1
- package/src/SmithersMetricDefinition.ts +0 -15
- package/src/SmithersMetricType.ts +0 -1
- package/src/SmithersMetricUnit.ts +0 -1
- package/src/SmithersObservability.js +0 -15
- package/src/SmithersObservabilityOptions.ts +0 -12
- package/src/SmithersObservabilityService.ts +0 -13
- package/src/_coreCorrelation/CorrelationContext.ts +0 -10
- package/src/_coreCorrelation/CorrelationContextLive.js +0 -11
- package/src/_coreCorrelation/CorrelationContextService.js +0 -15
- package/src/_coreCorrelation/CorrelationContextServiceShape.ts +0 -12
- package/src/_coreCorrelation/CorrelationPatch.ts +0 -3
- package/src/_coreCorrelation/README.md +0 -20
- package/src/_coreCorrelation/_correlationStorage.js +0 -4
- package/src/_coreCorrelation/correlationContextFiberRef.js +0 -5
- package/src/_coreCorrelation/correlationContextToLogAnnotations.js +0 -18
- package/src/_coreCorrelation/getCurrentCorrelationContext.js +0 -9
- package/src/_coreCorrelation/getCurrentCorrelationContextEffect.js +0 -11
- package/src/_coreCorrelation/index.js +0 -14
- package/src/_coreCorrelation/mergeCorrelationContext.js +0 -51
- package/src/_coreCorrelation/runWithCorrelationContext.js +0 -14
- package/src/_coreCorrelation/updateCurrentCorrelationContext.js +0 -17
- package/src/_coreCorrelation/withCorrelationContext.js +0 -38
- package/src/_coreCorrelation/withCurrentCorrelationContext.js +0 -11
- package/src/_coreMetrics.js +0 -14
- package/src/_coreMetricsShape.ts +0 -44
- package/src/_corePrometheus.js +0 -91
- package/src/_corePrometheusShape.ts +0 -11
- package/src/_coreTracing.js +0 -132
- package/src/_coreTracingShape.ts +0 -17
- package/src/_otelLogBuilders.js +0 -102
- package/src/_sessionFileResolvers.js +0 -164
- package/src/_smithersSpanAttributeAliases.js +0 -19
- package/src/_smithersTraceSpanStorage.js +0 -3
- package/src/_traceEventNormalizers.js +0 -499
- package/src/_traceRedaction.js +0 -162
- package/src/agentSessionEventToOtelLogRecord.js +0 -55
- package/src/agentTrace.ts +0 -144
- package/src/agentTraceCapabilities.js +0 -151
- package/src/annotateSmithersTrace.js +0 -11
- package/src/canonicalTraceEventToOtelLogRecord.js +0 -55
- package/src/correlation.js +0 -56
- package/src/createSmithersObservabilityLayer.js +0 -59
- package/src/createSmithersOtelLayer.js +0 -23
- package/src/createSmithersRuntimeLayer.js +0 -2
- package/src/detectAgentFamily.js +0 -26
- package/src/detectCaptureMode.js +0 -29
- package/src/emitOtelLogRecord.js +0 -19
- package/src/getCurrentSmithersTraceAnnotations.js +0 -14
- package/src/getCurrentSmithersTraceSpan.js +0 -7
- package/src/index.d.ts +0 -1392
- package/src/index.js +0 -137
- package/src/kindPhase.js +0 -17
- package/src/logging.js +0 -264
- package/src/makeSmithersSpanAttributes.js +0 -20
- package/src/metrics/README.md +0 -22
- package/src/metrics/SmithersMetricDefinition.ts +0 -17
- package/src/metrics/SmithersMetricType.ts +0 -1
- package/src/metrics/SmithersMetricUnit.ts +0 -1
- package/src/metrics/_asyncExternalWaitCounts.js +0 -4
- package/src/metrics/_buckets.js +0 -37
- package/src/metrics/_incrementGauge.js +0 -11
- package/src/metrics/_processStartMs.js +0 -1
- package/src/metrics/activeNodes.js +0 -2
- package/src/metrics/activeRuns.js +0 -2
- package/src/metrics/agentActionsTotal.js +0 -2
- package/src/metrics/agentDurationMs.js +0 -3
- package/src/metrics/agentErrorsTotal.js +0 -2
- package/src/metrics/agentEventsTotal.js +0 -2
- package/src/metrics/agentInvocationsTotal.js +0 -2
- package/src/metrics/agentRetriesTotal.js +0 -2
- package/src/metrics/agentSessionsTotal.js +0 -2
- package/src/metrics/agentTokensTotal.js +0 -2
- package/src/metrics/alertDeliveriesAttempted.js +0 -2
- package/src/metrics/alertDeliveriesSuppressed.js +0 -2
- package/src/metrics/alertsAcknowledgedTotal.js +0 -2
- package/src/metrics/alertsActive.js +0 -2
- package/src/metrics/alertsEscalatedTotal.js +0 -2
- package/src/metrics/alertsFiredTotal.js +0 -2
- package/src/metrics/alertsReopenedTotal.js +0 -2
- package/src/metrics/alertsResolvedTotal.js +0 -2
- package/src/metrics/alertsSilencedTotal.js +0 -2
- package/src/metrics/approvalPending.js +0 -2
- package/src/metrics/approvalWaitDuration.js +0 -5
- package/src/metrics/approvalsDenied.js +0 -2
- package/src/metrics/approvalsGranted.js +0 -2
- package/src/metrics/approvalsRequested.js +0 -2
- package/src/metrics/attemptDuration.js +0 -3
- package/src/metrics/attentionBacklog.js +0 -2
- package/src/metrics/cacheHits.js +0 -2
- package/src/metrics/cacheMisses.js +0 -2
- package/src/metrics/dbQueryDuration.js +0 -3
- package/src/metrics/dbRetries.js +0 -2
- package/src/metrics/dbTransactionDuration.js +0 -3
- package/src/metrics/dbTransactionRetries.js +0 -2
- package/src/metrics/dbTransactionRollbacks.js +0 -2
- package/src/metrics/devtoolsActiveSubscribers.js +0 -2
- package/src/metrics/devtoolsBackpressureDisconnectTotal.js +0 -2
- package/src/metrics/devtoolsDeltaBuildMs.js +0 -3
- package/src/metrics/devtoolsEventBytes.js +0 -3
- package/src/metrics/devtoolsEventTotal.js +0 -2
- package/src/metrics/devtoolsSnapshotBuildMs.js +0 -5
- package/src/metrics/devtoolsSubscribeTotal.js +0 -2
- package/src/metrics/errorsTotal.js +0 -2
- package/src/metrics/eventsEmittedTotal.js +0 -2
- package/src/metrics/externalWaitAsyncPending.js +0 -2
- package/src/metrics/gatewayApprovalDecisionsTotal.js +0 -2
- package/src/metrics/gatewayAuthEventsTotal.js +0 -2
- package/src/metrics/gatewayConnectionsActive.js +0 -2
- package/src/metrics/gatewayConnectionsClosedTotal.js +0 -2
- package/src/metrics/gatewayConnectionsTotal.js +0 -2
- package/src/metrics/gatewayCronTriggersTotal.js +0 -2
- package/src/metrics/gatewayErrorsTotal.js +0 -2
- package/src/metrics/gatewayHeartbeatTicksTotal.js +0 -2
- package/src/metrics/gatewayMessagesReceivedTotal.js +0 -2
- package/src/metrics/gatewayMessagesSentTotal.js +0 -2
- package/src/metrics/gatewayRpcCallsTotal.js +0 -2
- package/src/metrics/gatewayRpcDuration.js +0 -3
- package/src/metrics/gatewayRunEventBackpressureDisconnectTotal.js +0 -4
- package/src/metrics/gatewayRunsCompletedTotal.js +0 -2
- package/src/metrics/gatewayRunsStartedTotal.js +0 -2
- package/src/metrics/gatewaySignalsTotal.js +0 -2
- package/src/metrics/gatewayWebhooksReceivedTotal.js +0 -2
- package/src/metrics/gatewayWebhooksRejectedTotal.js +0 -2
- package/src/metrics/gatewayWebhooksVerifiedTotal.js +0 -2
- package/src/metrics/heartbeatDataSizeBytes.js +0 -5
- package/src/metrics/heartbeatIntervalMs.js +0 -3
- package/src/metrics/hotReloadDuration.js +0 -3
- package/src/metrics/hotReloadFailures.js +0 -2
- package/src/metrics/hotReloads.js +0 -2
- package/src/metrics/httpRequestDuration.js +0 -3
- package/src/metrics/httpRequests.js +0 -2
- package/src/metrics/index.d.ts +0 -1222
- package/src/metrics/index.js +0 -168
- package/src/metrics/memoryFactReads.js +0 -3
- package/src/metrics/memoryFactWrites.js +0 -3
- package/src/metrics/memoryMessageSaves.js +0 -3
- package/src/metrics/memoryRecallDuration.js +0 -11
- package/src/metrics/memoryRecallQueries.js +0 -3
- package/src/metrics/metricsServiceAdapter.js +0 -181
- package/src/metrics/nodeDuration.js +0 -3
- package/src/metrics/nodeRetriesTotal.js +0 -2
- package/src/metrics/nodesFailed.js +0 -2
- package/src/metrics/nodesFinished.js +0 -2
- package/src/metrics/nodesStarted.js +0 -2
- package/src/metrics/openApiToolCallErrorsTotal.js +0 -3
- package/src/metrics/openApiToolCallsTotal.js +0 -3
- package/src/metrics/openApiToolDuration.js +0 -9
- package/src/metrics/processHeapUsedBytes.js +0 -2
- package/src/metrics/processMemoryRssBytes.js +0 -2
- package/src/metrics/processUptimeSeconds.js +0 -2
- package/src/metrics/promptSizeBytes.js +0 -3
- package/src/metrics/replaysStarted.js +0 -3
- package/src/metrics/responseSizeBytes.js +0 -3
- package/src/metrics/rewindDurationMs.js +0 -3
- package/src/metrics/rewindFramesDeleted.js +0 -3
- package/src/metrics/rewindRollbackTotal.js +0 -2
- package/src/metrics/rewindSandboxesReverted.js +0 -3
- package/src/metrics/rewindTotal.js +0 -2
- package/src/metrics/runDuration.js +0 -3
- package/src/metrics/runForksCreated.js +0 -3
- package/src/metrics/runsAncestryDepth.js +0 -3
- package/src/metrics/runsCancelledTotal.js +0 -2
- package/src/metrics/runsCarriedStateBytes.js +0 -5
- package/src/metrics/runsContinuedTotal.js +0 -2
- package/src/metrics/runsFailedTotal.js +0 -2
- package/src/metrics/runsFinishedTotal.js +0 -2
- package/src/metrics/runsResumedTotal.js +0 -2
- package/src/metrics/runsTotal.js +0 -2
- package/src/metrics/sandboxActive.js +0 -2
- package/src/metrics/sandboxBundleSizeBytes.js +0 -5
- package/src/metrics/sandboxCompletedTotal.js +0 -2
- package/src/metrics/sandboxCreatedTotal.js +0 -2
- package/src/metrics/sandboxDurationMs.js +0 -3
- package/src/metrics/sandboxPatchCount.js +0 -3
- package/src/metrics/sandboxTransportDurationMs.js +0 -5
- package/src/metrics/schedulerConcurrencyUtilization.js +0 -2
- package/src/metrics/schedulerQueueDepth.js +0 -2
- package/src/metrics/schedulerWaitDuration.js +0 -5
- package/src/metrics/scorerDuration.js +0 -9
- package/src/metrics/scorerEventsFailed.js +0 -2
- package/src/metrics/scorerEventsFinished.js +0 -2
- package/src/metrics/scorerEventsStarted.js +0 -2
- package/src/metrics/scorersFailed.js +0 -3
- package/src/metrics/scorersFinished.js +0 -3
- package/src/metrics/scorersStarted.js +0 -3
- package/src/metrics/smithersMetricCatalog.js +0 -893
- package/src/metrics/smithersMetricCatalogByKey.js +0 -2
- package/src/metrics/smithersMetricCatalogByName.js +0 -2
- package/src/metrics/smithersMetricCatalogByPrometheusName.js +0 -4
- package/src/metrics/snapshotDuration.js +0 -9
- package/src/metrics/snapshotsCaptured.js +0 -3
- package/src/metrics/supervisorPollDuration.js +0 -5
- package/src/metrics/supervisorPollsTotal.js +0 -2
- package/src/metrics/supervisorResumeLag.js +0 -5
- package/src/metrics/supervisorResumedTotal.js +0 -2
- package/src/metrics/supervisorSkippedTotal.js +0 -2
- package/src/metrics/supervisorStaleDetected.js +0 -2
- package/src/metrics/taskHeartbeatTimeoutTotal.js +0 -2
- package/src/metrics/taskHeartbeatsTotal.js +0 -2
- package/src/metrics/timerDelayDuration.js +0 -3
- package/src/metrics/timersCancelled.js +0 -2
- package/src/metrics/timersCreated.js +0 -2
- package/src/metrics/timersFired.js +0 -2
- package/src/metrics/timersPending.js +0 -2
- package/src/metrics/toPrometheusMetricName.js +0 -8
- package/src/metrics/tokensCacheReadTotal.js +0 -2
- package/src/metrics/tokensCacheWriteTotal.js +0 -2
- package/src/metrics/tokensContextWindowBucketTotal.js +0 -2
- package/src/metrics/tokensContextWindowPerCall.js +0 -5
- package/src/metrics/tokensInputPerCall.js +0 -3
- package/src/metrics/tokensInputTotal.js +0 -2
- package/src/metrics/tokensOutputPerCall.js +0 -3
- package/src/metrics/tokensOutputTotal.js +0 -2
- package/src/metrics/tokensReasoningTotal.js +0 -2
- package/src/metrics/toolCallErrorsTotal.js +0 -2
- package/src/metrics/toolCallsTotal.js +0 -2
- package/src/metrics/toolDuration.js +0 -3
- package/src/metrics/toolOutputTruncatedTotal.js +0 -2
- package/src/metrics/trackEvent.js +0 -608
- package/src/metrics/updateAsyncExternalWaitPending.js +0 -18
- package/src/metrics/updateProcessMetrics.js +0 -20
- package/src/metrics/vcsDuration.js +0 -3
- package/src/normalizeStructuredEvent.js +0 -15
- package/src/prometheusContentType.js +0 -1
- package/src/renderPrometheusMetrics.js +0 -212
- package/src/resolveAgentTraceCapabilities.js +0 -59
- package/src/resolveSmithersObservabilityOptions.js +0 -109
- package/src/smithersMetrics.js +0 -2
- package/src/smithersSpanNames.js +0 -6
- package/src/unsupportedKindsForCapabilities.js +0 -32
- package/src/withSmithersSpan.js +0 -17
- package/tempo/tempo.yml +0 -17
package/docs/api.md
ADDED
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "API reference"
|
|
3
|
+
description: "Every public export of @smthrs/observability: the Otlp exporter layers, endpoint and resource validation, the logger layers, the journal forwarder and its durable schema, the runtime metric handles, and the three OpenTelemetry SDK bridges."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`@smthrs/observability` exports seven modules from its root entry point, and
|
|
7
|
+
each is also importable from `@smthrs/observability/<Module>`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Endpoint, JournalLogger, Logger, Metric, Otel, Otlp, Resource } from "@smthrs/observability"
|
|
11
|
+
// or
|
|
12
|
+
import * as Otlp from "@smthrs/observability/Otlp"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Two more modules are subpath-only, because each binds a host-specific
|
|
16
|
+
OpenTelemetry SDK. `@smthrs/observability/package.json` is exported.
|
|
17
|
+
|
|
18
|
+
| Import | Source | Platform |
|
|
19
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------- |
|
|
20
|
+
| `@smthrs/observability` | [src/index.ts](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/observability/src/index.ts) | any |
|
|
21
|
+
| `@smthrs/observability/NodeOtel` | [src/NodeOtel.ts](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/observability/src/NodeOtel.ts) | Node |
|
|
22
|
+
| `@smthrs/observability/BrowserOtel` | [src/BrowserOtel.ts](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/observability/src/BrowserOtel.ts) | browser |
|
|
23
|
+
|
|
24
|
+
The package is tested with `effect@4.0.0-rc.115`. Layers, services, and schemas
|
|
25
|
+
are Effect constructs: a `Layer` provides services, a scoped layer releases on
|
|
26
|
+
scope close, and a schema decodes to an `Effect`.
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import * as Otlp from "@smthrs/observability/Otlp"
|
|
32
|
+
|
|
33
|
+
const telemetry = Otlp.layerFetch({ baseUrl: "http://localhost:4318", serviceName: "deploy-status" })
|
|
34
|
+
const program = Effect.logInfo("deploying the API").pipe(Effect.withSpan("deploy"))
|
|
35
|
+
|
|
36
|
+
await Effect.runPromise(program.pipe(Effect.provide(telemetry), Effect.orDie, Effect.scoped))
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Otlp
|
|
40
|
+
|
|
41
|
+
The default exporter. `Otlp` composes `effect/unstable/observability/Otlp` and
|
|
42
|
+
nothing else, so it allocates no OpenTelemetry SDK and never resolves a `node:`
|
|
43
|
+
built-in. All three signals are JSON-serialized and posted below the configured
|
|
44
|
+
base URL at `/v1/logs`, `/v1/metrics`, and `/v1/traces`.
|
|
45
|
+
|
|
46
|
+
### Otlp.Options
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
interface Options {
|
|
50
|
+
readonly baseUrl: string
|
|
51
|
+
readonly serviceName?: string | undefined
|
|
52
|
+
readonly serviceVersion?: string | undefined
|
|
53
|
+
readonly attributes?: Record<string, unknown> | undefined
|
|
54
|
+
readonly headers?: Headers.Input | undefined
|
|
55
|
+
readonly exportInterval?: Duration.Input | undefined
|
|
56
|
+
readonly shutdownTimeout?: Duration.Input | undefined
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- `baseUrl`: the collector base URL, for example `http://localhost:4318`. It
|
|
61
|
+
must be an absolute `http://` or `https://` URL without credentials, query,
|
|
62
|
+
fragment, backslashes, spaces, or controls; anything else fails acquisition with
|
|
63
|
+
`Endpoint.InvalidExporterEndpoint` on path `baseUrl`.
|
|
64
|
+
- `serviceName`, `serviceVersion`: the `service.name` and `service.version`
|
|
65
|
+
resource attributes. Default to `defaultServiceName` and
|
|
66
|
+
`defaultServiceVersion`.
|
|
67
|
+
- `attributes`: additional resource attributes attached to every exported
|
|
68
|
+
signal, decoded by `Resource.Attributes`.
|
|
69
|
+
- `headers`: sent with every export request, which is where vendor
|
|
70
|
+
authentication goes. A header whose name names a credential
|
|
71
|
+
(`authorization`, `x-api-key`, `x-honeycomb-team`, any name
|
|
72
|
+
`Redaction.isSensitiveKey` recognizes) requires an `https://` `baseUrl` unless the host is `localhost`,
|
|
73
|
+
`127.0.0.0/8`, or `[::1]`; otherwise acquisition fails with
|
|
74
|
+
`Endpoint.InvalidExporterEndpoint` on path `baseUrl`. The check reads
|
|
75
|
+
header names only: a credential under any other name is sent as given, so
|
|
76
|
+
use `https://` for every remote collector.
|
|
77
|
+
- `exportInterval`: the export cadence applied to all three signals. Omitted,
|
|
78
|
+
each signal keeps Effect's own default.
|
|
79
|
+
- `shutdownTimeout`: upper bound on the flush performed when the layer's scope
|
|
80
|
+
closes.
|
|
81
|
+
|
|
82
|
+
### Otlp.layer
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const layer: (options: Options) => Layer.Layer<
|
|
86
|
+
never,
|
|
87
|
+
Resource.InvalidResourceConfiguration | Endpoint.InvalidExporterEndpoint,
|
|
88
|
+
HttpClient.HttpClient
|
|
89
|
+
>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Installs the OTLP logs, metrics, and traces exporters with the flows resource
|
|
93
|
+
defaults filled in. It requires an Effect `HttpClient`, which is how it stays
|
|
94
|
+
platform-neutral: a Node host may provide Undici, a browser or a test provides
|
|
95
|
+
something else. Both configuration inputs are decoded during acquisition, so
|
|
96
|
+
the returned layer either exports or refuses. Ambient `OTEL_RESOURCE_ATTRIBUTES`
|
|
97
|
+
cannot add unvalidated metadata to these explicit resources.
|
|
98
|
+
|
|
99
|
+
Requests over `maxRequestBytes` (1 MiB), stalled for ten seconds, or exceeding
|
|
100
|
+
four in-flight requests are discarded locally. Each discard increments
|
|
101
|
+
`flows_observability_otlp_dropped`. A `Warn` diagnostic with code
|
|
102
|
+
`otlp_export_discarded` reports `reason` (`oversized`, `stalled`, or `saturated`),
|
|
103
|
+
`bytes`, `limit`, and cumulative `dropped` at most once per minute per transport.
|
|
104
|
+
It uses the logger set captured before this exporter is installed, so it cannot
|
|
105
|
+
re-enter this exporter. Request bodies, headers, URLs, and ambient log
|
|
106
|
+
annotations are omitted. Keep an ambient sink outside OTLP at level `Warn` or
|
|
107
|
+
lower to observe loss independently; empty or filtered loggers cannot report it.
|
|
108
|
+
|
|
109
|
+
### Otlp transport constants
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const maxRequestBytes: number // 1048576 (1 MiB)
|
|
113
|
+
const maximumEnvelopeBytes: number // 8192 (8 KiB)
|
|
114
|
+
const reservedBatchBytes: number // 909312 (888 KiB)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The resource ceiling is 128 KiB. Another 8 KiB covers JSON wrappers and the
|
|
118
|
+
instrumentation scope, which repeats the service name (at most 6 KiB after
|
|
119
|
+
escaping). The remaining 888 KiB gives each record in the upstream 1,000-record
|
|
120
|
+
log or span batch about 909 bytes, several times a bare record. This guarantees
|
|
121
|
+
room for ordinary signal batches, not arbitrary record sizes or metric registry
|
|
122
|
+
cardinality.
|
|
123
|
+
|
|
124
|
+
### Otlp.layerFetch
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
const layerFetch: (options: Options) => Layer.Layer<
|
|
128
|
+
never,
|
|
129
|
+
Resource.InvalidResourceConfiguration | Endpoint.InvalidExporterEndpoint
|
|
130
|
+
>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`layer` with `FetchHttpClient.layer` already provided, which binds the host's
|
|
134
|
+
global `fetch`. This is the default wiring on Node 26 and the only one that is
|
|
135
|
+
browser-safe by construction.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const Telemetry = Otlp.layerFetch({ baseUrl: "http://localhost:4318" })
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Otlp.layerEnvironment
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
const layerEnvironment: (
|
|
145
|
+
environment: Readonly<Record<string, string | undefined>>,
|
|
146
|
+
options?: Omit<Options, "baseUrl" | "headers">
|
|
147
|
+
) => Layer.Layer<never, Otlp.LayerError>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`layerFetch` against `OTEL_EXPORTER_OTLP_ENDPOINT` with the headers
|
|
151
|
+
`Otlp.parseHeaders` reads from `OTEL_EXPORTER_OTLP_HEADERS`. An unset or blank
|
|
152
|
+
endpoint returns `layerNoop`, so no exporter is installed. `LayerError` is
|
|
153
|
+
`Resource.InvalidResourceConfiguration | Endpoint.InvalidExporterEndpoint`.
|
|
154
|
+
|
|
155
|
+
### Otlp.parseHeaders
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const parseHeaders: (value: string | undefined) => Record<string, string>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Reads the OpenTelemetry `key=value,key=value` header list and percent-decodes
|
|
162
|
+
each value. Pairs without `=` or with an empty key are skipped; a malformed
|
|
163
|
+
escape is kept verbatim.
|
|
164
|
+
|
|
165
|
+
### Otlp.layerNoop
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const layerNoop: Layer.Layer<never>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Provides nothing and exports nothing. The explicit stand-in for a host with no
|
|
172
|
+
collector, so wiring code switches layers rather than branching.
|
|
173
|
+
|
|
174
|
+
### Otlp.defaultServiceName
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
const defaultServiceName: string // "flows"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The `service.name` attribute installed when the caller supplies none.
|
|
181
|
+
|
|
182
|
+
### Otlp.defaultServiceVersion
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
const defaultServiceVersion: string // "1.0.0-rc.0"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The `service.version` attribute installed when the caller supplies none. It
|
|
189
|
+
mirrors this package's release version, held as a literal because a published
|
|
190
|
+
package cannot read its own manifest on every runtime it supports.
|
|
191
|
+
|
|
192
|
+
### Delivery behavior
|
|
193
|
+
|
|
194
|
+
Effect's exporter retries a transient failure three times, honoring a
|
|
195
|
+
`retry-after` response header when one is present, then disables that exporter
|
|
196
|
+
for 60 seconds and logs a `Debug` record. Export failure never fails the
|
|
197
|
+
application effect and never surfaces as an unhandled rejection. Closing the
|
|
198
|
+
layer's scope performs the final flush, bounded by `shutdownTimeout`.
|
|
199
|
+
|
|
200
|
+
## Endpoint
|
|
201
|
+
|
|
202
|
+
Validated collector endpoints, shared by every OTLP builder. The endpoint is
|
|
203
|
+
the field an operator most often gets wrong, and a wrong one is invisible after
|
|
204
|
+
acquisition, so it is decoded before any exporter exists.
|
|
205
|
+
|
|
206
|
+
### Endpoint.Endpoint
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
const Endpoint: Schema.String.check(...)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Runtime schema for an absolute `http:` or `https:` collector endpoint of at
|
|
213
|
+
most `maximumEndpointLength` characters that carries no credentials, query,
|
|
214
|
+
fragment, backslashes, spaces, or controls. A base path is allowed;
|
|
215
|
+
authentication belongs in exporter headers. Query and fragment suffixes are
|
|
216
|
+
rejected because appending `/v1/traces` to them does not change the request
|
|
217
|
+
path. A value the WHATWG URL parser would repair rather
|
|
218
|
+
than parse as written is refused, because the repaired URL is not the one the
|
|
219
|
+
exporter would post to.
|
|
220
|
+
|
|
221
|
+
### Endpoint.maximumEndpointLength
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
const maximumEndpointLength: number // 2048
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Largest collector endpoint accepted by a builder.
|
|
228
|
+
|
|
229
|
+
### Endpoint.decode
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const decode: (endpoint: unknown, path: string) => Effect.Effect<string, InvalidExporterEndpoint>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Decodes one endpoint into its normalized form. `path` names the option the
|
|
236
|
+
endpoint arrived on, so the refusal points at the caller's own field rather
|
|
237
|
+
than at a shared internal name. The rejected value is not retained in the
|
|
238
|
+
error.
|
|
239
|
+
|
|
240
|
+
### Endpoint.InvalidExporterEndpoint
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
class InvalidExporterEndpoint {
|
|
244
|
+
readonly code: "invalid_exporter_endpoint"
|
|
245
|
+
readonly path: string
|
|
246
|
+
readonly message: string
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The stable exporter-endpoint refusal shared by `Otlp.layer`,
|
|
251
|
+
`Otlp.layerFetch` (`path` is `baseUrl`), and `NodeOtel.layerOtel` (`path` is
|
|
252
|
+
`endpoint`).
|
|
253
|
+
|
|
254
|
+
### Endpoint.normalize
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
const normalize: (endpoint: string) => string
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Removes repeated trailing separators, so `http://host//` and `http://host` both
|
|
261
|
+
produce one signal URL.
|
|
262
|
+
|
|
263
|
+
### Endpoint.signalUrl
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
const signalUrl: (endpoint: string, signal: "traces" | "metrics" | "logs") => string
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Builds the OTLP/HTTP URL one signal is posted to below a decoded endpoint:
|
|
270
|
+
`signalUrl("http://host", "traces")` is `http://host/v1/traces`.
|
|
271
|
+
|
|
272
|
+
## Resource
|
|
273
|
+
|
|
274
|
+
Explicit, validated OpenTelemetry resource metadata. Every public OTEL builder
|
|
275
|
+
in this package decodes the same `Configuration`. Resource metadata comes from
|
|
276
|
+
the caller and the SDK's fixed telemetry fields. Neither the default exporter
|
|
277
|
+
nor the Node SDK layer merges ambient resource configuration after validation.
|
|
278
|
+
|
|
279
|
+
### Resource.Configuration
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
const Configuration: Schema.Struct<{
|
|
283
|
+
serviceName: Schema.String
|
|
284
|
+
serviceVersion: Schema.optional<Schema.String>
|
|
285
|
+
attributes: Schema.optional<typeof Attributes>
|
|
286
|
+
}>
|
|
287
|
+
type Configuration = typeof Configuration.Type
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The service identity attached to exported telemetry. `serviceName` and
|
|
291
|
+
`serviceVersion` are non-empty, well formed, and at most
|
|
292
|
+
`maximumIdentityLength` UTF-16 code units.
|
|
293
|
+
|
|
294
|
+
### Resource.Attributes and Resource.AttributeValue
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
const AttributeValue: Schema.Union<[...]>
|
|
298
|
+
const Attributes: Schema.Record<Schema.String, typeof AttributeValue>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`AttributeValue` accepts a string of at most `maximumAttributeStringLength`
|
|
302
|
+
code units, a finite number, a boolean, or a homogeneous array of one of those
|
|
303
|
+
scalar types, with at most `maximumAttributeArrayLength` elements. `Attributes` bounds the record at `maximumAttributes` entries
|
|
304
|
+
with non-empty, well formed keys of at most `maximumAttributeKeyLength` code
|
|
305
|
+
units. NUL and unpaired UTF-16 surrogates are refused in keys and in values;
|
|
306
|
+
valid astral Unicode is preserved.
|
|
307
|
+
|
|
308
|
+
### Resource constants
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
const maximumIdentityLength: number // 1024
|
|
312
|
+
const maximumAttributeKeyLength: number // 1024
|
|
313
|
+
const maximumAttributeStringLength: number // 65536
|
|
314
|
+
const maximumAttributes: number // 256
|
|
315
|
+
const maximumAttributeArrayLength: number // 256
|
|
316
|
+
const maximumResourceBytes: number // 131072 (128 KiB)
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The resource byte limit counts the complete OTLP JSON resource, including
|
|
320
|
+
identity, SDK-added `telemetry.sdk.name` and `telemetry.sdk.language`, attribute
|
|
321
|
+
keys, scalar and array wrappers, escaping, and UTF-8. SDK fields are reserved
|
|
322
|
+
even for the default Effect exporter, and caller attributes that the SDK
|
|
323
|
+
overwrites are conservatively counted too.
|
|
324
|
+
Counting stops at the first fragment over budget to bound intermediate
|
|
325
|
+
allocations; the error reports the measured lower bound and byte limit at path
|
|
326
|
+
`attributes`. Array-length errors report the measured element count and limit
|
|
327
|
+
at the attribute path. No rejected attribute values are retained.
|
|
328
|
+
|
|
329
|
+
All resource-accepting layers and `decode`, `decodeSync`, and
|
|
330
|
+
`configToAttributes` enforce these bounds before exporter acquisition.
|
|
331
|
+
Explicit `serviceName` and `serviceVersion` take precedence over attributes
|
|
332
|
+
with those keys. Admission conservatively counts those redundant attributes.
|
|
333
|
+
|
|
334
|
+
### Resource.decode
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
const decode: (configuration: unknown) => Effect.Effect<Configuration, InvalidResourceConfiguration>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Decodes one resource configuration without retaining rejected values.
|
|
341
|
+
|
|
342
|
+
### Resource.decodeSync
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
const decodeSync: (configuration: unknown) => Configuration
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
The same decoding for the package's pure projection API. Throws
|
|
349
|
+
`InvalidResourceConfiguration` rather than failing an effect.
|
|
350
|
+
|
|
351
|
+
### Resource.InvalidResourceConfiguration
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
class InvalidResourceConfiguration {
|
|
355
|
+
readonly code: "invalid_resource_configuration"
|
|
356
|
+
readonly path: string
|
|
357
|
+
readonly message: string
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
The stable resource refusal shared by every layer here. `path` is a dotted
|
|
362
|
+
route into the offending field, such as `serviceName` or `attributes.region`,
|
|
363
|
+
and is the bare `resource` when the whole configuration was malformed.
|
|
364
|
+
|
|
365
|
+
### Resource.toOpenTelemetryConfiguration
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
const toOpenTelemetryConfiguration: (configuration: Configuration) => {
|
|
369
|
+
readonly serviceName: string
|
|
370
|
+
readonly serviceVersion?: string
|
|
371
|
+
readonly attributes?: Attributes
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Projects a decoded resource into the exact optional-property shape the
|
|
376
|
+
OpenTelemetry SDK expects, omitting absent optional fields rather than setting
|
|
377
|
+
them to `undefined`.
|
|
378
|
+
|
|
379
|
+
### Resource.configToAttributes
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
const configToAttributes: (configuration: Configuration) => Attributes
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Converts explicit service metadata into OpenTelemetry resource attributes.
|
|
386
|
+
Invalid metadata throws the same typed `InvalidResourceConfiguration` a layer
|
|
387
|
+
returns during acquisition.
|
|
388
|
+
|
|
389
|
+
### Resource.layer
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
const layer: (configuration: Configuration) => Layer.Layer<Resource, InvalidResourceConfiguration>
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Provides an explicitly validated OpenTelemetry resource, for a composition that
|
|
396
|
+
assembles the rest of the SDK itself.
|
|
397
|
+
|
|
398
|
+
### Resource.Resource
|
|
399
|
+
|
|
400
|
+
The OpenTelemetry resource service tag, re-exported from
|
|
401
|
+
`@effect/opentelemetry/Resource`.
|
|
402
|
+
|
|
403
|
+
## Logger
|
|
404
|
+
|
|
405
|
+
Effect logger layers. All four follow two rules: `mergeWithExisting` defaults
|
|
406
|
+
to `false`, so installing one replaces the ambient logger set, and
|
|
407
|
+
`minimumLogLevel` is applied only when the caller names it.
|
|
408
|
+
|
|
409
|
+
### Logger.Options
|
|
410
|
+
|
|
411
|
+
```ts
|
|
412
|
+
interface Options {
|
|
413
|
+
readonly minimumLogLevel?: LogLevel.LogLevel | undefined
|
|
414
|
+
readonly mergeWithExisting?: boolean | undefined
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
- `minimumLogLevel`: pins `References.MinimumLogLevel` for the whole
|
|
419
|
+
application. Omitted, the layer leaves that reference alone and Effect's own
|
|
420
|
+
`Info` default applies.
|
|
421
|
+
- `mergeWithExisting`: keeps the ambient loggers alongside this one. Defaults
|
|
422
|
+
to `false`.
|
|
423
|
+
|
|
424
|
+
### Logger.layerPrettyDev
|
|
425
|
+
|
|
426
|
+
```ts
|
|
427
|
+
const layerPrettyDev: (options?: Options) => Layer.Layer<never>
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
A human-readable development logger, with colors and mode chosen from the
|
|
431
|
+
output it finds.
|
|
432
|
+
|
|
433
|
+
### Logger.layerStructuredJson
|
|
434
|
+
|
|
435
|
+
```ts
|
|
436
|
+
const layerStructuredJson: (options?: Options) => Layer.Layer<never>
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
One structured JSON object per log line.
|
|
440
|
+
|
|
441
|
+
### Logger.layerNoop
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
const layerNoop: (options?: Pick<Options, "minimumLogLevel">) => Layer.Layer<never>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Removes the active logger set. This is the one exception to the second rule:
|
|
448
|
+
silencing is its purpose, so it pins `None` unless the caller names another
|
|
449
|
+
level.
|
|
450
|
+
|
|
451
|
+
### Logger.layer
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
const layer: (logger: Logger.Logger<unknown, unknown>, options?: Options) => Layer.Layer<never>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Installs a caller-supplied logger under the same two rules.
|
|
458
|
+
|
|
459
|
+
## JournalLogger
|
|
460
|
+
|
|
461
|
+
Non-blocking forwarding of bounded operational logs to the durable journal. The
|
|
462
|
+
callback reads the queue's remaining room, snapshots and redacts a bounded
|
|
463
|
+
record synchronously only when a slot is free, then performs only queue
|
|
464
|
+
admission; a forked worker drains the queue into the journal. A record a full
|
|
465
|
+
queue cannot take is counted and discarded without being snapshotted.
|
|
466
|
+
|
|
467
|
+
### JournalLogger.Options
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
interface Options {
|
|
471
|
+
readonly runId: JournalEvent.RunId
|
|
472
|
+
readonly capacity?: number | undefined
|
|
473
|
+
readonly minimumLogLevel?: LogLevel.LogLevel | undefined
|
|
474
|
+
readonly mergeWithExisting?: boolean | undefined
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
- `runId`: the run every forwarded record is attributed to.
|
|
479
|
+
- `capacity`: queue depth, 1 through `maximumCapacity`. Defaults to 256.
|
|
480
|
+
- `minimumLogLevel` and `mergeWithExisting`: as on `Logger.Options`.
|
|
481
|
+
|
|
482
|
+
### JournalLogger.layerJournalForwarding
|
|
483
|
+
|
|
484
|
+
```ts
|
|
485
|
+
const layerJournalForwarding: (
|
|
486
|
+
options: Options
|
|
487
|
+
) => Layer.Layer<never, InvalidJournalLoggerOptions, Journal.Journal>
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Installs a bounded, drop-on-overflow forwarder for one explicit run.
|
|
491
|
+
Configuration is decoded before a worker starts, so an invalid run id or
|
|
492
|
+
capacity fails acquisition rather than being routed through the lossy worker.
|
|
493
|
+
|
|
494
|
+
Each record becomes one journal entry on the lossy channel, with `eventType`
|
|
495
|
+
`telemetry.log`, source `flows/observability/logger`, and a `TelemetryLog`
|
|
496
|
+
payload. The durable journal allocates the per-source sequence, so a rebuilt or
|
|
497
|
+
concurrently running layer for one run cannot reuse an identity.
|
|
498
|
+
|
|
499
|
+
Overflow, journal delivery failures, and journal defects are telemetry losses
|
|
500
|
+
rather than application failures. Each advances `Metric.droppedLogRecords`; the
|
|
501
|
+
two failure paths also log a warning annotated with the run id, and the worker
|
|
502
|
+
keeps draining. Interruption stays fatal, and closing the scope may drop
|
|
503
|
+
records queued behind an in-flight write.
|
|
504
|
+
|
|
505
|
+
### JournalLogger.TelemetryLog
|
|
506
|
+
|
|
507
|
+
```ts
|
|
508
|
+
const TelemetryLog: Schema.Struct<{
|
|
509
|
+
version: Schema.Literal<1>
|
|
510
|
+
level: Schema.Literals<["All", "Fatal", "Error", "Warn", "Info", "Debug", "Trace", "None"]>
|
|
511
|
+
message: Schema.Unknown
|
|
512
|
+
annotations: Schema.Record<Schema.String, Schema.Unknown>
|
|
513
|
+
cause: typeof TelemetryCause
|
|
514
|
+
fiberId: Schema.Int
|
|
515
|
+
traceId: Schema.optionalKey<Schema.String>
|
|
516
|
+
spanId: Schema.optionalKey<Schema.String>
|
|
517
|
+
timestamp: Schema.String
|
|
518
|
+
}>
|
|
519
|
+
type TelemetryLog = typeof TelemetryLog.Type
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
The durable wire shape of one forwarded log record. `traceId` and `spanId` are
|
|
523
|
+
present only when a span was active. `timestamp` is ISO-8601. Every persisted
|
|
524
|
+
`telemetry.log` payload decodes with this schema: a projection that would not
|
|
525
|
+
degrades to a total record with an empty cause rather than to a payload
|
|
526
|
+
consumers throw on.
|
|
527
|
+
|
|
528
|
+
### JournalLogger.TelemetryCause
|
|
529
|
+
|
|
530
|
+
```ts
|
|
531
|
+
const TelemetryCause: Schema.Struct<{
|
|
532
|
+
version: Schema.Literal<1>
|
|
533
|
+
reasons: Schema.Array<typeof TelemetryCauseReason>
|
|
534
|
+
}>
|
|
535
|
+
type TelemetryCause = typeof TelemetryCause.Type
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
A versioned structural Effect cause. Effect stores composed failures as an
|
|
539
|
+
ordered reason list, and the projection preserves that order and each
|
|
540
|
+
discriminator.
|
|
541
|
+
|
|
542
|
+
### JournalLogger.TelemetryCauseReason
|
|
543
|
+
|
|
544
|
+
```ts
|
|
545
|
+
const TelemetryCauseReason: Schema.Union<[
|
|
546
|
+
typeof TelemetryFail,
|
|
547
|
+
typeof TelemetryDie,
|
|
548
|
+
typeof TelemetryInterrupt
|
|
549
|
+
]>
|
|
550
|
+
type TelemetryCauseReason = typeof TelemetryCauseReason.Type
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
One reason in a persisted cause. `TelemetryFail` carries `error`,
|
|
554
|
+
`TelemetryDie` carries `defect`, and `TelemetryInterrupt` carries a
|
|
555
|
+
non-negative `fiberId` or `null`. All three are exported individually.
|
|
556
|
+
|
|
557
|
+
### JournalLogger.InvalidJournalLoggerOptions
|
|
558
|
+
|
|
559
|
+
```ts
|
|
560
|
+
class InvalidJournalLoggerOptions {
|
|
561
|
+
readonly code: "invalid_journal_logger_options"
|
|
562
|
+
readonly path: string
|
|
563
|
+
readonly message: string
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
The stable logger-configuration refusal, raised during layer acquisition.
|
|
568
|
+
|
|
569
|
+
### JournalLogger constants
|
|
570
|
+
|
|
571
|
+
```ts
|
|
572
|
+
const maximumCapacity: number // 65536
|
|
573
|
+
const maximumSnapshotBytes: number // 1048576
|
|
574
|
+
const maximumSnapshotMembers: number // 4096
|
|
575
|
+
const maximumSnapshotDepth: number // 64
|
|
576
|
+
const unrenderableMarker: string // "[Unrenderable]"
|
|
577
|
+
const truncatedMarker: string // "[Truncated]"
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
A snapshot admits at most `maximumSnapshotBytes` of encoded data,
|
|
581
|
+
`maximumSnapshotMembers` container members, and `maximumSnapshotDepth`
|
|
582
|
+
container edges. Unreadable values become `unrenderableMarker`, values past a
|
|
583
|
+
ceiling become `truncatedMarker`, and deeper values become the journal's
|
|
584
|
+
`[Deep]` marker. Container-shaped fields keep their shape, so annotations that
|
|
585
|
+
spent the whole budget arrive as `{ "[Truncated]": "[Truncated]" }` rather than
|
|
586
|
+
as a scalar. Text is bounded in one pass that never cuts a surrogate pair, and
|
|
587
|
+
the journal's own redaction rules run before queue admission.
|
|
588
|
+
|
|
589
|
+
## Metric
|
|
590
|
+
|
|
591
|
+
The runtime signals that cross package boundaries. Producers live in the
|
|
592
|
+
packages that know when to advance them; this module owns only the identifiers
|
|
593
|
+
and the handles.
|
|
594
|
+
|
|
595
|
+
### Metric handles
|
|
596
|
+
|
|
597
|
+
```ts
|
|
598
|
+
const runThroughput: Metric.Counter // "flows_run_throughput"
|
|
599
|
+
const activeSeats: Metric.Gauge // "flows_seat_active"
|
|
600
|
+
const quotaParks: Metric.Counter // "flows_quota_park"
|
|
601
|
+
const structuredOutputRejections: Metric.Counter // "flows_agent_structured_output_rejections"
|
|
602
|
+
const structuredOutputExhausted: Metric.Counter // "flows_agent_structured_output_exhausted"
|
|
603
|
+
const droppedLogRecords: Metric.Counter // "flows_observability_log_dropped"
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
- `runThroughput` advances after a terminal run transition commits in
|
|
607
|
+
[`@smthrs/run-store`](/api/run-store).
|
|
608
|
+
- `activeSeats` is held for the lifetime of a production `Agent.run` stream in
|
|
609
|
+
[`@smthrs/agent`](/api/agent) and released on success, failure, or
|
|
610
|
+
interruption.
|
|
611
|
+
- `quotaParks` advances when a sealed quota decision is first executed, not
|
|
612
|
+
when it is replayed after a wake or a process restart.
|
|
613
|
+
- `structuredOutputRejections` advances once per agent answer its declared
|
|
614
|
+
output schema refuses, in the same session or a fresh one.
|
|
615
|
+
- `structuredOutputExhausted` advances once per agent step that fails after
|
|
616
|
+
spending every output correction and its repair.
|
|
617
|
+
- `droppedLogRecords` advances once per record lost by `JournalLogger`.
|
|
618
|
+
|
|
619
|
+
Step-cache lookup and write counters remain owned by
|
|
620
|
+
[`@smthrs/step-cache`](/api/step-cache); this package does not duplicate those
|
|
621
|
+
handles.
|
|
622
|
+
|
|
623
|
+
### Metric.registry
|
|
624
|
+
|
|
625
|
+
```ts
|
|
626
|
+
const registry: {
|
|
627
|
+
readonly runThroughput: typeof runThroughput
|
|
628
|
+
readonly activeSeats: typeof activeSeats
|
|
629
|
+
readonly quotaParks: typeof quotaParks
|
|
630
|
+
readonly structuredOutputRejections: typeof structuredOutputRejections
|
|
631
|
+
readonly structuredOutputExhausted: typeof structuredOutputExhausted
|
|
632
|
+
readonly droppedLogRecords: typeof droppedLogRecords
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
All six handles as one object, for a host that enumerates them. The six
|
|
637
|
+
series names are the dashboard contract; treat them as public API.
|
|
638
|
+
|
|
639
|
+
## Otel
|
|
640
|
+
|
|
641
|
+
Provider-neutral composition for OpenTelemetry providers the application
|
|
642
|
+
already built. This module allocates no exporter.
|
|
643
|
+
|
|
644
|
+
### Otel.Options
|
|
645
|
+
|
|
646
|
+
```ts
|
|
647
|
+
interface Options {
|
|
648
|
+
readonly resource: Resource.Configuration
|
|
649
|
+
readonly tracerProvider?:
|
|
650
|
+
| Api.TracerProvider
|
|
651
|
+
| ((resource: Resource) => Api.TracerProvider)
|
|
652
|
+
| undefined
|
|
653
|
+
readonly loggerProvider?:
|
|
654
|
+
| LoggerProvider
|
|
655
|
+
| ((resource: Resource) => LoggerProvider)
|
|
656
|
+
| undefined
|
|
657
|
+
readonly metricReader?: (() => MetricReader | ReadonlyArray<MetricReader>) | undefined
|
|
658
|
+
readonly loggerMergeWithExisting?: boolean | undefined
|
|
659
|
+
readonly metricTemporality?: OtelMetrics.TemporalityPreference | undefined
|
|
660
|
+
}
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
`metricTemporality` is `"cumulative"` or `"delta"`.
|
|
664
|
+
|
|
665
|
+
Ownership differs by field. `tracerProvider` and `loggerProvider` are borrowed:
|
|
666
|
+
the layer bridges onto them and never flushes or shuts one down, including a
|
|
667
|
+
provider a factory returned. `metricReader` is owned: the factory runs once
|
|
668
|
+
during layer acquisition, after resource validation, and closing the layer's
|
|
669
|
+
scope shuts down every reader it returned. Build the readers inside the
|
|
670
|
+
factory. Returning a reader that a longer-lived composition still exports
|
|
671
|
+
through disables that reader when this scope closes.
|
|
672
|
+
|
|
673
|
+
### Otel.layerOtel
|
|
674
|
+
|
|
675
|
+
```ts
|
|
676
|
+
const layerOtel: (options: Options) => Layer.Layer<never, Resource.InvalidResourceConfiguration>
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Bridges Effect's tracer, logger, and metrics onto the supplied providers and
|
|
680
|
+
the readers the `metricReader` factory returns, over the validated resource.
|
|
681
|
+
Each bridge is installed only when its provider or factory is supplied, and a
|
|
682
|
+
factory that returns an empty array registers no reader at all.
|
|
683
|
+
|
|
684
|
+
### Otel.layerNoop
|
|
685
|
+
|
|
686
|
+
```ts
|
|
687
|
+
const layerNoop: Layer.Layer<never>
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
A no-op OTEL layer, for callers that want an explicit optional slot.
|
|
691
|
+
|
|
692
|
+
## NodeOtel
|
|
693
|
+
|
|
694
|
+
Node-only OTLP/HTTP OpenTelemetry SDK setup. Import it from
|
|
695
|
+
`@smthrs/observability/NodeOtel`; it is not re-exported from the root, because
|
|
696
|
+
it resolves Node-only host modules and would break the root's browser bundle.
|
|
697
|
+
|
|
698
|
+
### NodeOtel.Options
|
|
699
|
+
|
|
700
|
+
```ts
|
|
701
|
+
interface Options {
|
|
702
|
+
readonly endpoint: string
|
|
703
|
+
readonly resource: Resource.Configuration
|
|
704
|
+
readonly shutdownTimeout?: Duration.Input | undefined
|
|
705
|
+
readonly exportIntervalMillis?: number | undefined
|
|
706
|
+
}
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
`endpoint` is decoded exactly as `Otlp.Options.baseUrl` is, and a refusal names
|
|
710
|
+
the path `endpoint`.
|
|
711
|
+
|
|
712
|
+
### NodeOtel.layerOtel
|
|
713
|
+
|
|
714
|
+
```ts
|
|
715
|
+
const layerOtel: (options: Options) => Layer.Layer<
|
|
716
|
+
never,
|
|
717
|
+
Resource.InvalidResourceConfiguration | Endpoint.InvalidExporterEndpoint
|
|
718
|
+
>
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
Builds a scoped Node OTLP/HTTP layer for all three signals: a
|
|
722
|
+
`BatchSpanProcessor`, a `BatchLogRecordProcessor`, and a
|
|
723
|
+
`PeriodicExportingMetricReader`, each behind its own OTLP exporter. Exporter
|
|
724
|
+
objects are created only when the layer is built. `OTEL_SERVICE_NAME` and
|
|
725
|
+
`OTEL_RESOURCE_ATTRIBUTES` cannot add resource metadata after validation,
|
|
726
|
+
whether supplied by the process environment or an Effect `ConfigProvider`.
|
|
727
|
+
The OpenTelemetry exporters still read the standard transport variables
|
|
728
|
+
(`OTEL_EXPORTER_OTLP_HEADERS`, `_TIMEOUT`, `_COMPRESSION`, `_CERTIFICATE`,
|
|
729
|
+
`_CLIENT_CERTIFICATE`, `_CLIENT_KEY`, and their per-signal forms) from the
|
|
730
|
+
process environment; the explicit `endpoint` always wins over
|
|
731
|
+
`OTEL_EXPORTER_OTLP_ENDPOINT`. Headers set there reach this `endpoint`, so do
|
|
732
|
+
not set them for a different collector. `Otlp.layer` reads none of these.
|
|
733
|
+
Closing the scope
|
|
734
|
+
force-flushes both batch processors and collects the metric reader once, so
|
|
735
|
+
release rather than the interval is the deterministic flush.
|
|
736
|
+
|
|
737
|
+
## BrowserOtel
|
|
738
|
+
|
|
739
|
+
Browser OpenTelemetry SDK setup with explicitly injected processors. Import it
|
|
740
|
+
from `@smthrs/observability/BrowserOtel`.
|
|
741
|
+
|
|
742
|
+
### BrowserOtel.Options
|
|
743
|
+
|
|
744
|
+
```ts
|
|
745
|
+
interface Options {
|
|
746
|
+
readonly resource: Resource.Configuration
|
|
747
|
+
readonly spanProcessor?: (() => SpanProcessor | ReadonlyArray<SpanProcessor>) | undefined
|
|
748
|
+
readonly logRecordProcessor?: (() => LogRecordProcessor | ReadonlyArray<LogRecordProcessor>) | undefined
|
|
749
|
+
readonly metricReader?: (() => MetricReader | ReadonlyArray<MetricReader>) | undefined
|
|
750
|
+
readonly loggerMergeWithExisting?: boolean | undefined
|
|
751
|
+
}
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
Processors and readers are created by the caller's factories, which keeps this
|
|
755
|
+
module free of Node imports and free of browser exporter policy. Every factory
|
|
756
|
+
is owned: it runs once during layer acquisition, after resource validation, and
|
|
757
|
+
the web SDK shuts down everything it returned when the scope closes. A factory
|
|
758
|
+
that returns an empty array installs nothing for that signal.
|
|
759
|
+
|
|
760
|
+
### BrowserOtel.layerOtel
|
|
761
|
+
|
|
762
|
+
```ts
|
|
763
|
+
const layerOtel: (options: Options) => Layer.Layer<never, Resource.InvalidResourceConfiguration>
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
Builds a scoped browser OpenTelemetry layer over the validated resource. A
|
|
767
|
+
layer with no processor factories at all still builds; it provides the resource
|
|
768
|
+
and bridges nothing.
|