moonp8s Reference · every public name Reference GitHub
Reference

Every public name.

Generated from the interfaces MoonBit prints for this module, so nothing public is missing and no signature was typed twice. The prose is the documentation comment beside the code.

Packages
five, and a facade
Entries
— entries
Source
pkg.generated.mbti
01

metric

moonbitstack/moonp8s/metric

The model: kinds, the seven metric types, families, a registry, and the snapshot an exposition is written from. Nothing here reads a clock, opens a socket or writes a byte.

Values

let buckets: Array[Double]

The default bucket bounds the official Prometheus clients share: 0.005 through 10, fourteen finite bounds plus the implicit +Inf bucket every histogram has.

let exemplar_label_limit: Int32

OpenMetrics caps an exemplar's combined label names and values at 128 characters; a longer set makes the exemplar unrepresentable.

fn exponential(Double, Double, Int32) -> Array[Double] raise Refused

count bounds starting at start and multiplying by factor.

fn is_valid_label_name(String) -> Bool

Whether name is a label name under the OpenMetrics character rules: [a-zA-Z_][a-zA-Z0-9_]*.

fn is_valid_metric_name(String) -> Bool

Whether name is a metric name under the OpenMetrics character rules: [a-zA-Z_:][a-zA-Z0-9_:]*.

fn is_valid_unit(String) -> Bool

Whether unit may be appended to a metric name. A unit starts with a letter and continues with letters, digits, or underscores.

fn linear(Double, Double, Int32) -> Array[Double] raise Refused

count bounds starting at start and growing by width.

fn point_of(Value) -> Point

A point with no labels and no metadata, the shape a bare metric collects into before its registry or family adds labels.

Errors

error Refused

The one error this library raises: a request it will not honour, with the reason in the message. Messages carry the offending value and, where a position is meaningful, an at offset counted from zero.

Refused(String)

fn Refused::message(Self) -> String

The reason a request was refused.

Types and methods

struct Counter Metric

A monotonically increasing count. inc refuses a negative step because a counter that goes down is a gauge.

fn Counter::get(Self) -> Double

The current count.

fn Counter::inc(Self, by? : Double, exemplar? : Exemplar) -> Unit raise Refused

Increase the counter by by, keeping exemplar as the latest exemplar.

fn Counter::new(created? : Double) -> Self

A counter at zero. created records when the series came into existence, for the _created series OpenMetrics exposes.

fn Counter::reset(Self, created? : Double) -> Unit

Restart the counter at zero, optionally dating the reset as a new creation time. Use this when a logical process restarts without restarting the program.

A reset is a new series, so the creation time is the reset's: passing none clears it rather than leaving the old one in place, which would claim the restarted counter started when the old one did.

fn Counter::shard(Self) -> LocalCounter

A shard of this counter. Many shards may feed one counter; each flushes its own accumulations.

Also on the type: kind · points — derived, or required by an implementation above.

struct Exemplar

An exemplar ties a sample to the request that produced it: the request's labels, the observed value, and optionally when it was observed (Unix seconds).

labels
Array[(String, String)]
value
Double
timestamp
Double?
fn Exemplar::new(Array[(String, String)], Double, timestamp? : Double) -> Self raise Refused

Build an exemplar, refusing a label set over the OpenMetrics limit.

struct Gauge Metric

An instantaneous value that may go up or down. set takes the timestamp to record, because this library never reads a clock; pass timestamp~ when the sample is worth dating.

fn Gauge::dec(Self, by? : Double) -> Unit

Decrease the gauge by by.

fn Gauge::get(Self) -> Double

The current value.

fn Gauge::inc(Self, by? : Double) -> Unit

Increase the gauge by by.

fn Gauge::new(initial? : Double) -> Self

A gauge at initial (zero unless given).

fn Gauge::set(Self, Double, timestamp? : Double) -> Unit

Set the gauge to v, optionally dating the sample.

fn Gauge::set_function(Self, () -> Double) -> Unit

Take the value from f instead of a stored number. While a function is set, set, inc, and dec do nothing, matching the Python client.

