SpanA span created by an Effect tracer. It carries trace identity, parent, annotations, attributes, links, sampling and kind information, lifecycle status, and methods to end the span or add attributes, events, and links.
Example (Working with spans)
import { Context, Exit, Option } from "effect"
import type { Tracer } from "effect"
const attributes = new Map<string, unknown>()
const links: Array<Tracer.SpanLink> = []
let status: Tracer.SpanStatus = {
_tag: "Started",
startTime: 1_000_000_000n
}
const span: Tracer.Span = {
_tag: "Span",
name: "load-user",
spanId: "span-1",
traceId: "trace-1",
parent: Option.none(),
annotations: Context.empty(),
get status() {
return status
},
attributes,
links,
sampled: true,
kind: "internal",
end(endTime, exit) {
status = { _tag: "Ended", startTime: status.startTime, endTime, exit }
},
attribute(key, value) {
attributes.set(key, value)
},
event(name, startTime, eventAttributes = {}) {
console.log(`${name} at ${startTime} with ${Object.keys(eventAttributes).length} attributes`)
},
addLinks(newLinks) {
links.push(...newLinks)
}
}
span.attribute("user.id", "123")
span.end(1_500_000_000n, Exit.succeed("user"))
console.log(span.name) // "load-user"
console.log(span.attributes.get("user.id")) // "123"
console.log(span.status._tag) // "Ended"export interface Span {
readonly Span._tag: "Span"_tag: "Span"
readonly Span.name: stringname: string
readonly Span.spanId: stringspanId: string
readonly Span.traceId: stringtraceId: string
readonly Span.parent: Option.Option<AnySpan>parent: import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<type AnySpan = Span | ExternalSpanA span value that can participate in tracing, either an Effect-managed
Span or an ExternalSpan propagated from another tracing system.
Example (Accepting any span)
import { Effect, Tracer } from "effect"
// Function that accepts any span type
const logSpan = (span: Tracer.AnySpan) => {
console.log(`Span ID: ${span.spanId}, Trace ID: ${span.traceId}`)
return Effect.succeed(span)
}
// Works with both Span and ExternalSpan
const externalSpan = Tracer.externalSpan({
spanId: "span-123",
traceId: "trace-456"
})
AnySpan>
readonly Span.annotations: Context.Context<never>(property) Span.annotations: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
annotations: import ContextContext.interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<never>
readonly Span.status: SpanStatusstatus: type SpanStatus =
| {
_tag: "Started"
startTime: bigint
}
| {
_tag: "Ended"
startTime: bigint
endTime: bigint
exit: Exit.Exit<unknown, unknown>
}
Lifecycle state of a span, where Started records the start time and
Ended records the start time, end time, and exit value with which the span
completed.
Example (Creating span statuses)
import { Exit } from "effect"
import type { Tracer } from "effect"
const startTime = 1_000_000_000n
const endTime = 1_500_000_000n
const startedStatus: Tracer.SpanStatus = {
_tag: "Started",
startTime
}
const endedStatus: Tracer.SpanStatus = {
_tag: "Ended",
startTime,
endTime,
exit: Exit.succeed("result")
}
console.log(startedStatus._tag) // "Started"
console.log(endedStatus.endTime - endedStatus.startTime) // 500000000n
SpanStatus
readonly Span.attributes: ReadonlyMap<string, unknown>attributes: interface ReadonlyMap<K, V>ReadonlyMap<string, unknown>
readonly Span.links: ReadonlyArray<SpanLink>links: interface ReadonlyArray<T>ReadonlyArray<SpanLink>
readonly Span.sampled: booleansampled: boolean
readonly Span.kind: SpanKindkind: type SpanKind =
| "internal"
| "server"
| "client"
| "producer"
| "consumer"
OpenTelemetry-style role describing the kind of operation represented by a
span: internal work, server handling, client calls, producing, or consuming.
Example (Configuring span kinds)
import { Effect } from "effect"
import type { Tracer } from "effect"
// Different span kinds for different operations
const serverSpan = Effect.withSpan("handle-request", {
kind: "server" as Tracer.SpanKind
})
const clientSpan = Effect.withSpan("api-call", {
kind: "client" as Tracer.SpanKind
})
const internalSpan = Effect.withSpan("internal-process", {
kind: "internal" as Tracer.SpanKind
})
SpanKind
Span.end(endTime: bigint, exit: Exit.Exit<unknown, unknown>): voidend(endTime: bigintendTime: bigint, exit: Exit.Exit<unknown, unknown>exit: import ExitExit.type Exit<A, E = never> = Exit.Success<A, E> | Exit.Failure<A, E>Represents the result of an Effect computation.
When to use
Use when you need to synchronously inspect whether an Effect computation
succeeded or failed.
Details
An Exit<A, E> is either Success<A, E> containing a value of type A, or
Failure<A, E> containing a Cause<E> describing why the computation
failed.
Since Exit is also an Effect, you can yield it inside Effect.gen.
Example (Pattern matching on an Exit)
import { Exit } from "effect"
const success: Exit.Exit<number> = Exit.succeed(42)
const failure: Exit.Exit<number, string> = Exit.fail("error")
const result = Exit.match(success, {
onSuccess: (value) => `Got value: ${value}`,
onFailure: (cause) => `Got error: ${cause}`
})
Namespace containing helper types shared by Exit values.
When to use
Use to reference helper types that describe the shared structure of Exit
values.
Exit<unknown, unknown>): void
Span.attribute(key: string, value: unknown): voidattribute(key: stringkey: string, value: unknownvalue: unknown): void
Span.event(name: string, startTime: bigint, attributes?: Record<string, unknown>): voidevent(name: stringname: string, startTime: bigintstartTime: bigint, attributes: Record<string, unknown> | undefinedattributes?: type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<string, unknown>): void
Span.addLinks(links: ReadonlyArray<SpanLink>): voidaddLinks(links: ReadonlyArray<SpanLink>links: interface ReadonlyArray<T>ReadonlyArray<SpanLink>): void
}