diff --git a/packages/@contentlayer/utils/package.json b/packages/@contentlayer/utils/package.json index 849dedb1..d219628a 100644 --- a/packages/@contentlayer/utils/package.json +++ b/packages/@contentlayer/utils/package.json @@ -59,7 +59,6 @@ "dependencies": { "@effect-ts/core": "^0.60.5", "@effect-ts/otel": "^0.15.1", - "@effect-ts/otel-exporter-trace-otlp-grpc": "^0.15.1", "@effect-ts/otel-sdk-trace-node": "^0.15.1", "@js-temporal/polyfill": "^0.4.4", "@opentelemetry/api": "^1.8.0", diff --git a/packages/@contentlayer/utils/src/tracing-effect/index.ts b/packages/@contentlayer/utils/src/tracing-effect/index.ts index 5fdc1220..bde2b885 100644 --- a/packages/@contentlayer/utils/src/tracing-effect/index.ts +++ b/packages/@contentlayer/utils/src/tracing-effect/index.ts @@ -3,7 +3,7 @@ import type { Clock } from '@effect-ts/core/Effect/Clock' import type * as L from '@effect-ts/core/Effect/Layer' import type { Has } from '@effect-ts/core/Has' import * as OT from '@effect-ts/otel' -import { LiveSimpleProcessor, makeOTLPTraceExporterConfigLayer } from '@effect-ts/otel-exporter-trace-otlp-grpc' +import { LiveSimpleProcessor, makeOTLPTraceExporterConfigLayer } from './otel-exporter-trace-otlp-grpc.js' import * as OTNode from '@effect-ts/otel-sdk-trace-node' import { Resource } from '@opentelemetry/resources' import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions' diff --git a/packages/@contentlayer/utils/src/tracing-effect/otel-exporter-trace-otlp-grpc.ts b/packages/@contentlayer/utils/src/tracing-effect/otel-exporter-trace-otlp-grpc.ts new file mode 100644 index 00000000..8a1a9457 --- /dev/null +++ b/packages/@contentlayer/utils/src/tracing-effect/otel-exporter-trace-otlp-grpc.ts @@ -0,0 +1,60 @@ +// Inline to avoid peer dependency issues +// https://github.com/Effect-Deprecated/otel/blob/ee7aa57e42e1bcdf9af98815bc601279f54e26ec/packages/otel-exporter-trace-otlp-grpc/src/index.ts +import * as T from '@effect-ts/core/Effect' +import * as L from '@effect-ts/core/Effect/Layer' +import * as M from '@effect-ts/core/Effect/Managed' +import { pipe } from '@effect-ts/core/Function' +import { tag } from '@effect-ts/core/Has' +import { SimpleProcessor } from '@effect-ts/otel' +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc' +import type { OTLPGRPCExporterConfigNode } from '@opentelemetry/otlp-grpc-exporter-base' + +export const OTLPTraceExporterConfigSymbol = Symbol() + +export class OTLPTraceExporterConfig { + readonly [OTLPTraceExporterConfigSymbol] = OTLPTraceExporterConfigSymbol + constructor(readonly config: OTLPGRPCExporterConfigNode) {} +} + +export const OTLPTraceExporterConfigTag = tag(OTLPTraceExporterConfigSymbol) + +export const makeOTLPTraceExporterConfigLayer = (config: OTLPGRPCExporterConfigNode) => + L.fromEffect(OTLPTraceExporterConfigTag)(T.succeedWith(() => new OTLPTraceExporterConfig(config))).setKey( + OTLPTraceExporterConfigTag.key, + ) + +export const makeOTLPTraceExporterConfigLayerM = (config: T.Effect) => + L.fromEffect(OTLPTraceExporterConfigTag)(T.map_(config, (_) => new OTLPTraceExporterConfig(_))).setKey( + OTLPTraceExporterConfigTag.key, + ) + +export const makeTracingSpanExporter = M.gen(function* (_) { + const { config } = yield* _(OTLPTraceExporterConfigTag) + + const spanExporter = yield* _( + pipe( + T.succeedWith(() => new OTLPTraceExporter(config)), + // NOTE Unfortunately this workaround/"hack" is currently needed since Otel doesn't yet provide a graceful + // way to shutdown. + // + // Related issue: https://github.com/open-telemetry/opentelemetry-js/issues/987 + M.make((p) => + T.gen(function* (_) { + while (1) { + yield* _(T.sleep(0)) + const promises = p['_sendingPromises'] as any[] + if (promises.length > 0) { + yield* _(T.result(T.promise(() => Promise.all(promises)))) + } else { + break + } + } + }), + ), + ), + ) + + return spanExporter +}) + +export const LiveSimpleProcessor = SimpleProcessor(makeTracingSpanExporter) diff --git a/yarn.lock b/yarn.lock index d26c6b96..7e5bafdb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -438,7 +438,6 @@ __metadata: dependencies: "@effect-ts/core": ^0.60.5 "@effect-ts/otel": ^0.15.1 - "@effect-ts/otel-exporter-trace-otlp-grpc": ^0.15.1 "@effect-ts/otel-sdk-trace-node": ^0.15.1 "@js-temporal/polyfill": ^0.4.4 "@opentelemetry/api": ^1.8.0 @@ -484,21 +483,6 @@ __metadata: languageName: node linkType: hard -"@effect-ts/otel-exporter-trace-otlp-grpc@npm:^0.15.1": - version: 0.15.1 - resolution: "@effect-ts/otel-exporter-trace-otlp-grpc@npm:0.15.1" - dependencies: - "@effect-ts/otel": ^0.15.1 - peerDependencies: - "@effect-ts/core": ^0.60.2 - "@opentelemetry/api": ^1.4.0 - "@opentelemetry/core": ^1.13.0 - "@opentelemetry/exporter-trace-otlp-grpc": ^0.39.0 - "@opentelemetry/sdk-trace-base": ^1.13.0 - checksum: 5f81693c725f9bdf515374752437c0d20d65b123ca2235ba9cedf477308e43c115edb8b8b4934e19d8e89f52307d5001efe6299e4ca43734459fc37aab9bad30 - languageName: node - linkType: hard - "@effect-ts/otel-sdk-trace-node@npm:^0.15.1": version: 0.15.1 resolution: "@effect-ts/otel-sdk-trace-node@npm:0.15.1"