> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gocopper.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Metrics

Copper's `cmetrics` package provides Prometheus metrics with a declare-then-use model: register your counters and histograms up front, then emit them from anywhere. The `cprometheus` package (from [gocopper/pkg](https://github.com/gocopper/pkg)) exposes them over HTTP.

### Declaring Metrics

To declare your application's metrics, provide a `*cmetrics.Registry` and add `cmetrics.WireModule` to your wire set:

```go pkg/app/metrics.go theme={null}
func MetricsRegistry() *cmetrics.Registry {
	return cmetrics.NewRegistry(cmetrics.NewRegistryParams{
		Counters: []cmetrics.Counter{
			{Name: "rocket_launches_total", Labels: []string{"status"}},
		},
		Histograms: []cmetrics.Histogram{
			{Name: "launch_duration_seconds", Labels: []string{"rocket"}, Buckets: []float64{1, 5, 15, 60}},
		},
	})
}
```

Projects scaffolded with `copper create` already include this file and the wiring, so you only need to add your metrics to the registry.

### Emitting Metrics

To emit a metric, inject `cmetrics.Metrics` and reference the metric by name:

```go theme={null}
s.metrics.CounterInc("rocket_launches_total", map[string]string{"status": "success"})

s.metrics.HistogramObserve("launch_duration_seconds", map[string]string{"rocket": rocket.Name}, dur.Seconds())
```

<Note>
  Emitting an unregistered metric name (or a mismatched label set) logs a warning and does nothing; it will never panic or return an error.
</Note>

### Built-in HTTP Metrics

Every registry automatically includes two built-in metrics, which are emitted by `chttp.RequestLoggerMiddleware` (wired in by default):

* `http_requests_total{status_code, path}`
* `http_request_duration_seconds{status_code, path}`

The `path` label is the route template (`/api/rockets/{id}`) rather than the raw URL, so cardinality stays manageable.

### Exposing the Metrics Endpoint

To expose your metrics over HTTP, add `cprometheus.WireModule`, register `*cprometheus.Router` in your handler, and enable the endpoint in your config:

```toml theme={null}
[cprometheus]
http_enabled = true
http_path = "/internal/metrics" # default
```

The endpoint is disabled by default, so you may enable it only in the environments that Prometheus scrapes.