Also on the type: kind · points — derived, or required by an implementation above.

struct GaugeHistogram Metric

A gauge histogram: the same buckets as a histogram, but the sum and count are a gauge's, and the wire format spells them _gsum and _gcount.

fn GaugeHistogram::new(buckets? : Array[Double], created? : Double) -> Self raise Refused

A gauge histogram over buckets (the shared defaults unless given).

fn GaugeHistogram::observe(Self, Double, exemplar? : Exemplar) -> Unit

Record one observation.

fn GaugeHistogram::snapshot(Self) -> Point

The snapshot of this gauge histogram.

Also on the type: kind · points — derived, or required by an implementation above.

struct Histogram Metric

A histogram with cumulative buckets. Counts are kept per bucket and made cumulative on snapshot, which is what the wire format carries.

fn Histogram::new(buckets? : Array[Double], created? : Double) -> Self raise Refused

A histogram over buckets (the shared defaults unless given).

fn Histogram::observe(Self, Double, exemplar? : Exemplar) -> Unit

Record one observation in the first bucket whose bound it does not exceed, or in the +Inf bucket when it exceeds every bound.

fn Histogram::snapshot(Self) -> Point

The snapshot of this histogram: cumulative bucket counts, the sum, and the total count, with the retained exemplars.

fn Histogram::sum_value(Self) -> Double

The sum of the observations.

fn Histogram::total(Self) -> Int64

The number of observations.

Also on the type: kind · points — derived, or required by an implementation above.

struct Info Metric

An info metric: a fixed set of labels whose value is always 1. It carries build and version metadata, which is why it never changes after creation.

fn Info::labels(Self) -> Array[(String, String)]

The labels this info metric carries.

fn Info::new(Array[(String, String)]) -> Self raise Refused

An info metric with these labels.

Also on the type: kind · points — derived, or required by an implementation above.

enum Kind

The kind of a metric, as spelled in the # TYPE line of an exposition.

Counter

Gauge

Histogram

GaugeHistogram

Summary

Info

StateSet

Unknown

fn Kind::code(Self) -> String

The wire spelling of this kind: counter, gauge, histogram, gaugehistogram, summary, info, stateset, or unknown.

fn Kind::of(String) -> Self

The kind a wire spelling names. untyped is the legacy spelling of unknown, and an unrecognised spelling is unknown rather than an error so that a newer peer's exposition still parses.

struct LocalCounter Metric

A non-atomic shard of a counter. Increments land in the shard and are added to the shared counter on flush, which is the local accumulation the Rust client offers; it keeps a hot path off the shared value without requiring thread-local storage.

fn LocalCounter::flush(Self) -> Unit

Add the shard's value to the shared counter and clear the shard.

fn LocalCounter::get(Self) -> Double

The shard's unflushed value.

fn LocalCounter::inc(Self, by? : Double) -> Unit raise Refused

Increase the shard by by.

fn LocalCounter::reset(Self) -> Unit

Drop the unflushed value.

Also on the type: kind · points — derived, or required by an implementation above.

struct MetricFamily

A family of series sharing one name, help text, kind, and optional unit. This is what an exposition is written from and what a parser produces.

name
String
kind
Kind
help
String
unit
String?
metrics
Array[Point]
struct Point

One series of a family: its labels, its value, and the optional metadata OpenMetrics carries alongside it. created is when the series was created (Unix seconds); exemplars are the retained exemplars, matched to histogram buckets by the value that produced them.

labels
Array[(String, String)]
value
Value
timestamp
Double?
created
Double?
exemplars
Array[Exemplar]
struct ProcessCollector Collector

The seven process_* series the Rust client's process collector exposes: CPU time, open and maximum file descriptors, virtual and resident memory, start time, and thread count.

fn ProcessCollector::new(ProcessStats, prefix? : String) -> Self

A process collector over stats. namespace prefixes every name, as the Rust client's namespace does.

Also on the type: collect — derived, or required by an implementation above.

struct ProcessStats

The process numbers a ProcessCollector exports. The caller reads them — this library performs no I/O — which keeps the collector portable across every target.

