zeekayandHanzo Dev b588a65987 Registering a vector takes the series it already has
A vector is built against one registry and often registered with another,
and the natural order is to create it, use it, then register it.
Registration repointed the vector for writes still to come and left the
children where they were made, so a counter incremented before registration
gathered nowhere: the series was not wrong, it was absent, and the answer
depended on whether the caller registered before or after first use.

Registration now moves that name's series across. The entries carry their
own labels, so nothing is rebuilt and nothing is renamed — the same series,
gathered somewhere else — and the move runs under the vector's own lock, so
no child can appear midway.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 21:59:59 -07:00
2026-08-03 21:02:04 -07:00
2026-02-13 16:09:16 -08:00
2026-02-13 16:09:16 -08:00
2026-09-17 12:15:53 -07:00
2025-09-24 09:55:53 +00:00

metric

Lux Metrics Library

github.com/luxfi/metric is the native metrics library for Lux. It produces a scrape-compatible text exposition format and is designed for low overhead in hot paths.

Features

  • Single, native API for counters, gauges, histograms, summaries, and vectors
  • Scrape-compatible text format encoder and HTTP handler
  • Registry + gatherer model for composition
  • Optional no-op build for benchmark runs (build-tagged swap)

Installation

go get github.com/luxfi/metric@latest

Quick Start

package main

import (
	"net/http"

	"github.com/luxfi/metric"
)

func main() {
	m := metric.New("myapp")

	requests := m.NewCounter("requests_total", "Total requests")
	latency := m.NewHistogram("request_seconds", "Request latency (s)", metric.DefBuckets)

	requests.Inc()
	latency.Observe(0.123)

	http.Handle("/metrics", metric.Handler())
	_ = http.ListenAndServe(":8080", nil)
}

Custom Registry

reg := metric.NewRegistry()
m := metric.NewWithRegistry("myapp", reg)

requests := m.NewCounter("requests_total", "Total requests")
requests.Inc()

handler := metric.NewHTTPHandler(reg, metric.HandlerOpts{})

Vector Metrics

m := metric.New("myapp")
byRoute := m.NewCounterVec("requests_total", "Requests by route", []string{"method", "route"})

byRoute.WithLabelValues("GET", "/").Inc()

Metrics Off Build

Metrics record for real in an ordinary build. For benchmark runs you can swap the entire package to no-op implementations with a build tag, which keeps call sites unchanged while minimizing overhead.

go test -tags metrics_noop ./...

Built with the metrics_noop tag, metric.NewRegistry() and the package defaults return no-op implementations that record nothing — every counter reads zero — so use it only where that is what you want. Pre-bind label values in hot paths to avoid argument construction overhead.

S
Description
Prometheus metrics helpers: standard counters, gauges, histograms, and instrumentation conventions for all Lux components.
Readme BSD-3-Clause
880 KiB
Languages
Go 89.3%
HTML 9.4%
Makefile 1.3%