Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

`ph` (module: `github.com/phonkee/ph`) is a Go library for declaratively defining Prometheus metrics as struct fields. It uses struct tags to inspect fields and auto-register them with the Prometheus client library.

## Commands

```bash
# Run all tests
go test ./...

# Run a single test
go test -run TestRegister ./...

# Run tests with verbose output
go test -v ./...

# Build the example
go build ./example/...

# Run the example
go run ./example/example.go
```

## Architecture

### Core flow

1. `New[T]` / `NewExisting[T]` (`new.go`) — entry points; call `apply()` then `registerCollectorInfos()`
2. `apply()` (`apply.go`) — walks struct fields via reflection; handles embedded structs recursively; calls `metricField()` for each supported field
3. `metricField()` (`metric.go`) — dispatches to the appropriate `newMetric*` factory based on the field's reflect type; populates a `collectorInfo`
4. `registerCollectorInfos()` (`collector.go`) — iterates `collectorInfo` slice and calls `registerer.Register()` for each

### Tag parsing

The `ph` struct tag is parsed via the external `github.com/phonkee/attribs` library (local replace directive points to `../attribs`). Tag attribute types are defined in `attribs.go`: `AttrCommon` (name, help, namespace, subsystem, skip), `AttrLabels` (labels), `AttrHistogram` (buckets). Pre-built parsers (`attribCounter`, `attribCounterVec`, etc.) are package-level vars.

### Supported field types

| Field type | Tag struct |
|---|---|
| `prometheus.Counter` (interface) | `AttrCounter` |
| `*prometheus.CounterVec` | `AttrCounterVec` |
| `prometheus.Gauge` (interface) | `AttrGauge` |
| `*prometheus.GaugeVec` | `AttrGaugeVec` |
| `prometheus.Histogram` (interface) | `AttrHistogram` |
| `*prometheus.HistogramVec` | `AttrHistogramVec` |

Interfaces are stored by value; `Vec` types must be pointers. `validate.go` detects common mistakes (e.g. `*prometheus.Counter` instead of `prometheus.Counter`) and emits a suggestion error.

### Options & Renamer

`Options` (`options.go`) controls defaults for namespace, subsystem, buckets, logger, mode, and renamer. All `With*` methods return a cloned options struct (immutable builder style). `Renamer` (`renamer.go`) is an interface applied to field names when no explicit `name=` tag is set; `Renamers()` chains multiple renamers; built-ins: `RenamerCase`, `RenamerPrefix`, `RenamerSuffix`.

### Mode

`ModeStrict` (default) returns an error for fields that look wrong (wrong pointer-ness, unexported fields with tags, etc.). `ModeWarning` logs warnings instead of failing.

### Utilities

- `Register[T]` (`prometheus.go`) — registers an already-populated struct into a registerer (no metric creation)
- `Validate[T]` (`validate.go`) — checks that all metric fields in a struct are non-nil after `New`
- `Must` / `MustError` (`must.go`) — panic helpers for tests/examples
- `DebugGather` (`debug.go`) — pretty-prints gathered metrics to stdout
- `TrackingRegistry` (`testing.go`) — test helper that wraps `prometheus.Registry` and tracks registered descriptors
- `StdOutLogger` / `StdErrLogger` / `FileLogger` / `LoggerAdapterZap` (`logger.go`) — logger adapters; default is `noopLogger`
Loading
Loading