cpu_seconds
Double
open_fds
Int64
max_fds
Int64
virtual_memory_bytes
Int64
resident_memory_bytes
Int64
start_time_seconds
Double
threads
Int64
struct Registry

The set of metrics one exposition exposes, with an optional name prefix and optional constant labels applied to everything registered. A registry refuses a metric name that is not a valid OpenMetrics name, a label name that is not a valid label name, a unit that is not a valid unit, and a name registered twice.

fn Registry::add(Self, &Collector) -> Unit

Add a custom collector. Its families are exposed after the registered metrics, with this registry's prefix and labels applied.

fn Registry::counter(Self, String, String, unit? : String) -> Counter raise Refused

Create a counter, register it, and return it.

fn Registry::gauge(Self, String, String, unit? : String) -> Gauge raise Refused

Create a gauge, register it, and return it.

fn Registry::histogram(Self, String, String, buckets? : Array[Double], unit? : String) -> Histogram raise Refused

Create a histogram, register it, and return it.

fn Registry::new(prefix? : String, labels? : Array[(String, String)]) -> Self raise Refused

An empty registry. prefix is prepended to every registered name, and labels is added to every series.

fn Registry::register(Self, String, String, &Metric, unit? : String) -> Unit raise Refused

Register metric under name, with help and an optional unit. The unit is appended to the name on the wire.

fn Registry::sub(Self, prefix~ : String, labels? : Array[(String, String)]) -> Self raise Refused

A sub-registry whose names carry prefix after this registry's own prefix, and whose series carry this registry's labels plus labels.

Also on the type: collect — derived, or required by an implementation above.

struct StateSet Metric

A set of named states, each true or false. A state set with exactly one true state is the Enum of the Python client.

fn StateSet::exclusive(Array[String]) -> Self

A state set with exactly one state true: the first, which is the Python client's default.

fn StateSet::get(Self, String) -> Bool

Whether state is true.

fn StateSet::new(Array[String]) -> Self

A state set whose states all start false, in the order given.

fn StateSet::set(Self, String) -> Unit

Set one state true, leaving the others as they are.

fn StateSet::set_many(Self, Map[String, Bool]) -> Unit

Apply a whole map of states at once.

fn StateSet::unset(Self, String) -> Unit

Set one state false.

Also on the type: kind · points — derived, or required by an implementation above.

struct Summary Metric

A summary: the count and sum of the observations, plus approximate quantiles when the constructor is given target quantiles and their permitted rank error.

fn Summary::new(quantiles? : Array[(Double, Double)], created? : Double) -> Self raise Refused

A summary. With quantiles (pairs of target quantile and permitted error), observations also feed a sketch so that snapshot can report those quantiles; without them the summary carries only count and sum, as the official clients do by default.

fn Summary::observe(Self, Double) -> Unit

Record one observation.

fn Summary::snapshot(Self) -> Point

The snapshot of this summary: the configured quantiles (empty when none were configured), the sum, and the count.

fn Summary::total(Self) -> Int64

The number of observations.

Also on the type: kind · points — derived, or required by an implementation above.

enum Value

The value of one series. A histogram carries its cumulative buckets, sum, and count together so that one series stays one Point; a summary carries its quantiles, sum, and count the same way; a state set carries every state with its flag.

Number(Double)

Buckets(buckets~ : Array[(Double, Int64)], sum~ : Double, count~ : Int64)

Quantiles(quantiles~ : Array[(Double, Double)], sum~ : Double, count~ : Int64)

State(states~ : Array[(String, Bool)])

Traits

trait Collector

A custom source of metric families. Implement this to contribute series whose shape the built-in metric types do not cover; the registry applies its prefix and constant labels to whatever collect returns.

fn Collector::collect(Self) -> Array[MetricFamily]
trait LabelSet

A record that can name its own label pairs. Implementing this for a struct and using TypedFamily gives a family keyed by a typed label set instead of an array of strings.

fn LabelSet::pairs(Self) -> Array[(String, String)]
trait Metric

