import { Effect, Layer, References, Tracer } from "effect";import { OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability"; import { ServerConfig } from "../../config.ts";import { ServerLoggerLive } from "../../serverLogger.ts";import { makeLocalFileTracer } from "../LocalFileTracer.ts";import { BrowserTraceCollector } from "../Services/BrowserTraceCollector.ts";import { makeTraceSink } from "../TraceSink.ts"; const otlpSerializationLayer = OtlpSerialization.layerJson; export const ObservabilityLive = Layer.unwrap( Effect.gen(function* () { const config = yield* ServerConfig; const traceReferencesLayer = Layer.mergeAll( Layer.succeed(Tracer.MinimumTraceLevel, config.traceMinLevel), Layer.succeed(References.TracerTimingEnabled, config.traceTimingEnabled), ); const tracerLayer = Layer.unwrap( Effect.gen(function* () { const sink = yield* makeTraceSink({ filePath: config.serverTracePath, maxBytes: config.traceMaxBytes, maxFiles: config.traceMaxFiles, batchWindowMs: config.traceBatchWindowMs, }); const delegate = config.otlpTracesUrl === undefined ? undefined : yield* OtlpTracer.make({ url: config.otlpTracesUrl, exportInterval: `${config.otlpExportIntervalMs} millis`, resource: { serviceName: config.otlpServiceName, attributes: { "service.runtime": "t3-server", "service.mode": config.mode, }, }, }); const tracer = yield* makeLocalFileTracer({ filePath: config.serverTracePath, maxBytes: config.traceMaxBytes, maxFiles: config.traceMaxFiles, batchWindowMs: config.traceBatchWindowMs, sink, ...(delegate ? { delegate } : {}), }); return Layer.mergeAll( Layer.succeed(Tracer.Tracer, tracer), Layer.succeed(BrowserTraceCollector, { record: (records) => Effect.sync(() => { for (const record of records) { sink.push(record); } }), }), ); }), ).pipe(Layer.provideMerge(otlpSerializationLayer)); const metricsLayer = config.otlpMetricsUrl === undefined ? Layer.empty : OtlpMetrics.layer({ url: config.otlpMetricsUrl, exportInterval: `${config.otlpExportIntervalMs} millis`, resource: { serviceName: config.otlpServiceName, attributes: { "service.runtime": "t3-server", "service.mode": config.mode, }, }, }).pipe(Layer.provideMerge(otlpSerializationLayer)); return Layer.mergeAll(ServerLoggerLive, traceReferencesLayer, tracerLayer, metricsLayer); }),);
import { Effect, Layer, References, Tracer } from "effect";
import { OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
import { ServerConfig } from "../../config.ts";
import { ServerLoggerLive } from "../../serverLogger.ts";
import { makeLocalFileTracer } from "../LocalFileTracer.ts";
import { BrowserTraceCollector } from "../Services/BrowserTraceCollector.ts";
import { makeTraceSink } from "../TraceSink.ts";
const otlpSerializationLayer = OtlpSerialization.layerJson;
export const ObservabilityLive = Layer.unwrap(
Effect.gen(function* () {
const config = yield* ServerConfig;
const traceReferencesLayer = Layer.mergeAll(
Layer.succeed(Tracer.MinimumTraceLevel, config.traceMinLevel),
Layer.succeed(References.TracerTimingEnabled, config.traceTimingEnabled),
);
const tracerLayer = Layer.unwrap(
Effect.gen(function* () {
const sink = yield* makeTraceSink({
filePath: config.serverTracePath,
maxBytes: config.traceMaxBytes,
maxFiles: config.traceMaxFiles,
batchWindowMs: config.traceBatchWindowMs,
});
const delegate =
config.otlpTracesUrl === undefined
? undefined
: yield* OtlpTracer.make({
url: config.otlpTracesUrl,
exportInterval: `${config.otlpExportIntervalMs} millis`,
resource: {
serviceName: config.otlpServiceName,
attributes: {
"service.runtime": "t3-server",
"service.mode": config.mode,
},
},
});
const tracer = yield* makeLocalFileTracer({
filePath: config.serverTracePath,
maxBytes: config.traceMaxBytes,
maxFiles: config.traceMaxFiles,
batchWindowMs: config.traceBatchWindowMs,
sink,
...(delegate ? { delegate } : {}),
});
return Layer.mergeAll(
Layer.succeed(Tracer.Tracer, tracer),
Layer.succeed(BrowserTraceCollector, {
record: (records) =>
Effect.sync(() => {
for (const record of records) {
sink.push(record);
}
}),
}),
);
}),
).pipe(Layer.provideMerge(otlpSerializationLayer));
const metricsLayer =
config.otlpMetricsUrl === undefined
? Layer.empty
: OtlpMetrics.layer({
url: config.otlpMetricsUrl,
exportInterval: `${config.otlpExportIntervalMs} millis`,
resource: {
serviceName: config.otlpServiceName,
attributes: {
"service.runtime": "t3-server",
"service.mode": config.mode,
},
},
}).pipe(Layer.provideMerge(otlpSerializationLayer));
return Layer.mergeAll(ServerLoggerLive, traceReferencesLayer, tracerLayer, metricsLayer);
}),
);