Hyperlinkv0.8.0-beta.28

Metric

Metric.dumpconsteffect/Metric.ts:3104
Effect<string, never, never>

Returns a human-readable string representation of all currently registered metrics in a tabular format.

Details

This debugging utility captures a snapshot of all metrics and formats them in an easy-to-read table showing names, descriptions, types, attributes, and current state values.

Example (Dumping metrics as text)

import { Console, Data, Effect, Metric } from "effect"

class DumpError extends Data.TaggedError("DumpError")<{
  readonly operation: string
}> {}

const program = Effect.gen(function*() {
  // Create and update some metrics for demonstration
  const requestCounter = Metric.counter("http_requests_total", {
    description: "Total HTTP requests"
  })
  const responseTime = Metric.gauge("response_time_ms", {
    description: "Current response time in milliseconds"
  })
  const statusFreq = Metric.frequency("http_status_codes", {
    description: "Frequency of HTTP status codes"
  })

  // Update metrics with some values
  yield* Metric.update(requestCounter, 1)
  yield* Metric.update(requestCounter, 1)
  yield* Metric.update(responseTime, 125)
  yield* Metric.update(statusFreq, "200")
  yield* Metric.update(statusFreq, "404")
  yield* Metric.update(statusFreq, "200")

  // Get formatted dump of all metrics
  const metricsReport = yield* Metric.dump
  yield* Console.log("Current Metrics:")
  yield* Console.log(metricsReport)

  // Output will look like a formatted table:
  // Name                  Description                           Type       State
  // http_requests_total   Total HTTP requests                   Counter    [count: 2]
  // response_time_ms      Current response time in milliseconds Gauge      [value: 125]
  // http_status_codes     Frequency of HTTP status codes       Frequency  [occurrences: 200 -> 2, 404 -> 1]

  return metricsReport
})
Debugging
Source effect/Metric.ts:310434 lines
export const dump: Effect<string> = InternalEffect.flatMap(InternalEffect.context(), (context) => {
  const metrics = snapshotUnsafe(context)
  if (metrics.length > 0) {
    const maxNameLength = metrics.reduce((max, metric) => {
      const length = metric.id.length
      return length > max ? length : max
    }, 0) + 2
    const maxDescriptionLength = metrics.reduce((max, metric) => {
      const length = Predicate.isNotUndefined(metric.description) ? metric.description.length : 0
      return length > max ? length : max
    }, 0) + 2
    const maxTypeLength = metrics.reduce((max, metric) => {
      const length = metric.type.length
      return length > max ? length : max
    }, 0) + 2
    const maxAttributesLength = metrics.reduce((max, metric) => {
      const length = Predicate.isNotUndefined(metric.attributes) ? attributesToString(metric.attributes).length : 0
      return length > max ? length : max
    }, 0) + 2
    const grouped = Object.entries(Arr.groupBy(metrics, (metric) => metric.id))
    const sorted = Arr.sortWith(grouped, (entry) => entry[0], _String.Order)
    const rendered = sorted.map(([, group]) =>
      group.map((metric) =>
        renderName(metric, maxNameLength) +
        renderDescription(metric, maxDescriptionLength) +
        renderType(metric, maxTypeLength) +
        renderAttributes(metric, maxAttributesLength) +
        renderState(metric)
      ).join("\n")
    ).join("\n")
    return InternalEffect.succeed(rendered)
  }
  return InternalEffect.succeed("")
})