Anything a registry can collect: a metric, a family of metrics, or a custom collector's contribution. Implement this to plug a new metric shape into a registry without changing the registry.

fn Metric::kind(Self) -> Kind
fn Metric::points(Self) -> Array[Point]
02

expo

moonbitstack/moonp8s/expo

The two text formats, their negotiation from an Accept header, and a parser for both. The float and escape rules are the ones a scraper already implements.

Values

fn escape_help(String, Bool) -> String

Escape help text. The compatibility format escapes backslash and newline; OpenMetrics also escapes the double quote, so help text survives a round trip inside a line-oriented document.

fn escape_label_value(String) -> String

Escape a label value: backslash, double quote, and newline are backslash-escaped, every other character passes through as UTF-8.

fn format_float(Double) -> String

Format a float the way the official clients do: +Inf, -Inf, and NaN by name; otherwise the shortest decimal that round-trips, with a .0 on integers and Go's switch to a two-digit exponent once the integer part is longer than six digits (so 1000000.0 is 1e+06, matching what a Prometheus scrape expects to read).

fn negotiate(String) -> Format

Pick a format from an HTTP Accept header. application/openmetrics-text wins when it names a version this library speaks (or names no version); otherwise a scrape gets the compatibility format, which is also the default when the header is absent or unrecognised.

fn openmetrics(Array[@metric.MetricFamily]) -> String

Write families in the OpenMetrics text format, version 1.0.0, ending with the # EOF marker the format requires.

fn parse(String, format? : Format) -> Array[@metric.MetricFamily] raise @metric.Refused

Parse an exposition back into families. The compatibility format is lossy for info and state sets, which it spells as gauges; OpenMetrics keeps them. The format argument selects which spelling conventions to expect, and the same parser accepts both because the syntax is a superset.

fn protobuf(Array[@metric.MetricFamily]) -> Bytes

Write families in the Prometheus protobuf format: a length-delimited stream of io.prometheus.client.MetricFamily messages, the bytes a scraper reads when it answers application/vnd.google.protobuf. It shares the text formats' snapshot, so one scrape is every format. A family is named as the text format declares it, so a counter is <name>_total with its value in the counter field and an info is <name>_info; a histogram keeps its cumulative buckets, sum, and count, its +Inf bucket being the count; a summary keeps its count, sum, and quantiles; a state set is a gauge per state.

let protobuf_content_type: String

The Content-Type an HTTP response should carry for the protobuf format: the metric family the stream holds and the framing of the messages.

fn text(Array[@metric.MetricFamily]) -> String

Write families in the Prometheus text exposition format, version 0.0.4. Counters gain a _total suffix, info becomes a gauge ending in _info, state sets become gauges, and _created, _gcount, and _gsum series are emitted as separate gauge families, as the compatibility format requires.

fn wants_protobuf(String) -> Bool

Whether an Accept header asks for the protobuf format. It does when any part is the media type the protobuf exposition carries; the two text formats are picked out of the header by negotiate, which never returns a protobuf.

Types and methods

enum Format

The exposition formats this library writes and reads.

Text004

Prometheus text exposition format, version 0.0.4.

OpenMetrics100

OpenMetrics text format, version 1.0.0.

fn Format::content_type(Self) -> String

The Content-Type an HTTP response should carry for this format.

03

push

moonbitstack/moonp8s/push

Push gateway requests — method, path, headers and body — built and handed back. Sending them is the caller's, which is why this package needs no HTTP client.

Values

fn delete(String, String, grouping_key? : Array[(String, String)]) -> PushRequest

Build a DELETE that removes every series under job and grouping_key.

fn push(String, String, Array[@metric.MetricFamily], grouping_key? : Array[(String, String)], format? : @expo.Format) -> PushRequest

Build a PUT that replaces every series under job and grouping_key with the exposition of families.

fn push_add(String, String, Array[@metric.MetricFamily], grouping_key? : Array[(String, String)], format? : @expo.Format) -> PushRequest

Build a POST that replaces only the series named in families, leaving other series under the same job and grouping key alone.

Types and methods

struct PushRequest

