Context.Reference<Readonly<Record<string, string>>>Context reference for metric attributes applied from the current Effect context.
When to use
Use to provide default attributes that should be merged into metric updates and reads in a scoped part of a program.
Details
The default value is an empty attribute set. Metric reads and updates merge these contextual attributes with the metric's own attributes to select the metric series being accessed.
Example (Providing current metric attributes)
import { Data, Effect, Metric } from "effect"
class AttributesError extends Data.TaggedError("AttributesError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Access current metric attributes
const attributes = yield* Metric.CurrentMetricAttributes
console.log("Current attributes:", attributes)
// Set new attributes context
const newAttributes = { service: "api", version: "1.0" }
const result = yield* Effect.provideService(
Effect.gen(function*() {
const updatedAttributes = yield* Metric.CurrentMetricAttributes
return updatedAttributes
}),
Metric.CurrentMetricAttributes,
newAttributes
)
return result
})export const const CurrentMetricAttributes: Context.Reference<
Readonly<Record<string, string>>
>
const CurrentMetricAttributes: {
defaultValue: () => Shape;
of: (this: void, self: Readonly<Record<string, string>>) => Readonly<Record<string, string>>;
context: (self: Readonly<Record<string, string>>) => Context.Context<never>;
use: (f: (service: Readonly<Record<string, string>>) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: Readonly<Record<string, string>>) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
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;
}
Context reference for metric attributes applied from the current Effect
context.
When to use
Use to provide default attributes that should be merged into metric updates
and reads in a scoped part of a program.
Details
The default value is an empty attribute set. Metric reads and updates merge
these contextual attributes with the metric's own attributes to select the
metric series being accessed.
Example (Providing current metric attributes)
import { Data, Effect, Metric } from "effect"
class AttributesError extends Data.TaggedError("AttributesError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Access current metric attributes
const attributes = yield* Metric.CurrentMetricAttributes
console.log("Current attributes:", attributes)
// Set new attributes context
const newAttributes = { service: "api", version: "1.0" }
const result = yield* Effect.provideService(
Effect.gen(function*() {
const updatedAttributes = yield* Metric.CurrentMetricAttributes
return updatedAttributes
}),
Metric.CurrentMetricAttributes,
newAttributes
)
return result
})
CurrentMetricAttributes = import ContextContext.Reference<Metric.type Metric<in Input, out State>.AttributeSet = {
readonly [x: string]: string;
}
Type for metric attributes as a readonly record of string key-value pairs.
Example (Combining metric attribute sets)
import { Data, Effect, Metric } from "effect"
class AttributeSetError extends Data.TaggedError("AttributeSetError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Define attribute sets for different contexts
const serviceAttributes = {
service: "user-api",
version: "2.1.0",
environment: "production"
}
const operationAttributes = {
operation: "create_user",
method: "POST",
endpoint: "/api/users"
}
const infrastructureAttributes = {
region: "us-east-1",
datacenter: "dc1",
host: "api-server-01"
}
// Create metrics with predefined attribute sets
const requestCounter = Metric.counter("http_requests_total", {
description: "Total HTTP requests",
attributes: serviceAttributes
})
// Combine attribute sets
const combineAttributes = (...attributeSets: Array<Record<string, string>>) =>
Object.assign({}, ...attributeSets)
const fullAttributes = combineAttributes(
serviceAttributes,
operationAttributes,
infrastructureAttributes
)
// Create metric with combined attributes
const detailedCounter = Metric.withAttributes(requestCounter, fullAttributes)
// Helper to validate attribute keys (all must be strings)
const validateAttributeSet = (attrs: Record<string, string>): boolean => {
return Object.entries(attrs).every(([key, value]) =>
typeof key === "string" && typeof value === "string"
)
}
yield* Metric.update(detailedCounter, 1)
return {
attributes: {
service: serviceAttributes,
operation: operationAttributes,
infrastructure: infrastructureAttributes,
combined: fullAttributes,
isValid: validateAttributeSet(fullAttributes), // true
totalKeys: Object.keys(fullAttributes).length // 9
}
}
})
AttributeSet>(const CurrentMetricAttributesKey: "effect/Metric/CurrentMetricAttributes"Service key for the current metric attributes context.
Example (Accessing the current metric attributes key)
import { Data, Effect, Metric } from "effect"
class AttributesKeyError extends Data.TaggedError("AttributesKeyError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// The key is used internally by the Effect runtime to manage metric attributes
const key = Metric.CurrentMetricAttributesKey
// Create metrics with base attributes
const requestCounter = Metric.counter("requests_total", {
description: "Total HTTP requests"
})
// The CurrentMetricAttributes service provides default attributes
// that get applied to all metrics in the current context
const baseAttributes = { service: "api", version: "1.0" }
// Use withAttributes to apply attributes to metrics
const taggedCounter1 = Metric.withAttributes(requestCounter, baseAttributes)
const program1 = Metric.update(taggedCounter1, 1)
const taggedCounter2 = Metric.withAttributes(requestCounter, {
...baseAttributes,
endpoint: "/users"
})
const program2 = Metric.update(taggedCounter2, 5)
yield* program1
yield* program2
return {
keyValue: key, // "effect/Metric/CurrentMetricAttributes"
keyType: typeof key, // "string"
isConstant: key === "effect/Metric/CurrentMetricAttributes" // true
}
})
CurrentMetricAttributesKey, {
defaultValue: () => {}defaultValue: () => ({})
})