Telemetry
Every hyperlink-ts node already writes into Effects Metric registry — queues, processes, HTTP clients, runtime gauges. Telemetry serves that registry as a Hyperlink: leaf fields for this node, fleet folds when the tag is meshed. OTEL stays the professional sink; Telemetry is for custom glass (CLI, TUI, web) over the same tags.
Declare the glass
One tag. Distribute it across the droplets you actually run — Context service keys, not nicknames.
class class DropletEastclass DropletEast {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
}
DropletEast extends import NodeNode.Tag<class DropletEastclass DropletEast {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
}
DropletEast>()("app/DropletEast") {}
class class DropletWestclass DropletWest {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
}
DropletWest extends import NodeNode.Tag<class DropletWestclass DropletWest {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
}
DropletWest>()("app/DropletWest") {}
class class DropletCentralclass DropletCentral {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
}
DropletCentral extends import NodeNode.Tag<class DropletCentralclass DropletCentral {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
}
DropletCentral>()("app/DropletCentral") {}
class class FleetMetricsFleetMetrics extends import TelemetryTelemetry.Tag<FleetMetrics>(): {
(): Telemetry.TelemetryTag<FleetMetrics>;
<HSelf>(options: {
readonly node: NodeKey<HSelf>;
readonly description?: string;
}): Telemetry.TelemetryNodeTag<FleetMetrics, HSelf>;
}
export Tag
Declare a Telemetry tag: class FleetTelemetry extends Telemetry.Tag<FleetTelemetry>()() {} (nodeless
— the dashboard reaches each node via Resource.client(FleetTelemetry, node)), or
…Tag<FleetTelemetry>()({ node: MiniNode }) to bind + serve it on a specific node.
Tag<class FleetMetricsFleetMetrics>()().Pipeable.pipe<Telemetry.TelemetryTag<FleetMetrics>, never>(this: Telemetry.TelemetryTag<FleetMetrics>, ab: (_: Telemetry.TelemetryTag<FleetMetrics>) => never): never (+21 overloads)pipe(
import HyperlinkHyperlink.distributed([class DropletEastclass DropletEast {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
of: (this: void, self: NodeProtocol) => NodeProtocol;
context: (self: NodeProtocol) => Context<DropletEast>;
use: (f: (service: NodeProtocol) => Effect<A, E, R>) => Effect<A, E, DropletEast | R>;
useSync: (f: (service: NodeProtocol) => A) => Effect<A, never, DropletEast>;
Identifier: Identifier;
stack: string | undefined;
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;
url: undefined;
path: undefined;
kind: undefined;
logs: unknown;
onConflict: OnConflict;
}
DropletEast, class DropletWestclass DropletWest {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
of: (this: void, self: NodeProtocol) => NodeProtocol;
context: (self: NodeProtocol) => Context<DropletWest>;
use: (f: (service: NodeProtocol) => Effect<A, E, R>) => Effect<A, E, DropletWest | R>;
useSync: (f: (service: NodeProtocol) => A) => Effect<A, never, DropletWest>;
Identifier: Identifier;
stack: string | undefined;
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;
url: undefined;
path: undefined;
kind: undefined;
logs: unknown;
onConflict: OnConflict;
}
DropletWest, class DropletCentralclass DropletCentral {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
of: (this: void, self: NodeProtocol) => NodeProtocol;
context: (self: NodeProtocol) => Context<DropletCentral>;
use: (f: (service: NodeProtocol) => Effect<A, E, R>) => Effect<A, E, DropletCentral | R>;
useSync: (f: (service: NodeProtocol) => A) => Effect<A, never, DropletCentral>;
Identifier: Identifier;
stack: string | undefined;
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;
url: undefined;
path: undefined;
kind: undefined;
logs: unknown;
onConflict: OnConflict;
}
DropletCentral]),
) {}Serve it on a droplet
Telemetry.serve forks the sampler and mounts leaf + fleet handlers. Discharge the mesh with Hyperlink.peersLayer so fleet fields can fold the other nodes leaf snapshots.
const const east: anyconst east: {
build: (memoMap: Layer.MemoMap, scope: Scope) => Effect<Context<unknown>, ServeError, Scope>;
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; <…;
}
east = import TelemetryTelemetry.serve<unknown>(tag: Telemetry.TelemetryTag<unknown>, options?: Telemetry.TelemetryOptions): Layer.Layer<unknown, never, Scope>
export serve
Serve this Telemetry resource and grant its local instance from one materialization — the
counterpart to
Resource.serve
. Forks one sampling fiber, mounts the snapshot/live RPC
handlers, and grants Self | Local<Self> so co-located code can yield* Tag. Reach it
remotely with Resource.client; a served-only edge uses
serveRemote
.
serve(class FleetMetricsFleetMetrics, {
TelemetryOptions.interval?: Duration.Duration | undefined(property) TelemetryOptions.interval?: {
value: DurationValue;
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;
}
Live-stream sampling cadence.
interval: import DurationDuration.const seconds: (
seconds: number
) => Duration.Duration
Creates a Duration from seconds.
Example (Creating durations from seconds)
import { Duration } from "effect"
const duration = Duration.seconds(30)
console.log(Duration.toMillis(duration)) // 30000
seconds(1),
}).Pipeable.pipe<Layer.Layer<unknown, never, Scope>, Layer.Layer<unknown, any, any>, any>(this: Layer.Layer<unknown, never, Scope>, ab: (_: Layer.Layer<unknown, never, Scope>) => Layer.Layer<unknown, any, any>, bc: (_: Layer.Layer<unknown, any, any>) => any): any (+21 overloads)pipe(
import LayerLayer.const provide: <any>(that: any) => <A, E, R>(self: Layer.Layer<A, E, R>) => Layer.Layer<A, any, any> (+3 overloads)Feeds the output services of the dependency layer into the requirements of
this layer, returning a layer that only provides the services from this layer.
When to use
Use when you need to hide an implementation dependency layer from callers.
Details
In serviceLayer.pipe(Layer.provide(dependencyLayer)), the dependency layer is
built first and is used to satisfy the requirements of serviceLayer.
Example (Providing layer dependencies)
import { Context, Effect, Layer } from "effect"
class Database extends Context.Service<Database, {
readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}
class UserService extends Context.Service<UserService, {
readonly getUser: (id: string) => Effect.Effect<{
id: string
name: string
}>
}>()("UserService") {}
class Logger extends Context.Service<Logger, {
readonly log: (msg: string) => Effect.Effect<void>
}>()("Logger") {}
// Create dependency layers
const databaseLayer = Layer.succeed(Database, {
query: Effect.fn("Database.query")((sql: string) => Effect.succeed(`DB: ${sql}`))
})
const loggerLayer = Layer.succeed(Logger, {
log: Effect.fn("Logger.log")((msg: string) => Effect.sync(() => console.log(`[LOG] ${msg}`)))
})
// UserService depends on Database and Logger
const userServiceLayer = Layer.effect(UserService, Effect.gen(function*() {
const database = yield* Database
const logger = yield* Logger
return {
getUser: Effect.fn("UserService.getUser")(function*(id: string) {
yield* logger.log(`Looking up user ${id}`)
const result = yield* database.query(
`SELECT * FROM users WHERE id = ${id}`
)
return { id, name: result }
})
}
}))
// Provide dependencies to UserService layer
const userServiceWithDependencies = userServiceLayer.pipe(
Layer.provide(Layer.mergeAll(databaseLayer, loggerLayer))
)
// Now UserService layer has no dependencies
const program = Effect.gen(function*() {
const userService = yield* UserService
return yield* userService.getUser("123")
}).pipe(
Effect.provide(userServiceWithDependencies)
)
provide(import HyperlinkHyperlink.peersLayer(class FleetMetricsFleetMetrics, class DropletEastclass DropletEast {
key: Identifier;
Service: {
protocol: Context.Service.Shape<typeof RpcClient.Protocol>;
};
of: (this: void, self: NodeProtocol) => NodeProtocol;
context: (self: NodeProtocol) => Context<DropletEast>;
use: (f: (service: NodeProtocol) => Effect<A, E, R>) => Effect<A, E, DropletEast | R>;
useSync: (f: (service: NodeProtocol) => A) => Effect<A, never, DropletEast>;
Identifier: Identifier;
stack: string | undefined;
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;
url: undefined;
path: undefined;
kind: undefined;
logs: unknown;
onConflict: OnConflict;
}
DropletEast)),
const nodeServer: (
port: number
) => <A, E, R>(
resource: Layer.Layer<A, E, R>
) => any
nodeServer(3001),
)
// east: Layer — this droplet samples its registry and reaches West + Central for fleet foldsA single-node app with no peers uses Telemetry.alone instead of peersLayer:
const const local: Layer.Layer<
FleetTelemetry,
any,
any
>
const local: {
build: (memoMap: Layer.MemoMap, scope: Scope) => Effect<Context<FleetTelemetry | Local<FleetTelemetry>>, never, never>;
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; <…;
}
local = import TelemetryTelemetry.layer<FleetTelemetry>(tag: Telemetry.TelemetryTag<FleetTelemetry>, options?: Telemetry.TelemetryOptions): Layer.Layer<FleetTelemetry, never, Scope>
export layer
Local layer for a Telemetry tag — forks one sampling fiber into scope and wires snapshot/live.
layer(class FleetTelemetryclass FleetTelemetry {
key: Identifier;
Service: {
snapshot: Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect<number, never, never>;
};
groupId: string;
description: string | undefined;
of: (this: void, self: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; reado…;
context: (self: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; readonly fleetInF…;
use: (f: (service: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; readonly f…;
useSync: (f: (service: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; readonly f…;
Identifier: Identifier;
stack: string | undefined;
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;
}
FleetTelemetry).Pipeable.pipe<Layer.Layer<FleetTelemetry, never, Scope>, Layer.Layer<FleetTelemetry, any, any>>(this: Layer.Layer<FleetTelemetry, never, Scope>, ab: (_: Layer.Layer<FleetTelemetry, never, Scope>) => Layer.Layer<FleetTelemetry, any, any>): Layer.Layer<FleetTelemetry, any, any> (+21 overloads)pipe(
import LayerLayer.const provide: <any>(that: any) => <A, E, R>(self: Layer.Layer<A, E, R>) => Layer.Layer<A, any, any> (+3 overloads)Feeds the output services of the dependency layer into the requirements of
this layer, returning a layer that only provides the services from this layer.
When to use
Use when you need to hide an implementation dependency layer from callers.
Details
In serviceLayer.pipe(Layer.provide(dependencyLayer)), the dependency layer is
built first and is used to satisfy the requirements of serviceLayer.
Example (Providing layer dependencies)
import { Context, Effect, Layer } from "effect"
class Database extends Context.Service<Database, {
readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}
class UserService extends Context.Service<UserService, {
readonly getUser: (id: string) => Effect.Effect<{
id: string
name: string
}>
}>()("UserService") {}
class Logger extends Context.Service<Logger, {
readonly log: (msg: string) => Effect.Effect<void>
}>()("Logger") {}
// Create dependency layers
const databaseLayer = Layer.succeed(Database, {
query: Effect.fn("Database.query")((sql: string) => Effect.succeed(`DB: ${sql}`))
})
const loggerLayer = Layer.succeed(Logger, {
log: Effect.fn("Logger.log")((msg: string) => Effect.sync(() => console.log(`[LOG] ${msg}`)))
})
// UserService depends on Database and Logger
const userServiceLayer = Layer.effect(UserService, Effect.gen(function*() {
const database = yield* Database
const logger = yield* Logger
return {
getUser: Effect.fn("UserService.getUser")(function*(id: string) {
yield* logger.log(`Looking up user ${id}`)
const result = yield* database.query(
`SELECT * FROM users WHERE id = ${id}`
)
return { id, name: result }
})
}
}))
// Provide dependencies to UserService layer
const userServiceWithDependencies = userServiceLayer.pipe(
Layer.provide(Layer.mergeAll(databaseLayer, loggerLayer))
)
// Now UserService layer has no dependencies
const program = Effect.gen(function*() {
const userService = yield* UserService
return yield* userService.getUser("123")
}).pipe(
Effect.provide(userServiceWithDependencies)
)
provide(import TelemetryTelemetry.alone(class FleetTelemetryclass FleetTelemetry {
key: Identifier;
Service: {
snapshot: Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect<number, never, never>;
};
groupId: string;
description: string | undefined;
of: (this: void, self: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; reado…;
context: (self: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; readonly fleetInF…;
use: (f: (service: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; readonly f…;
useSync: (f: (service: { readonly snapshot: Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect<{ readonly [x: string]: number }, never, never>; readonly f…;
Identifier: Identifier;
stack: string | undefined;
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;
}
FleetTelemetry)),
)
// local: Layer — leaf snapshot/live + fleet fields that only see this nodeRead this nodes registry
snapshot is point-in-time. live is a ~1s push of the same envelope. Same handle, local or remote.
const const glass: ServiceOf<
{
snapshot: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
false,
MethodAnnotations & {
description: string
}
>
live: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
true,
MethodAnnotations & {
description: string
}
>
},
FleetMetrics
>
const glass: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
}
glass = yield* class FleetMetricsclass FleetMetrics {
key: Identifier;
Service: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
};
groupId: string;
description: string | undefined;
of: (this: void, self: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never,…;
context: (self: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>; rea…;
use: (f: (service: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, neve…;
useSync: (f: (service: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, neve…;
Identifier: Identifier;
stack: string | undefined;
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;
}
FleetMetrics
const const snap: Telemetry.MetricsSnapshotconst snap: {
ts: number;
metrics: ReadonlyArray<Telemetry.CounterDatum | Telemetry.GaugeDatum | Telemetry.HistogramDatum>;
}
snap = yield* const glass: ServiceOf<
{
snapshot: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
false,
MethodAnnotations & {
description: string
}
>
live: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
true,
MethodAnnotations & {
description: string
}
>
},
FleetMetrics
>
const glass: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
}
glass.snapshot: Effect.Effect<
Telemetry.MetricsSnapshot,
never,
never
>
(property) snapshot: {
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;
}
snapshot // MetricsSnapshot { ts, metrics }
const const probe:
| Telemetry.MetricDatum
| undefined
probe = const snap: Telemetry.MetricsSnapshotconst snap: {
ts: number;
metrics: ReadonlyArray<Telemetry.CounterDatum | Telemetry.GaugeDatum | Telemetry.HistogramDatum>;
}
snap.MetricsSnapshot.metrics: readonly Telemetry.MetricDatum[]metrics.ReadonlyArray<MetricDatum>.find(predicate: (value: Telemetry.MetricDatum, index: number, obj: readonly Telemetry.MetricDatum[]) => unknown, thisArg?: any): Telemetry.MetricDatum | undefined (+1 overload)Returns the value of the first element in the array where predicate is true, and undefined
otherwise.
find((m: Telemetry.MetricDatumm) => m: Telemetry.MetricDatumm.id: stringid === "queue_enqueued_total")
const const mine: anymine = import TelemetryTelemetry.inFlightOf(const snap: Telemetry.MetricsSnapshotconst snap: {
ts: number;
metrics: ReadonlyArray<Telemetry.CounterDatum | Telemetry.GaugeDatum | Telemetry.HistogramDatum>;
}
snap) // number — queue_in_flight on this node (0 if absent)
Show the fleet
Fleet fields fold each peers leaf snapshot (peers never expose fleet fields, so a fold cant recurse). One yield, columns + total:
const const glass: ServiceOf<
{
snapshot: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
false,
MethodAnnotations & {
description: string
}
>
live: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
true,
MethodAnnotations & {
description: string
}
>
},
FleetMetrics
>
const glass: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
}
glass = yield* class FleetMetricsclass FleetMetrics {
key: Identifier;
Service: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
};
groupId: string;
description: string | undefined;
of: (this: void, self: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never,…;
context: (self: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>; rea…;
use: (f: (service: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, neve…;
useSync: (f: (service: { readonly snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>; readonly live: Stream<Telemetry.MetricsSnapshot, never, never>; readonly inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, neve…;
Identifier: Identifier;
stack: string | undefined;
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;
}
FleetMetrics
const const columns: anycolumns = yield* const glass: ServiceOf<
{
snapshot: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
false,
MethodAnnotations & {
description: string
}
>
live: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
true,
MethodAnnotations & {
description: string
}
>
},
FleetMetrics
>
const glass: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
}
glass.inFlightByNode
// columns: Record<string, number> — e.g. { "app/DropletEast": 5, "app/DropletWest": 3 }
const const total: anytotal = yield* const glass: ServiceOf<
{
snapshot: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
false,
MethodAnnotations & {
description: string
}
>
live: Method<
"query",
undefined,
Codec<
Telemetry.MetricsSnapshot,
Telemetry.MetricsSnapshot,
never,
never
>,
Never,
true,
MethodAnnotations & {
description: string
}
>
},
FleetMetrics
>
const glass: {
snapshot: Effect.Effect<Telemetry.MetricsSnapshot, never, never>;
live: Stream<Telemetry.MetricsSnapshot, never, never>;
inFlightByNode: Effect.Effect<{ readonly [x: string]: number }, never, never>;
fleetInFlight: Effect.Effect<number, never, never>;
}
glass.fleetInFlight
// total: number — sum of queue_in_flight across self + peers
Telemetry.inFlightMetricId is "queue_in_flight" — the gauge queue engines already emit.
OTEL stays the grown-up sink
Telemetry does not retain, alert, or query history. Wire @effect/opentelemetry when you need collectors; keep Telemetry when you want the registry on a Hyperlink tag your CLI / TUI / web already speak.
Runnable form: pnpm run example:telemetry-fleet-glass. For readiness across the same mesh (Reachable / Unreachable, not metric skip-omit), see Fleet Health. Also Fleets & Peers.