Raxol.Terminal.Metrics.MetricsServer (Raxol Terminal v2.6.0)

Copy Markdown View Source

ETS-backed metrics collection and export module.

Provides centralized metrics storage using ETS for high-performance concurrent writes and reads. Supports multiple metric types and Prometheus-compatible export.

Design

Uses ETS for write-heavy workloads (per Rich Hickey's feedback). No GenServer serialization for metric recording - direct ETS writes.

Metric Types

  • Counters: Monotonically increasing values (e.g., operations count)
  • Gauges: Point-in-time values (e.g., memory usage)
  • Histograms: Distribution of values (e.g., latency percentiles)

Usage

# Initialize (call once at app startup)
MetricsServer.init()

# Record metrics
MetricsServer.increment(:requests_total, %{path: "/api"})
MetricsServer.gauge(:memory_bytes, 1024000, %{type: :heap})
MetricsServer.histogram(:latency_ms, 42.5, %{endpoint: :render})

# Query metrics
MetricsServer.get(:requests_total, %{path: "/api"})
MetricsServer.get_all()

# Export for monitoring
MetricsServer.export(:prometheus)
MetricsServer.export(:json)

Summary

Functions

Exports metrics in the specified format.

Exports metrics in the specified format.

Sets a gauge metric to a specific value.

Gets all metrics as a map.

Gets the current value of a counter.

Gets the current value of a gauge.

Gets histogram statistics.

Gets a metric value (generic interface).

Records a value in a histogram.

Increments a counter metric.

Initializes the metrics storage tables.

Checks if metrics storage is initialized.

Records a metric value (generic interface).

Types

labels()

@type labels() :: map()

metric_name()

@type metric_name() :: atom()

metric_value()

@type metric_value() :: number()

Functions

cleanup_metrics(opts \\ [], store_name \\ nil)

@spec cleanup_metrics(
  keyword(),
  atom()
) :: :ok

Cleans up old metrics.

Options

  • :older_than - Remove entries older than this many milliseconds
  • :type - Only clean this type (:histogram, :error)

export(format)

@spec export(atom()) :: String.t() | {:error, :unsupported_format}

Exports metrics in the specified format.

export_metrics(opts \\ [], store_name \\ nil)

@spec export_metrics(
  keyword(),
  atom()
) :: String.t() | {:error, :unsupported_format}

Exports metrics in the specified format.

Formats

  • :prometheus - Prometheus text format
  • :json - JSON format

Examples

MetricsServer.export(:prometheus)
MetricsServer.export(:json)

gauge(name, value, labels \\ %{})

@spec gauge(metric_name(), metric_value(), labels()) :: :ok

Sets a gauge metric to a specific value.

Examples

MetricsServer.gauge(:memory_bytes, 1024000)
MetricsServer.gauge(:cpu_percent, 45.5, %{core: 0})

get_all()

@spec get_all() :: map()

Gets all metrics as a map.

get_counter(name, labels \\ %{})

@spec get_counter(metric_name(), labels()) :: non_neg_integer()

Gets the current value of a counter.

get_error_stats(labels \\ %{}, store_name \\ nil)

@spec get_error_stats(labels(), atom()) :: {:ok, map()}

Gets error statistics.

get_gauge(name, labels \\ %{})

@spec get_gauge(metric_name(), labels()) :: metric_value() | nil

Gets the current value of a gauge.

get_histogram(name, labels \\ %{})

@spec get_histogram(metric_name(), labels()) :: map()

Gets histogram statistics.

Returns count, sum, min, max, and percentiles.

get_metric(name, labels \\ %{}, store_name \\ nil)

@spec get_metric(metric_name(), labels(), atom()) ::
  {:ok, metric_value()} | {:error, :not_found}

Gets a metric value (generic interface).

histogram(name, value, labels \\ %{})

@spec histogram(metric_name(), metric_value(), labels()) :: :ok

Records a value in a histogram.

Examples

MetricsServer.histogram(:latency_ms, 42.5)
MetricsServer.histogram(:latency_ms, 15.2, %{endpoint: :render})

increment(name, labels \\ %{}, amount \\ 1)

@spec increment(metric_name(), labels(), pos_integer()) :: :ok

Increments a counter metric.

Examples

MetricsServer.increment(:requests_total)
MetricsServer.increment(:requests_total, %{path: "/api"})
MetricsServer.increment(:requests_total, %{path: "/api"}, 5)

init()

@spec init() :: :ok

Initializes the metrics storage tables.

Call once during application startup.

initialized?()

@spec initialized?() :: boolean()

Checks if metrics storage is initialized.

record_error(message, labels \\ %{}, store_name \\ nil)

@spec record_error(String.t(), labels(), atom()) :: :ok

Records an error occurrence.

record_metric(name, value, labels \\ %{}, store_name \\ nil)

@spec record_metric(metric_name(), metric_value(), labels(), atom()) :: :ok

Records a metric value (generic interface).