Metrics
Metrics are an effective approach to monitoring applications at scale. They can be cheap to collect, making them suitable for performance sensitive operations. They can also be compact to report, making them suitable for high-volume scenarios.
emit
doesn't provide its own definitions of types like gauges and counters that you can set or increment. The way you define, store, and track metrics in your application will depend on your specific needs. emit
becomes involved at the point you want to send samples you collect of your metrics to external systems. It does this by representing the values you sample as events with well-known properties:
flowchart meter["`**meter/instrument** _Atomic integers, local variables_`"] -- sample --> emit emit["`**emit event** _Events in the metrics data model_ `"]
Emitters that are metric-aware, like emit_otlp
, can then handle those samples differently from regular events.
The sample!
macro
In emit
, metric samples are events that represent an aggregation of their underlying source into a value at a particular point in time, or over a particular time range. These samples can be constructed and emitted using the sample!
macro.
A standard kind of metric is a monotonic counter, which can be represented as an atomic integer. In this example, our counter is for the number of bytes written to a file, which we'll call bytes_written
. We can report a sample of this counter:
#![allow(unused)] fn main() { extern crate emit; fn sample_bytes_written() -> usize { 4643 } // `sample_bytes_written` is an application-specific method to read your metric values let bytes_written: usize = sample_bytes_written(); // The `sample!` macro wraps the sample into an event and emits it through the diagnostic pipeline emit::sample!(value: bytes_written, agg: "count"); }
Event {
mdl: "my_app",
tpl: "{metric_agg} of {metric_name} is {metric_value}",
extent: Some(
"2024-04-29T10:08:24.780230000Z",
),
props: {
"evt_kind": metric,
"metric_name": "bytes_written",
"metric_agg": "count",
"metric_value": 4643,
},
}
Note that the type of a sample value isn't required to be an integer as in the previous example. It can be any value, including floating points, booleans, strings, and objects. It's best to stick to numeric types though for the broadest compatibility.
emit
also defines macros for producing metric samples for specific aggregations:
count_sample!
for samples of a monotonic counter.sum_sample!
for samples of a non-monotonic sum.min_sample!
for samples of the minimum observed value.max_sample!
for samples of the maximum observed value.last_sample!
for samples of the latest value.
A metric produced by this example application in Prometheus.