@@ -6,17 +6,27 @@ import { assert, describe, expect, it } from "@effect/vitest"
66import * as OtelApi from "@opentelemetry/api"
77import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks"
88import { InMemorySpanExporter , SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base"
9+ import * as Console from "effect/Console"
910import * as Effect from "effect/Effect"
11+ import * as FiberRef from "effect/FiberRef"
1012import * as Layer from "effect/Layer"
1113import * as Runtime from "effect/Runtime"
1214import { OtelSpan } from "../src/internal/tracer.js"
1315
14- const TracingLive = NodeSdk . layer ( Effect . sync ( ( ) => ( {
15- resource : {
16- serviceName : "test"
17- } ,
18- spanProcessor : [ new SimpleSpanProcessor ( new InMemorySpanExporter ( ) ) ]
19- } ) ) )
16+ class Exporter extends Effect . Service < Exporter > ( ) ( "Exporter" , {
17+ effect : Effect . sync ( ( ) => ( { exporter : new InMemorySpanExporter ( ) } ) )
18+ } ) { }
19+
20+ const TracingLive = Layer . unwrapEffect ( Effect . gen ( function * ( ) {
21+ const { exporter } = yield * Exporter
22+
23+ return NodeSdk . layer ( Effect . sync ( ( ) => ( {
24+ resource : {
25+ serviceName : "test"
26+ } ,
27+ spanProcessor : [ new SimpleSpanProcessor ( exporter ) ]
28+ } ) ) )
29+ } ) ) . pipe ( Layer . provideMerge ( Exporter . Default ) )
2030
2131// needed to test context propagation
2232const contextManager = new AsyncHooksContextManager ( )
@@ -160,4 +170,59 @@ describe("Tracer", () => {
160170 OtlpTracingLive
161171 ) )
162172 } )
173+
174+ describe ( "Log Attributes" , ( ) => {
175+ it . effect ( "propagates attributes with Effect.fnUntraced" , ( ) =>
176+ Effect . gen ( function * ( ) {
177+ const f = Effect . fnUntraced ( function * ( ) {
178+ yield * Effect . logWarning ( "FooBar" )
179+ return yield * Effect . fail ( "Oops" )
180+ } )
181+
182+ const p = f ( ) . pipe ( Effect . withSpan ( "p" ) )
183+
184+ yield * Effect . ignore ( p )
185+
186+ const { exporter } = yield * Exporter
187+
188+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "FooBar" ) )
189+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "exception" ) )
190+ } ) . pipe ( Effect . provide ( TracingLive ) ) )
191+
192+ it . effect ( "propagates attributes with Effect.fn(name)" , ( ) =>
193+ Effect . gen ( function * ( ) {
194+ const f = Effect . fn ( "f" ) ( function * ( ) {
195+ yield * Effect . logWarning ( "FooBar" )
196+ return yield * Effect . fail ( "Oops" )
197+ } )
198+
199+ const p = f ( ) . pipe ( Effect . withSpan ( "p" ) )
200+
201+ yield * Effect . ignore ( p )
202+
203+ const { exporter } = yield * Exporter
204+
205+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "FooBar" ) )
206+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "exception" ) )
207+ } ) . pipe ( Effect . provide ( TracingLive ) ) )
208+
209+ it . effect ( "propagates attributes with Effect.fn" , ( ) =>
210+ Effect . gen ( function * ( ) {
211+ const f = Effect . fn ( function * ( ) {
212+ yield * Effect . logWarning ( "FooBar" )
213+ return yield * Effect . fail ( "Oops" )
214+ } )
215+
216+ const p = f ( ) . pipe ( Effect . withSpan ( "p" ) )
217+
218+ yield * Effect . ignore ( p )
219+
220+ const { exporter } = yield * Exporter
221+
222+ yield * Console . log ( Array . from ( yield * FiberRef . get ( FiberRef . currentLoggers ) ) )
223+
224+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "FooBar" ) )
225+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "exception" ) )
226+ } ) . pipe ( Effect . provide ( TracingLive ) ) )
227+ } )
163228} )
0 commit comments