@smthrs/observability 0.35.0 → 1.0.0-rc.12
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 +87 -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 +415 -0
- package/dist/cjs/JournalLogger.js.map +7 -0
- package/dist/cjs/Logger.d.ts +56 -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 +63 -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 +203 -0
- package/dist/cjs/Otlp.d.ts.map +1 -0
- package/dist/cjs/Otlp.js +251 -0
- package/dist/cjs/Otlp.js.map +7 -0
- package/dist/cjs/Resource.d.ts +163 -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 +520 -0
- package/dist/esm/JournalLogger.js.map +1 -0
- package/dist/esm/Logger.d.ts +56 -0
- package/dist/esm/Logger.d.ts.map +1 -0
- package/dist/esm/Logger.js +61 -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 +63 -0
- package/dist/esm/Otel.d.ts.map +1 -0
- package/dist/esm/Otel.js +52 -0
- package/dist/esm/Otel.js.map +1 -0
- package/dist/esm/Otlp.d.ts +203 -0
- package/dist/esm/Otlp.d.ts.map +1 -0
- package/dist/esm/Otlp.js +384 -0
- package/dist/esm/Otlp.js.map +1 -0
- package/dist/esm/Resource.d.ts +163 -0
- package/dist/esm/Resource.d.ts.map +1 -0
- package/dist/esm/Resource.js +238 -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 +164 -0
- package/docs/api.md +780 -0
- package/docs/concepts/instrumentation-and-export.md +98 -0
- package/docs/concepts/layer-map.md +73 -0
- package/docs/concepts/validated-acquisition.md +106 -0
- package/docs/guides/export-to-a-collector.md +190 -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 +226 -0
- package/docs/installation.md +102 -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 +635 -0
- package/src/Logger.ts +107 -0
- package/src/Metric.ts +88 -0
- package/src/NodeOtel.ts +90 -0
- package/src/Otel.ts +118 -0
- package/src/Otlp.ts +514 -0
- package/src/Resource.ts +325 -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/src/Resource.ts
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explicit, validated OpenTelemetry resource metadata for Smithers.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as OtelResource from "@effect/opentelemetry/Resource"
|
|
8
|
+
import type { Attributes as OtelAttributes } from "@opentelemetry/api"
|
|
9
|
+
import * as Effect from "effect/Effect"
|
|
10
|
+
import * as Layer from "effect/Layer"
|
|
11
|
+
import * as OtlpResource from "effect/observability/OtlpResource"
|
|
12
|
+
import * as Schema from "effect/Schema"
|
|
13
|
+
import { schemaIssueMessage, schemaIssuePath } from "./internal/schemaIssuePath.ts"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Largest service-name or service-version field accepted by a resource.
|
|
17
|
+
*
|
|
18
|
+
* @category constants
|
|
19
|
+
* @since 1.0.0-rc.0
|
|
20
|
+
*/
|
|
21
|
+
export const maximumIdentityLength = 1_024
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Largest attribute key accepted by a resource.
|
|
25
|
+
*
|
|
26
|
+
* @category constants
|
|
27
|
+
* @since 1.0.0-rc.0
|
|
28
|
+
*/
|
|
29
|
+
export const maximumAttributeKeyLength = 1_024
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Largest string value accepted by one resource attribute.
|
|
33
|
+
*
|
|
34
|
+
* @category constants
|
|
35
|
+
* @since 1.0.0-rc.0
|
|
36
|
+
*/
|
|
37
|
+
export const maximumAttributeStringLength = 65_536
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Largest number of elements accepted in one array attribute value.
|
|
41
|
+
*
|
|
42
|
+
* @category constants
|
|
43
|
+
* @since 1.0.0-rc.0
|
|
44
|
+
*/
|
|
45
|
+
export const maximumAttributeArrayLength = 256
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Largest number of attributes accepted by one resource.
|
|
49
|
+
*
|
|
50
|
+
* @category constants
|
|
51
|
+
* @since 1.0.0-rc.0
|
|
52
|
+
*/
|
|
53
|
+
export const maximumAttributes = 256
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Largest OTLP/JSON encoding accepted for one whole resource, in UTF-8 bytes.
|
|
57
|
+
*
|
|
58
|
+
* The measure is the OTLP `Resource` message the exporters place in every
|
|
59
|
+
* request, `{"attributes":[{"key":…,"value":{…}}],"droppedAttributesCount":0}`
|
|
60
|
+
* with service identity and SDK-added `telemetry.sdk.name`,
|
|
61
|
+
* `telemetry.sdk.language` and `telemetry.sdk.version` included, after JSON
|
|
62
|
+
* escaping and UTF-8 encoding. The SDK's own values are reserved even for the
|
|
63
|
+
* default Effect exporter, whose values are shorter. A caller attribute that
|
|
64
|
+
* replaces an SDK field, or that service identity overwrites, is counted
|
|
65
|
+
* beside it. It is the bound the per-field limits cannot express: 256
|
|
66
|
+
* attributes at the string ceiling would encode to 16 MiB, and the resource
|
|
67
|
+
* rides in every export request, so the default transport, which discards a
|
|
68
|
+
* request over 1 MiB, would deliver nothing at all. 128 KiB admits one
|
|
69
|
+
* ASCII attribute at the string ceiling and leaves that transport 888 KiB of every
|
|
70
|
+
* request for the signal batch; see `Otlp.reservedBatchBytes`.
|
|
71
|
+
*
|
|
72
|
+
* @category constants
|
|
73
|
+
* @since 1.0.0-rc.0
|
|
74
|
+
*/
|
|
75
|
+
export const maximumResourceBytes = 131_072
|
|
76
|
+
|
|
77
|
+
const loneSurrogate = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/
|
|
78
|
+
const embeddedNul = new RegExp(String.fromCharCode(0))
|
|
79
|
+
|
|
80
|
+
const isWellFormed = (value: string): boolean => !loneSurrogate.test(value) && !embeddedNul.test(value)
|
|
81
|
+
|
|
82
|
+
const identity = Schema.NonEmptyString.check(
|
|
83
|
+
Schema.isMaxLength(maximumIdentityLength),
|
|
84
|
+
Schema.makeFilter((value: string) => isWellFormed(value), { title: "wellFormedResourceIdentity" })
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const attributeString = Schema.String.check(
|
|
88
|
+
Schema.isMaxLength(maximumAttributeStringLength),
|
|
89
|
+
Schema.makeFilter((value: string) => isWellFormed(value), { title: "wellFormedAttributeString" })
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const attributeNumber = Schema.Number.check(
|
|
93
|
+
Schema.makeFilter((value: number) => Number.isFinite(value), { title: "finiteAttributeNumber" })
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Runtime schema for one OpenTelemetry resource attribute value.
|
|
98
|
+
*
|
|
99
|
+
* @category schemas
|
|
100
|
+
* @since 1.0.0-rc.0
|
|
101
|
+
*/
|
|
102
|
+
export const AttributeValue = Schema.Union([
|
|
103
|
+
attributeString,
|
|
104
|
+
attributeNumber,
|
|
105
|
+
Schema.Boolean,
|
|
106
|
+
Schema.Array(attributeString),
|
|
107
|
+
Schema.Array(attributeNumber),
|
|
108
|
+
Schema.Array(Schema.Boolean)
|
|
109
|
+
]).check(
|
|
110
|
+
Schema.makeFilter(
|
|
111
|
+
(value) =>
|
|
112
|
+
!Array.isArray(value) || value.length <= maximumAttributeArrayLength || {
|
|
113
|
+
path: [],
|
|
114
|
+
issue: `holds ${value.length} elements, over the ${maximumAttributeArrayLength} element limit`
|
|
115
|
+
},
|
|
116
|
+
{ title: "boundedResourceAttributeArrays" }
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Runtime schema for OpenTelemetry resource attributes.
|
|
122
|
+
*
|
|
123
|
+
* @category schemas
|
|
124
|
+
* @since 1.0.0-rc.0
|
|
125
|
+
*/
|
|
126
|
+
export const Attributes = Schema.Record(Schema.String, AttributeValue).check(
|
|
127
|
+
Schema.makeFilter(
|
|
128
|
+
(attributes: Readonly<Record<string, unknown>>) => Object.keys(attributes).length <= maximumAttributes,
|
|
129
|
+
{ title: "boundedResourceAttributes" }
|
|
130
|
+
),
|
|
131
|
+
Schema.makeFilter(
|
|
132
|
+
(attributes: Readonly<Record<string, unknown>>) =>
|
|
133
|
+
Object.keys(attributes).every(
|
|
134
|
+
(key) => key.length > 0 && key.length <= maximumAttributeKeyLength && isWellFormed(key)
|
|
135
|
+
),
|
|
136
|
+
{ title: "wellFormedResourceAttributeKeys" }
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
const encoder = new TextEncoder()
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Counts OTLP JSON fragments, including keys, wrappers, escaping and UTF-8.
|
|
144
|
+
* Stops at the first fragment over budget: the refusal reports a lower bound.
|
|
145
|
+
* A configuration may reuse one large string in thousands of array slots, so
|
|
146
|
+
* serializing the whole resource before checking could allocate gigabytes.
|
|
147
|
+
*/
|
|
148
|
+
const encodedResourceBytes = (configuration: {
|
|
149
|
+
readonly serviceName: string
|
|
150
|
+
readonly serviceVersion?: string | undefined
|
|
151
|
+
readonly attributes?: Record<string, unknown> | undefined
|
|
152
|
+
}): number => {
|
|
153
|
+
const bytes = (value: unknown) => encoder.encode(JSON.stringify(value)).byteLength
|
|
154
|
+
const identityAttributes = OtelResource.configToAttributes({
|
|
155
|
+
serviceName: configuration.serviceName,
|
|
156
|
+
...(configuration.serviceVersion === undefined ? {} : { serviceVersion: configuration.serviceVersion })
|
|
157
|
+
})
|
|
158
|
+
// Use the pinned SDK projection so its added metadata cannot escape the
|
|
159
|
+
// complete-resource ceiling. Both exporters use these OTLP AnyValue shapes.
|
|
160
|
+
let total = bytes({
|
|
161
|
+
attributes: OtlpResource.entriesToAttributes(Object.entries(identityAttributes)),
|
|
162
|
+
droppedAttributesCount: 0
|
|
163
|
+
})
|
|
164
|
+
for (const [key, value] of Object.entries(configuration.attributes ?? {})) {
|
|
165
|
+
// An identity attribute is always present, so every addition needs a comma.
|
|
166
|
+
total += 1 + bytes({ key, value: Array.isArray(value) ? { arrayValue: { values: [] } } : null })
|
|
167
|
+
if (Array.isArray(value)) {
|
|
168
|
+
for (const [index, element] of value.entries()) {
|
|
169
|
+
total += (index === 0 ? 0 : 1) + bytes(OtlpResource.unknownToAttributeValue(element))
|
|
170
|
+
if (total > maximumResourceBytes) return total
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
total += bytes(OtlpResource.unknownToAttributeValue(value)) - 4 // replace JSON null
|
|
174
|
+
}
|
|
175
|
+
if (total > maximumResourceBytes) return total
|
|
176
|
+
}
|
|
177
|
+
return total
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Runtime schema for the service identity attached to exported telemetry.
|
|
182
|
+
*
|
|
183
|
+
* @category schemas
|
|
184
|
+
* @since 1.0.0-rc.0
|
|
185
|
+
*/
|
|
186
|
+
export const Configuration = Schema.Struct({
|
|
187
|
+
serviceName: identity,
|
|
188
|
+
serviceVersion: Schema.optional(identity),
|
|
189
|
+
attributes: Schema.optional(Attributes)
|
|
190
|
+
}).check(
|
|
191
|
+
Schema.makeFilter(
|
|
192
|
+
(configuration: {
|
|
193
|
+
readonly serviceName: string
|
|
194
|
+
readonly serviceVersion?: string | undefined
|
|
195
|
+
readonly attributes?: Record<string, unknown> | undefined
|
|
196
|
+
}) => {
|
|
197
|
+
const bytes = encodedResourceBytes(configuration)
|
|
198
|
+
// Only attributes can carry a resource past the budget: the two identity
|
|
199
|
+
// fields encode to at most 6 KiB each, so the refusal points there.
|
|
200
|
+
return bytes <= maximumResourceBytes || {
|
|
201
|
+
path: ["attributes"],
|
|
202
|
+
issue: `bring the resource to at least ${bytes} bytes of OTLP JSON, over the ${maximumResourceBytes} byte limit`
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
{ title: "boundedResourceBytes" }
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Configuration used to identify the service emitting telemetry.
|
|
211
|
+
*
|
|
212
|
+
* @category models
|
|
213
|
+
* @since 1.0.0-rc.0
|
|
214
|
+
*/
|
|
215
|
+
export type Configuration = typeof Configuration.Type
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Stable resource-configuration refusal shared by every OTEL layer.
|
|
219
|
+
*
|
|
220
|
+
* @category errors
|
|
221
|
+
* @since 1.0.0-rc.0
|
|
222
|
+
*/
|
|
223
|
+
export class InvalidResourceConfiguration extends Schema.TaggedError<InvalidResourceConfiguration>()(
|
|
224
|
+
"@smthrs/observability/InvalidResourceConfiguration",
|
|
225
|
+
{
|
|
226
|
+
code: Schema.Literal("invalid_resource_configuration"),
|
|
227
|
+
path: Schema.String,
|
|
228
|
+
message: Schema.String
|
|
229
|
+
}
|
|
230
|
+
) {}
|
|
231
|
+
|
|
232
|
+
const invalid = (cause: unknown): InvalidResourceConfiguration => {
|
|
233
|
+
const path = schemaIssuePath(cause, "resource")
|
|
234
|
+
return new InvalidResourceConfiguration({
|
|
235
|
+
code: "invalid_resource_configuration",
|
|
236
|
+
path,
|
|
237
|
+
message: `OpenTelemetry resource ${path} ${schemaIssueMessage(cause) ?? "is invalid"}`
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Decodes one resource configuration without retaining rejected values.
|
|
243
|
+
*
|
|
244
|
+
* @category decoding
|
|
245
|
+
* @since 1.0.0-rc.0
|
|
246
|
+
*/
|
|
247
|
+
export const decode = (
|
|
248
|
+
configuration: unknown
|
|
249
|
+
): Effect.Effect<Configuration, InvalidResourceConfiguration> =>
|
|
250
|
+
Schema.decodeUnknownEffect(Configuration)(configuration).pipe(Effect.mapError(invalid))
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Decodes one resource configuration for the package's pure projection API.
|
|
254
|
+
*
|
|
255
|
+
* @category decoding
|
|
256
|
+
* @since 1.0.0-rc.0
|
|
257
|
+
*/
|
|
258
|
+
export const decodeSync = (configuration: unknown): Configuration => {
|
|
259
|
+
try {
|
|
260
|
+
return Schema.decodeUnknownSync(Configuration)(configuration)
|
|
261
|
+
} catch (cause) {
|
|
262
|
+
throw invalid(cause)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Projects a decoded resource into the exact optional-property shape expected
|
|
268
|
+
* by the OpenTelemetry SDK.
|
|
269
|
+
*
|
|
270
|
+
* @category conversions
|
|
271
|
+
* @since 1.0.0-rc.0
|
|
272
|
+
*/
|
|
273
|
+
export const toOpenTelemetryConfiguration = (
|
|
274
|
+
configuration: Configuration
|
|
275
|
+
): {
|
|
276
|
+
readonly serviceName: string
|
|
277
|
+
readonly serviceVersion?: string
|
|
278
|
+
readonly attributes?: OtelAttributes
|
|
279
|
+
} => ({
|
|
280
|
+
serviceName: configuration.serviceName,
|
|
281
|
+
...(configuration.serviceVersion === undefined ? {} : { serviceVersion: configuration.serviceVersion }),
|
|
282
|
+
...(configuration.attributes === undefined
|
|
283
|
+
? {}
|
|
284
|
+
: {
|
|
285
|
+
attributes: Object.fromEntries(
|
|
286
|
+
Object.entries(configuration.attributes).map(([key, value]) => [
|
|
287
|
+
key,
|
|
288
|
+
Array.isArray(value) ? [...value] : value
|
|
289
|
+
])
|
|
290
|
+
) as OtelAttributes
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Converts explicit service metadata into OpenTelemetry resource attributes.
|
|
296
|
+
*
|
|
297
|
+
* No environment variables are read. Invalid metadata throws the same typed
|
|
298
|
+
* {@link InvalidResourceConfiguration} every layer returns during acquisition.
|
|
299
|
+
*
|
|
300
|
+
* @category conversions
|
|
301
|
+
* @since 1.0.0-rc.0
|
|
302
|
+
*/
|
|
303
|
+
export const configToAttributes = (configuration: Configuration): OtelAttributes =>
|
|
304
|
+
OtelResource.configToAttributes(toOpenTelemetryConfiguration(decodeSync(configuration)))
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Provides an explicitly validated OpenTelemetry resource.
|
|
308
|
+
*
|
|
309
|
+
* @category layers
|
|
310
|
+
* @since 1.0.0-rc.0
|
|
311
|
+
*/
|
|
312
|
+
export const layer = (
|
|
313
|
+
configuration: Configuration
|
|
314
|
+
): Layer.Layer<OtelResource.Resource, InvalidResourceConfiguration> =>
|
|
315
|
+
Layer.unwrap(
|
|
316
|
+
Effect.map(decode(configuration), (decoded) => OtelResource.layer(toOpenTelemetryConfiguration(decoded)))
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* The OpenTelemetry resource service.
|
|
321
|
+
*
|
|
322
|
+
* @category services
|
|
323
|
+
* @since 1.0.0-rc.0
|
|
324
|
+
*/
|
|
325
|
+
export const Resource = OtelResource.Resource
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observability for flows: the default OTLP export wiring plus the
|
|
3
|
+
* Effect-native logger, metric, and OpenTelemetry resource layers.
|
|
4
|
+
*
|
|
5
|
+
* The store packages define and update their own metric handles
|
|
6
|
+
* (`JournalMetrics`, `RunStoreMetrics`, `CacheStoreMetrics`,
|
|
7
|
+
* `ArtifactStoreMetrics`, `DatabaseMetrics`) and open spans through Effect's
|
|
8
|
+
* tracer; this package is the exporter they deliberately leave out. `Otlp`
|
|
9
|
+
* only composes what `effect` already ships, so it is browser-bundleable. The
|
|
10
|
+
* remaining modules are the fuller stack folded in from the agent workspace:
|
|
11
|
+
* a structured `Logger`, a `JournalLogger` that mirrors log events into the
|
|
12
|
+
* run journal, `Metric` helpers, the `Resource` descriptor, and the `Otel`
|
|
13
|
+
* layer the OpenTelemetry SDK wiring installs behind.
|
|
14
|
+
*
|
|
15
|
+
* `NodeOtel` and `BrowserOtel` are deliberately NOT re-exported here. Each
|
|
16
|
+
* resolves a host-specific OpenTelemetry SDK. `NodeOtel` reaches Node-only
|
|
17
|
+
* host modules through `@effect/opentelemetry/NodeSdk` and
|
|
18
|
+
* `@opentelemetry/sdk-trace-node`, including the bare `async_hooks` specifier
|
|
19
|
+
* `@opentelemetry/context-async-hooks` imports, so re-exporting it would put a
|
|
20
|
+
* module a browser bundler cannot resolve in the root entry and break the
|
|
21
|
+
* browser bundle this package guarantees. Import them by subpath instead:
|
|
22
|
+
* `@smthrs/observability/NodeOtel`.
|
|
23
|
+
*
|
|
24
|
+
* @since 0.1.0
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @category layers
|
|
29
|
+
* @since 0.1.0
|
|
30
|
+
*/
|
|
31
|
+
export * as Otlp from "./Otlp.ts"
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @category observability
|
|
35
|
+
* @since 1.0.0-rc.0
|
|
36
|
+
*/
|
|
37
|
+
export * as Endpoint from "./Endpoint.ts"
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @category observability
|
|
41
|
+
* @since 0.1.0
|
|
42
|
+
*/
|
|
43
|
+
export * as JournalLogger from "./JournalLogger.ts"
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @category observability
|
|
47
|
+
* @since 0.1.0
|
|
48
|
+
*/
|
|
49
|
+
export * as Logger from "./Logger.ts"
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @category observability
|
|
53
|
+
* @since 0.1.0
|
|
54
|
+
*/
|
|
55
|
+
export * as Metric from "./Metric.ts"
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @category observability
|
|
59
|
+
* @since 0.1.0
|
|
60
|
+
*/
|
|
61
|
+
export * as Otel from "./Otel.ts"
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @category observability
|
|
65
|
+
* @since 0.1.0
|
|
66
|
+
*/
|
|
67
|
+
export * as Resource from "./Resource.ts"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The decoder-issue walk shared by this package's refusals.
|
|
3
|
+
*
|
|
4
|
+
* `JournalLogger` and `Resource` both publish the path of the option a decode
|
|
5
|
+
* rejected, and `Resource` also publishes the measured size a budget filter
|
|
6
|
+
* attached to its refusal. Effect's issues nest the same way for both, so the
|
|
7
|
+
* traversal lives once and a decoder change is followed once.
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
* @since 1.0.0-rc.0
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
interface IssueLeaf {
|
|
14
|
+
readonly segments: ReadonlyArray<string>
|
|
15
|
+
readonly leaf: unknown
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Walks a decode failure to its first offending leaf, collecting the path
|
|
20
|
+
* segments passed on the way. The walk is bounded so a self-referential issue
|
|
21
|
+
* tree cannot spin.
|
|
22
|
+
*/
|
|
23
|
+
const walk = (error: unknown): IssueLeaf => {
|
|
24
|
+
let issue = (error as { readonly issue?: unknown } | null)?.issue
|
|
25
|
+
const segments: Array<string> = []
|
|
26
|
+
for (let depth = 0; depth < 64 && typeof issue === "object" && issue !== null; depth++) {
|
|
27
|
+
const node = issue as { readonly path?: unknown; readonly issue?: unknown; readonly issues?: unknown }
|
|
28
|
+
if (Array.isArray(node.path)) segments.push(...node.path.map(String))
|
|
29
|
+
if (node.issue !== undefined) {
|
|
30
|
+
issue = node.issue
|
|
31
|
+
continue
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(node.issues) && node.issues[0] !== undefined) {
|
|
34
|
+
issue = node.issues[0]
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
break
|
|
38
|
+
}
|
|
39
|
+
return { segments, leaf: issue }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Walks a decode failure to the dotted path of the value it refused.
|
|
44
|
+
*
|
|
45
|
+
* Returns the caller's domain name when the failure carries no path at all.
|
|
46
|
+
*
|
|
47
|
+
* @private
|
|
48
|
+
* @since 1.0.0-rc.0
|
|
49
|
+
*/
|
|
50
|
+
export const schemaIssuePath = (error: unknown, fallback: string): string => walk(error).segments.join(".") || fallback
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Reads the message a filter attached to the value a decode refused, when the
|
|
54
|
+
* filter attached one. None of the Effect checks this package composes attach
|
|
55
|
+
* one, so a refusal only ever carries text this package wrote, never the
|
|
56
|
+
* rejected value.
|
|
57
|
+
*
|
|
58
|
+
* @private
|
|
59
|
+
* @since 1.0.0-rc.0
|
|
60
|
+
*/
|
|
61
|
+
export const schemaIssueMessage = (error: unknown): string | undefined => {
|
|
62
|
+
const leaf = walk(error).leaf as { readonly annotations?: { readonly message?: unknown } } | null | undefined
|
|
63
|
+
const message = leaf?.annotations?.message
|
|
64
|
+
return typeof message === "string" ? message : undefined
|
|
65
|
+
}
|
package/docker-compose.otel.yml
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
version: "3.9"
|
|
2
|
-
|
|
3
|
-
services:
|
|
4
|
-
otel-collector:
|
|
5
|
-
image: otel/opentelemetry-collector-contrib:0.148.0
|
|
6
|
-
restart: unless-stopped
|
|
7
|
-
command: ["--config", "/etc/otelcol/config.yml"]
|
|
8
|
-
volumes:
|
|
9
|
-
- ./otel-collector-config.yml:/etc/otelcol/config.yml:ro
|
|
10
|
-
ports:
|
|
11
|
-
- "4317:4317" # gRPC
|
|
12
|
-
- "4318:4318" # HTTP (Smithers sends here)
|
|
13
|
-
- "8889:8889" # Prometheus exporter scrape endpoint
|
|
14
|
-
depends_on:
|
|
15
|
-
tempo:
|
|
16
|
-
condition: service_healthy
|
|
17
|
-
loki:
|
|
18
|
-
condition: service_healthy
|
|
19
|
-
healthcheck:
|
|
20
|
-
test: ["CMD", "/otelcol-contrib", "--version"]
|
|
21
|
-
interval: 10s
|
|
22
|
-
timeout: 5s
|
|
23
|
-
retries: 12
|
|
24
|
-
start_period: 10s
|
|
25
|
-
|
|
26
|
-
loki:
|
|
27
|
-
image: grafana/loki:3.3.2
|
|
28
|
-
restart: unless-stopped
|
|
29
|
-
command: ["-config.file=/etc/loki/local-config.yaml"]
|
|
30
|
-
volumes:
|
|
31
|
-
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml:ro
|
|
32
|
-
- ./data/loki:/loki
|
|
33
|
-
ports:
|
|
34
|
-
- "3100:3100"
|
|
35
|
-
healthcheck:
|
|
36
|
-
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1:3100/ready"]
|
|
37
|
-
interval: 10s
|
|
38
|
-
timeout: 5s
|
|
39
|
-
retries: 18
|
|
40
|
-
start_period: 10s
|
|
41
|
-
|
|
42
|
-
prometheus:
|
|
43
|
-
image: prom/prometheus:v3.2.0
|
|
44
|
-
restart: unless-stopped
|
|
45
|
-
volumes:
|
|
46
|
-
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
|
47
|
-
- ./data/prometheus:/prometheus
|
|
48
|
-
ports:
|
|
49
|
-
- "9090:9090"
|
|
50
|
-
depends_on:
|
|
51
|
-
otel-collector:
|
|
52
|
-
condition: service_healthy
|
|
53
|
-
healthcheck:
|
|
54
|
-
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1:9090/-/ready"]
|
|
55
|
-
interval: 10s
|
|
56
|
-
timeout: 5s
|
|
57
|
-
retries: 18
|
|
58
|
-
start_period: 10s
|
|
59
|
-
|
|
60
|
-
tempo:
|
|
61
|
-
image: grafana/tempo:2.7.0
|
|
62
|
-
restart: unless-stopped
|
|
63
|
-
command: ["-config.file=/etc/tempo/tempo.yml"]
|
|
64
|
-
volumes:
|
|
65
|
-
- ./tempo/tempo.yml:/etc/tempo/tempo.yml:ro
|
|
66
|
-
- ./data/tempo:/tmp/tempo
|
|
67
|
-
ports:
|
|
68
|
-
- "3200:3200" # Tempo query API
|
|
69
|
-
- "4317" # OTLP gRPC (internal)
|
|
70
|
-
healthcheck:
|
|
71
|
-
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1:3200/api/search"]
|
|
72
|
-
interval: 10s
|
|
73
|
-
timeout: 5s
|
|
74
|
-
retries: 24
|
|
75
|
-
start_period: 20s
|
|
76
|
-
|
|
77
|
-
grafana:
|
|
78
|
-
image: grafana/grafana:11.5.0
|
|
79
|
-
restart: unless-stopped
|
|
80
|
-
environment:
|
|
81
|
-
# Local dev default is "admin"; override via env for anything shared.
|
|
82
|
-
- GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD:-admin}
|
|
83
|
-
# Anonymous browsing stays on for frictionless local dev, but read-only.
|
|
84
|
-
- GF_AUTH_ANONYMOUS_ENABLED=${GF_AUTH_ANONYMOUS_ENABLED:-true}
|
|
85
|
-
- GF_AUTH_ANONYMOUS_ORG_ROLE=${GF_AUTH_ANONYMOUS_ORG_ROLE:-Viewer}
|
|
86
|
-
volumes:
|
|
87
|
-
- ./grafana/provisioning:/etc/grafana/provisioning:ro
|
|
88
|
-
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
|
|
89
|
-
- ./data/grafana:/var/lib/grafana
|
|
90
|
-
ports:
|
|
91
|
-
- "3001:3000"
|
|
92
|
-
depends_on:
|
|
93
|
-
prometheus:
|
|
94
|
-
condition: service_healthy
|
|
95
|
-
tempo:
|
|
96
|
-
condition: service_healthy
|
|
97
|
-
loki:
|
|
98
|
-
condition: service_healthy
|
|
99
|
-
healthcheck:
|
|
100
|
-
test: ["CMD", "wget", "-q", "-O-", "http://127.0.0.1:3000/api/health"]
|
|
101
|
-
interval: 10s
|
|
102
|
-
timeout: 5s
|
|
103
|
-
retries: 24
|
|
104
|
-
start_period: 20s
|