@@ -4,16 +4,27 @@ import { assert, describe, expect, it } from "@effect/vitest"
44import * as OtelApi from "@opentelemetry/api"
55import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks"
66import { InMemorySpanExporter , SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base"
7+ import * as Console from "effect/Console"
78import * as Effect from "effect/Effect"
9+ import * as FiberRef from "effect/FiberRef"
10+ import * as Layer from "effect/Layer"
811import * as Runtime from "effect/Runtime"
912import { OtelSpan } from "../src/internal/tracer.js"
1013
11- const TracingLive = NodeSdk . layer ( Effect . sync ( ( ) => ( {
12- resource : {
13- serviceName : "test"
14- } ,
15- spanProcessor : [ new SimpleSpanProcessor ( new InMemorySpanExporter ( ) ) ]
16- } ) ) )
14+ class Exporter extends Effect . Service < Exporter > ( ) ( "Exporter" , {
15+ effect : Effect . sync ( ( ) => ( { exporter : new InMemorySpanExporter ( ) } ) )
16+ } ) { }
17+
18+ const TracingLive = Layer . unwrapEffect ( Effect . gen ( function * ( ) {
19+ const { exporter } = yield * Exporter
20+
21+ return NodeSdk . layer ( Effect . sync ( ( ) => ( {
22+ resource : {
23+ serviceName : "test"
24+ } ,
25+ spanProcessor : [ new SimpleSpanProcessor ( exporter ) ]
26+ } ) ) )
27+ } ) ) . pipe ( Layer . provideMerge ( Exporter . Default ) )
1728
1829// needed to test context propagation
1930const contextManager = new AsyncHooksContextManager ( )
@@ -123,4 +134,59 @@ describe("Tracer", () => {
123134 } )
124135 ) )
125136 } )
137+
138+ describe ( "Log Attributes" , ( ) => {
139+ it . effect ( "propagates attributes with Effect.fnUntraced" , ( ) =>
140+ Effect . gen ( function * ( ) {
141+ const f = Effect . fnUntraced ( function * ( ) {
142+ yield * Effect . logWarning ( "FooBar" )
143+ return yield * Effect . fail ( "Oops" )
144+ } )
145+
146+ const p = f ( ) . pipe ( Effect . withSpan ( "p" ) )
147+
148+ yield * Effect . ignore ( p )
149+
150+ const { exporter } = yield * Exporter
151+
152+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "FooBar" ) )
153+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "exception" ) )
154+ } ) . pipe ( Effect . provide ( TracingLive ) ) )
155+
156+ it . effect ( "propagates attributes with Effect.fn(name)" , ( ) =>
157+ Effect . gen ( function * ( ) {
158+ const f = Effect . fn ( "f" ) ( function * ( ) {
159+ yield * Effect . logWarning ( "FooBar" )
160+ return yield * Effect . fail ( "Oops" )
161+ } )
162+
163+ const p = f ( ) . pipe ( Effect . withSpan ( "p" ) )
164+
165+ yield * Effect . ignore ( p )
166+
167+ const { exporter } = yield * Exporter
168+
169+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "FooBar" ) )
170+ assert . isNotEmpty ( exporter . getFinishedSpans ( ) [ 0 ] . events . filter ( ( _ ) => _ . name === "exception" ) )
171+ } ) . pipe ( Effect . provide ( TracingLive ) ) )
172+
173+ it . effect ( "propagates attributes with Effect.fn" , ( ) =>
174+ Effect . gen ( function * ( ) {
175+ const f = Effect . fn ( function * ( ) {
176+ yield * Effect . logWarning ( "FooBar" )
177+ return yield * Effect . fail ( "Oops" )
178+ } )
179+
180+ const p = f ( ) . pipe ( Effect . withSpan ( "p" ) )
181+
182+ yield * Effect . ignore ( p )
183+
184+ const { exporter } = yield * Exporter
185+
186+ yield * Console . log ( Array . from ( yield * FiberRef . get ( FiberRef . currentLoggers ) ) )
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+ } )
126192} )
0 commit comments