# gizlang:metrics

counters, gauges and histograms that every thread of a process can change without a lock or an allocation, and their exposition in the Prometheus text format 0.0.4 (GET /metrics). OTLP push reads the same metrics later; there is one registry of values, the process's atomics.

A metric declares its label values up front: its series set is bounded and known. Each series cell is Task.atomicGlobal of the series identity, so two declarations of the same metric (in two modules or threads) share values. Exposition takes the metrics to show; there is no hidden global list. Values are i64 in the metric's base unit. `scale` (a power of ten) states how many base units make one exposed unit, so an exposed value is exact decimal text (for example microseconds observed, seconds exposed).

```gizlang
import * as Metrics from "gizlang:metrics";
```

## Types

### `Series`

```gizlang
type Series = { values: Vec<string>; kind: string; bounds: Vec<i64>; cells: Vec<Task.Atomic>; }
```

One labelled series. Counter and gauge: one cell. Histogram: one cell per
bucket (not cumulative), the last for values above every bound, then the sum.

- `values`: `Vec<string>`
- `kind`: `string`
- `bounds`: `Vec<i64>`
- `cells`: `Vec<gizlang_task.Atomic>`

### `Metric`

```gizlang
type Metric = { name: string; help: string; kind: string; labels: Vec<string>; scale: i64; bounds: Vec<i64>; series: Vec<Series>; }
```

A metric: its name, help, kind, label names, scale, histogram bounds and series.

- `name`: `string`
- `help`: `string`
- `kind`: `string`
- `labels`: `Vec<string>`
- `scale`: `i64`
- `bounds`: `Vec<i64>`
- `series`: `Vec<gizlang_metrics.Series>`

## Functions

### `counter`

```gizlang
function counter(name: string, help: string, labels: Vec<string>, values: Vec<Vec<string>>): Metric throws string
```

A monotonic count. `values` lists the label values of each series.

Effects: fail, io.

### `gauge`

```gizlang
function gauge(name: string, help: string, labels: Vec<string>, values: Vec<Vec<string>>, scale: i64): Metric throws string
```

A value that goes up and down, exposed as value/scale.

Effects: fail, io.

### `histogram`

```gizlang
function histogram(name: string, help: string, labels: Vec<string>, values: Vec<Vec<string>>, bounds: Vec<i64>, scale: i64): Metric throws string
```

Observations counted in buckets with upper bounds `bounds` (ascending, in
base units), exposed with their sum and count.

Effects: fail, io.

### `text`

```gizlang
function text(metrics: Vec<Metric>): string
```

The metrics in the Prometheus text exposition format 0.0.4. A histogram's
count is the sum of the bucket cells it read, so +Inf and _count agree.

Effects: fail, io.

### `handler`

```gizlang
function handler(metrics: Vec<Metric>): Response
```

The GET /metrics response.

Effects: fail, io.

## Methods

### `Metric.at`

```gizlang
function Metric.at(self: Metric, values: Vec<string>): Option<Series>
```

The series with these label values. Keep it: the lookup is linear.

Effects: fail.

### `Series.add`

```gizlang
function Series.add(self: Series, n: i64): bool
```

Add to a counter (n >= 0) or a gauge. False for a histogram or a negative counter step.

Effects: fail, io.

### `Series.set`

```gizlang
function Series.set(self: Series, value: i64): bool
```

Set a gauge. False for other kinds.

Effects: fail, io.

### `Series.observe`

```gizlang
function Series.observe(self: Series, value: i64): bool
```

Record one observation in a histogram. False for other kinds.

Effects: fail, io.

### `Series.value`

```gizlang
function Series.value(self: Series): i64
```

The current value of a counter or gauge, in base units.

Effects: fail, io.