A push gateway request: the method, the absolute URL path, the headers, and the body. The caller sends it with whatever HTTP client it has; this package never touches a socket.

http_method
String
path
String
headers
Array[(String, String)]
body
String
04

asgi

moonbitstack/moonp8s/asgi

The /metrics handler and the request-counting middleware, built on moonbitstack/moonasgi.

Values

fn app(@metric.Registry) -> (@http.Request) -> @http.Response

A /metrics handler for a registry. GET negotiates the format from the Accept header, OPTIONS advertises the allowed methods, anything else is refused with 405, and /favicon.ico is answered empty so a browser probing the endpoint stays quiet.

fn middleware(@metric.Registry, now? : () -> Double) -> (((@http.Request) -> @http.Response) -> ((@http.Request) -> @http.Response)) raise @metric.Refused

A middleware that counts handled requests (http_requests, labelled by method, route, and status) and observes their duration in seconds (http_request_duration_seconds, labelled by method and route). The clock is a parameter so a test can drive time; it defaults to wall-clock seconds.

05

compat

moonbitstack/moonp8s/compat

The surface an older caller already has: a counter vector keyed by one label, the server metric set, and the remote report writer — rebuilt on the registry model so it can be replaced one import at a time.

Values

let default_latency_buckets: Array[Double]

The latency buckets the legacy metric package used, in milliseconds.

Types and methods

struct CounterVec @metric.Metric

A counter partitioned by one label string, the shape the legacy metric package exposed. New code should use Family[@metric.Counter]; this exists so an existing call site can move over without being rewritten.

fn CounterVec::add(Self, String, Int64) -> Unit raise @metric.Refused

Add delta to the series named by label, creating it on first sight.

fn CounterVec::inc(Self, String) -> Unit raise @metric.Refused

Increment the series named by label by one.

fn CounterVec::kind(Self) -> @metric.Kind
fn CounterVec::labels(Self) -> Array[String]

The series names seen so far.

fn CounterVec::new(label? : String) -> Self

An empty counter vector whose series are labelled label.

fn CounterVec::points(Self) -> Array[@metric.Point]
fn CounterVec::total(Self) -> Int64

The sum of every series.

fn CounterVec::value(Self, String) -> Int64

The current count of the series named by label.

struct RemoteRequest

A report request, ready for the caller to send: a POST of JSON to the reporting endpoint.

http_method
String
url
String
headers
Array[(String, String)]
body
String
struct RemoteWriter

A remote writer bound to one reporting endpoint.

fn RemoteWriter::new(String) -> Self

A writer for endpoint.

fn RemoteWriter::request(Self, StatReport) -> RemoteRequest

Build the POST a remote writer sends for report.

struct ServerMetrics

The request counter and latency histogram the legacy server metric set exposed: request counts labelled by request signature, and a millisecond latency histogram.

fn ServerMetrics::latency(Self) -> @metric.Histogram

The latency histogram, in milliseconds.

fn ServerMetrics::new() -> Self raise @metric.Refused

A fresh server metric set.

fn ServerMetrics::register(Self, @metric.Registry, prefix? : String) -> Unit raise @metric.Refused

Register both series under the legacy names, optionally prefixed.

fn ServerMetrics::requests(Self) -> CounterVec

The request counter.

struct StatReport

The periodic stat report the legacy remote writer posted as JSON.

name
String
timestamp
Int64
pid
Int64
reqs_per_second
Double
drops
Int64
average
Double
median
Double
top90th
Double
top99th
Double
top99p9th
Double
06

multiproc

moonbitstack/moonp8s/multiproc

How several processes' values become one series: the gauge modes, the record a worker's file holds, its bytes, and the merge. Pure data, so it runs on every target.

Values

fn merge(Array[Part]) -> Array[@metric.MetricFamily] raise @metric.Refused

Fold the parts into one set of families.

Counters and summaries add up across processes; histograms add up per bucket and are made cumulative again; a gauge follows its mode. Families come out in the order their first part mentions them, and series in the order they were first seen, so two runs over the same directory write the same bytes.

