Skip to content

Commit

Permalink
add fiber ref for disabling the tracer (#2381)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart authored Mar 21, 2024
1 parent 6fbac51 commit 37ca592
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 11 deletions.
17 changes: 17 additions & 0 deletions .changeset/hip-bags-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"effect": patch
---

add fiber ref for disabling the tracer

You can use it with the Effect.withTracerEnabled api:

```ts
import { Effect } from "effect";

Effect.succeed(42).pipe(
Effect.withSpan("my-span"),
// the span will not be registered with the tracer
Effect.withTracerEnabled(false),
);
```
19 changes: 19 additions & 0 deletions packages/effect/src/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5061,6 +5061,25 @@ export const withTracer: {
export const withTracerScoped: (value: Tracer.Tracer) => Effect<void, never, Scope.Scope> =
fiberRuntime.withTracerScoped

/**
* Disable the tracer for the given Effect.
*
* @since 2.0.0
* @category tracing
* @example
* import { Effect } from "effect"
*
* Effect.succeed(42).pipe(
* Effect.withSpan("my-span"),
* // the span will not be registered with the tracer
* Effect.withTracerEnabled(false)
* )
*/
export const withTracerEnabled: {
(enabled: boolean): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>
<A, E, R>(effect: Effect<A, E, R>, enabled: boolean): Effect<A, E, R>
} = core.withTracerEnabled

/**
* @since 2.0.0
* @category tracing
Expand Down
6 changes: 6 additions & 0 deletions packages/effect/src/FiberRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,12 @@ export const currentSupervisor: FiberRef<Supervisor.Supervisor<any>> = fiberRunt
*/
export const currentMetricLabels: FiberRef<ReadonlyArray<MetricLabel.MetricLabel>> = core.currentMetricLabels

/**
* @since 2.0.0
* @category fiberRefs
*/
export const currentTracerEnabled: FiberRef<boolean> = core.currentTracerEnabled

/**
* @since 2.0.0
* @category fiberRefs
Expand Down
9 changes: 9 additions & 0 deletions packages/effect/src/Layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,15 @@ export const span: (
*/
export const setTracer: (tracer: Tracer.Tracer) => Layer<never> = circularLayer.setTracer

/**
* @since 2.0.0
* @category tracing
*/
export const setTracerEnabled: (enabled: boolean) => Layer<never> = (enabled: boolean) =>
scopedDiscard(
fiberRuntime.fiberRefLocallyScoped(core.currentTracerEnabled, enabled)
)

/**
* @since 2.0.0
* @category tracing
Expand Down
15 changes: 11 additions & 4 deletions packages/effect/src/internal/core-effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2051,6 +2051,11 @@ export const makeSpan = (
): Effect.Effect<Tracer.Span> =>
core.flatMap(fiberRefs, (fiberRefs) =>
core.sync(() => {
const enabled = FiberRefs.getOrDefault(fiberRefs, core.currentTracerEnabled)
if (enabled === false) {
return core.noopSpan
}

const context = FiberRefs.getOrDefault(fiberRefs, core.currentContext)
const services = FiberRefs.getOrDefault(fiberRefs, defaultServices.currentServices)

Expand Down Expand Up @@ -2131,10 +2136,12 @@ export const useSpan: {
makeSpan(name, options),
evaluate,
(span, exit) =>
core.flatMap(
currentTimeNanosTracing,
(endTime) => core.sync(() => span.end(endTime, exit))
)
span.status._tag === "Ended" ?
core.unit :
core.flatMap(
currentTimeNanosTracing,
(endTime) => core.sync(() => span.end(endTime, exit))
)
)
}

Expand Down
39 changes: 39 additions & 0 deletions packages/effect/src/internal/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,17 @@ export const withRuntimeFlags = dual<
return effect
})

/** @internal */
export const withTracerEnabled = dual<
(enabled: boolean) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
<A, E, R>(effect: Effect.Effect<A, E, R>, enabled: boolean) => Effect.Effect<A, E, R>
>(2, (effect, enabled) =>
fiberRefLocally(
effect,
currentTracerEnabled,
enabled
))

/** @internal */
export const withTracerTiming = dual<
(enabled: boolean) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
Expand Down Expand Up @@ -2015,6 +2026,12 @@ export const currentInterruptedCause: FiberRef.FiberRef<Cause.Cause<never>> = gl
})
)

/** @internal */
export const currentTracerEnabled: FiberRef.FiberRef<boolean> = globalValue(
Symbol.for("effect/FiberRef/currentTracerEnabled"),
() => fiberRefUnsafeMake(true)
)

/** @internal */
export const currentTracerTimingEnabled: FiberRef.FiberRef<boolean> = globalValue(
Symbol.for("effect/FiberRef/currentTracerTiming"),
Expand Down Expand Up @@ -3073,3 +3090,25 @@ export const currentSpanFromFiber = <A, E>(fiber: Fiber.RuntimeFiber<A, E>): Opt
| undefined
return span !== undefined && span._tag === "Span" ? Option.some(span) : Option.none()
}

/** @internal */
export const noopSpan: Tracer.Span = globalValue("effect/Tracer/noopSpan", () => ({
_tag: "Span",
spanId: "noop",
traceId: "noop",
name: "noop",
sampled: false,
parent: Option.none(),
context: Context.empty(),
status: {
_tag: "Ended",
startTime: BigInt(0),
endTime: BigInt(0),
exit: exitUnit
},
attributes: new Map(),
links: [],
attribute() {},
event() {},
end() {}
}))
10 changes: 6 additions & 4 deletions packages/effect/src/internal/fiberRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3505,10 +3505,12 @@ export const makeSpanScoped = (
acquireRelease(
internalEffect.makeSpan(name, options),
(span, exit) =>
core.flatMap(
internalEffect.currentTimeNanosTracing,
(endTime) => core.sync(() => span.end(endTime, exit))
)
span.status._tag === "Ended" ?
core.unit :
core.flatMap(
internalEffect.currentTimeNanosTracing,
(endTime) => core.sync(() => span.end(endTime, exit))
)
)

/* @internal */
Expand Down
6 changes: 3 additions & 3 deletions packages/effect/src/internal/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class NativeSpan implements Tracer.Span {
this.spanId = `span${randomString(16)}`
}

end = (endTime: bigint, exit: Exit.Exit<unknown, unknown>): void => {
end(endTime: bigint, exit: Exit.Exit<unknown, unknown>): void {
this.status = {
_tag: "Ended",
endTime,
Expand All @@ -68,11 +68,11 @@ export class NativeSpan implements Tracer.Span {
}
}

attribute = (key: string, value: unknown): void => {
attribute(key: string, value: unknown): void {
this.attributes.set(key, value)
}

event = (name: string, startTime: bigint, attributes?: Record<string, unknown>): void => {
event(name: string, startTime: bigint, attributes?: Record<string, unknown>): void {
this.events.push([name, startTime, attributes ?? {}])
}
}
Expand Down
17 changes: 17 additions & 0 deletions packages/effect/test/Tracer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,21 @@ describe("Tracer", () => {
assert.strictEqual(onEndCalled, true)
}))
})

it.effect("withTracerEnabled", () =>
Effect.gen(function*($) {
const span = yield* $(
Effect.currentSpan,
Effect.withSpan("A"),
Effect.withTracerEnabled(false)
)
const spanB = yield* $(
Effect.currentSpan,
Effect.withSpan("B"),
Effect.withTracerEnabled(true)
)

assert.deepEqual(span.name, "noop")
assert.deepEqual(spanB.name, "B")
}))
})

0 comments on commit 37ca592

Please sign in to comment.