Documentation
¶
Overview ¶
HIP-0106 native observability subsystem — New/Mount composition-root form.
import "github.com/hanzoai/metrics"
metrics.Mount(app, metrics.Deps{Logger: log, DataDir: dir, Brand: brand})
One subsystem serves all three signals — metrics, logs, traces — under /v1/{metrics,logs,traces}/* on the shared zip.App. Storage is native and WAL-durable; ingest for metrics is luxfi/metric.MetricBatch (the ZAP MsgMetricBatch payload). Every request is scoped to a tenant via the gateway-minted X-Org-Id header (falling back to the deployment brand), so the same binary serves any tenant with hard data isolation. There is no prometheus, no Grafana, no scrape endpoint, no /api/ path.
This package imports ONLY zap-proto/zip + luxfi (no hanzoai/cloud): it depends on the 3 things it uses — a logger, a data dir, and the brand — which it declares in its own Deps. The composition root (cmd/cloud) constructs those and calls Mount explicitly; there is no global registry and no init() side effect.
Package metrics is the native, ZAP-native, prometheus-free time-series store for the Hanzo cloud. It replaces the vendored Grafana/Prometheus observability backends with a small in-process store that ingests luxfi/metric.MetricBatch (the same wire shape the ZAP MsgMetricBatch transport carries) and serves range queries under /v1/metrics/*.
The storage API is deliberately tiny (Append + Query + SeriesCount) so a durable per-tenant backend (DataDir-backed, columnar) can replace the in-memory map without changing mount.go or ingest.go. There is ZERO prometheus here.
Index ¶
- Constants
- func Mount(app *zip.App, deps Deps) error
- type Deps
- type LogRecord
- type LogStore
- type Registry
- type Sample
- type Series
- type Span
- type Store
- func (s *Store) Append(name string, labels map[string]string, smp Sample)
- func (s *Store) EnableDurability(path string) error
- func (s *Store) IngestBatch(b *metric.MetricBatch) int
- func (s *Store) Query(name string, matchers map[string]string, startNs, endNs int64) []Series
- func (s *Store) SeriesCount() int
- type TraceStore
- type WAL
Constants ¶
const MsgMetricBatch uint16 = 2
MsgMetricBatch is the canonical ZAP MsgType for metric batches — it matches luxfi/metric.MsgMetricBatch and o11y/pkg/zapmetricreceiver so any luxfi/metric ZAP exporter ingests here unchanged.
const Version = "0.4.0"
Version is surfaced on the /health routes.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Deps ¶ added in v1.110.2
type Deps struct {
// Logger is the canonical Hanzo logger; Mount derives a scoped child.
Logger luxlog.Logger
// DataDir is the per-deployment data root; per-org WALs land under it.
DataDir string
// Brand is the default tenant when a request omits X-Org-Id.
Brand string
}
Deps is the NARROW dependency surface this subsystem declares — only the three things it uses. The composition root builds it from Config and passes it to Mount. No hanzoai/cloud import, no god-struct: a subsystem depends on what it needs, nothing more.
type LogRecord ¶ added in v0.2.0
type LogRecord struct {
TsNs int64 `json:"t"`
Level string `json:"level,omitempty"`
Body string `json:"body"`
Labels map[string]string `json:"labels,omitempty"`
}
LogRecord is one structured log line — the native, prometheus-free, Loki-free log signal. Bodies are stored verbatim; labels are the indexed dimensions.
type LogStore ¶ added in v0.2.0
type LogStore struct {
// contains filtered or unexported fields
}
LogStore is the native log store: an append-only bounded ring with label + time-range + case-insensitive substring query. Durable via the shared WAL.
func NewLogStore ¶ added in v0.2.0
func NewLogStore() *LogStore
NewLogStore returns an empty store retaining up to 1Mi records in memory.
func (*LogStore) Append ¶ added in v0.2.0
Append stores one log record (and durably logs it when durability is on).
func (*LogStore) EnableDurability ¶ added in v0.2.0
EnableDurability opens and replays a WAL at path (e.g. <DataDir>/logs/logs.wal).
func (*LogStore) Query ¶ added in v0.2.0
func (s *LogStore) Query(matchers map[string]string, startNs, endNs int64, contains string, limit int) []LogRecord
Query returns up to limit records (newest first) matching labels, the [startNs,endNs] range, and an optional case-insensitive substring of Body.
type Registry ¶ added in v0.3.0
type Registry struct {
// contains filtered or unexported fields
}
Registry lazily creates per-tenant store sets. Each tenant's WALs live under <DataDir>/orgs/<org>/o11y/ (the HIP-0302 per-org convention), so one tenant's metrics/logs/traces never mingle with another's — the same binary serves lux.cloud and zoo.cloud with hard data isolation. A single-tenant deployment simply uses one org (the deployment brand).
func NewRegistry ¶ added in v0.3.0
NewRegistry returns a registry rooted at dataDir ("" = in-memory, no durability).
type Sample ¶
Sample is a single timestamped value. Ts is nanoseconds since the Unix epoch to match luxfi/metric.MetricBatch.TimestampNs.
type Series ¶
type Series struct {
Name string `json:"name"`
Labels map[string]string `json:"labels,omitempty"`
Samples []Sample `json:"samples"`
}
Series is a named, labeled append-only stream of samples.
type Span ¶ added in v0.2.0
type Span struct {
TraceID string `json:"traceId"`
SpanID string `json:"spanId"`
Parent string `json:"parentId,omitempty"`
Name string `json:"name"`
StartNs int64 `json:"startNs"`
EndNs int64 `json:"endNs"`
Attrs map[string]string `json:"attrs,omitempty"`
}
Span is one unit of a distributed trace — the native, prometheus-free, Tempo-free trace signal. Times are nanoseconds since the Unix epoch.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the native in-memory time-series store. Each series is bounded to maxPerSeries samples (oldest evicted first). Safe for concurrent use.
func NewStore ¶
func NewStore() *Store
NewStore returns an empty store with a default per-series retention of 64Ki samples (a real deployment sets this from config / per-tenant quota).
func (*Store) Append ¶
Append adds one sample to the series identified by (name, labels), creating the series on first write and evicting the oldest sample past retention. When durability is enabled the sample is also written to the WAL.
func (*Store) EnableDurability ¶ added in v0.2.0
EnableDurability opens a write-ahead log at path and replays it into the store so samples survive restart. Replayed samples are not re-logged. Pass a per-deployment path (e.g. <DataDir>/metrics/metrics.wal).
func (*Store) IngestBatch ¶
func (s *Store) IngestBatch(b *metric.MetricBatch) int
IngestBatch writes every sample in a luxfi/metric.MetricBatch into the store. This is the exact wire type the ZAP MsgMetricBatch transport carries, so the same code path serves both the HTTP /v1/metrics/batch endpoint and a future ZAP receiver. Counter/gauge values land directly; histogram/summary families contribute derived <name>_sum and <name>_count series. Returns samples written.
func (*Store) Query ¶
Query returns copies of every series whose Name equals name (or all, if name is "") and whose labels are a superset of matchers, with samples restricted to [startNs, endNs] (a zero bound is treated as unbounded).
func (*Store) SeriesCount ¶
SeriesCount reports the number of distinct series held (surfaced on /health).
type TraceStore ¶ added in v0.2.0
type TraceStore struct {
// contains filtered or unexported fields
}
TraceStore is the native span store: an append-only bounded ring with a trace-id index for waterfall lookup and time-range listing. Durable via WAL.
func NewTraceStore ¶ added in v0.2.0
func NewTraceStore() *TraceStore
NewTraceStore returns an empty store retaining up to 1Mi spans in memory.
func (*TraceStore) Append ¶ added in v0.2.0
func (s *TraceStore) Append(sp Span)
Append stores one span (and durably logs it when durability is on).
func (*TraceStore) ByTrace ¶ added in v0.2.0
func (s *TraceStore) ByTrace(traceID string) []Span
ByTrace returns every span belonging to a trace id (the waterfall).
func (*TraceStore) Count ¶ added in v0.2.0
func (s *TraceStore) Count() int
Count reports the number of spans held.
func (*TraceStore) EnableDurability ¶ added in v0.2.0
func (s *TraceStore) EnableDurability(path string) error
EnableDurability opens and replays a WAL at path (e.g. <DataDir>/traces/traces.wal).
type WAL ¶ added in v0.2.0
type WAL struct {
// contains filtered or unexported fields
}
WAL is a simple append-only write-ahead log of length-prefixed records. It gives the in-memory stores durability: every write is appended here and the log is replayed on startup. This is intentionally a single flat segment — a production deployment adds rotation/compaction behind the same Append/Replay API without touching callers.
func OpenWAL ¶ added in v0.2.0
OpenWAL opens (creating parent dirs and the file as needed) an append log.