A family that two files disagree about — a name that is a counter in one process and a histogram in another, or a gauge written under two modes — is refused. The numbers would be meaningless, and a scrape that says so is better than one that quietly picks a side.

Types and methods

struct Entry

One value in one worker's file: the family it belongs to, the name the sample is written under, its labels, the family's help text, the value, and the time the value was recorded (zero when it was not recorded with one).

The pair of metric and sample is what lets a counter be filed under orders and written as orders_total, and a histogram bucket under orders_seconds and orders_seconds_bucket.

metric
String
sample
String
labels
Array[(String, String)]
help
String
value
Double
timestamp
Double
fn Entry::new(String, String, Array[(String, String)], String, Double, timestamp? : Double) -> Self

One value for a worker's file.

enum Mode

How the values of one gauge from several processes become one series.

A gauge has no natural merge — a counter can be added up, a bucket can be added up, but "requests in flight" from three workers is a policy decision. All and LiveAll keep the processes apart, one series each, labelled pid; the other four collapse them: the smallest, the largest, the sum, or the value set most recently.

The Live spellings mean the same thing at a scrape. They decide what happens when a process exits: mark_dead removes the files of a live mode, and leaves the others, which is what makes a handful of gauges forget a dead worker instead of keeping its last value forever.

All

LiveAll

Min

LiveMin

Max

LiveMax

Sum

LiveSum

MostRecent

LiveMostRecent

fn Mode::code(Self) -> String

The spelling a file name carries: all, liveall, min, livemin, max, livemax, sum, livesum, mostrecent, livemostrecent.

fn Mode::is_live(Self) -> Bool

Whether this mode forgets a process when it exits. mark_dead removes the files of these modes only.

fn Mode::is_most_recent(Self) -> Bool

Whether this mode keeps the value set most recently instead of combining values, which is why a most-recent gauge cannot be stepped with inc.

fn Mode::is_separate(Self) -> Bool

Whether this mode keeps the processes apart, one series per pid.

fn Mode::of(String) -> Self raise @metric.Refused

The mode a file name spells. An unknown spelling is refused: it would change what the numbers mean, which is worse than a failed scrape.

struct Part

One worker's file, decoded: whose it is, what kind of metric it holds, the gauge mode it was written for, and its values.

pid
String

The process the file belongs to, as the pid label carries it.

kind
@metric.Kind
mode
Mode?

The gauge mode, for a file of gauges; None for every other kind.

entries
Array[Entry]
fn Part::decode(String, Bytes) -> Self raise @metric.Refused

Decode one worker's file. A file shorter than its header claims is refused rather than half-read: a torn file means a writer that does not write whole files, and guessing at the remainder would report numbers nobody wrote.

fn Part::encode(Self) -> Bytes

The bytes of this part: a four-byte used count, four bytes of padding, then one record per entry — a key length, the key, padding to an eight-byte boundary, the value, and the timestamp, each value a little-endian double.

This is the layout the official clients' multiprocess mode uses, which is the point: a directory of these files is readable by them and by this library alike.

fn Part::file_name(Self) -> String

The name this part is stored under: <kind>_<pid>.db, or gauge_<mode>_<pid>.db for gauges, which is the layout the official clients read and write.

fn Part::name_of(String) -> (String, @metric.Kind, Mode?) raise @metric.Refused

The part a file name announces. A gauge file carries its mode in the name because the mode is a property of how the worker wrote the value, and the scrape has no other way to learn it.

fn Part::new(String, @metric.Kind, Mode?, Array[Entry]) -> Self

One worker's file.

07

multiproc/directory

moonbitstack/moonp8s/multiproc/directory

The directory the worker files live in. Native only: writing a process's file, reading them all at a scrape, and forgetting the gauges of a process that has exited.

Types and methods

struct Written

What one flush left behind: how many files it wrote, how many series they hold, and the families it could not share between processes.

files
Int32
entries
Int32
skipped
Array[String]

Families of a kind that has no cross-process meaning — an info metric, a state set, a gauge histogram — left out by name rather than dropped quietly.