Crates.io | goodmetrics |
lib.rs | goodmetrics |
version | 6.0.0 |
source | src |
created_at | 2022-11-23 04:29:57.9754 |
updated_at | 2024-07-30 23:03:30.139393 |
description | Unlimited cardinality, fast metrics recording - for services |
homepage | |
repository | https://github.com/kvc0/goodmetrics_rs |
max_upload_size | |
id | 721353 |
size | 268,973 |
This is the Rust goodmetrics client. It bundles an opentelemetry protocol downstream and some performance tools like the PooledMetricsAllocator. To use any grpc downstream (goodmetrics or opentelemetry) you will need a tokio runtime.
See the lightstep demo for a complete setup and usage example with opentelemetry.
Once you have a configured MetricsFactory, the way you use Metrics does not change with subsequent updates to the configured downstream(s):
let mut metrics = metrics_factory.record_scope("demo"); // By default, includes a "demo_totaltime" histogram measurement, capturing the time it took to complete the unit of work
{
let _scope = metrics.time("timed_delay"); // you can time additional scopes
my_timed_delay();
}
metrics.measurement("ran", 1); // measurements can be plain numbers; when preaggregated they are StatisticSets (min/max/sum/count)
metrics.sum("runs_count", 1); // If you do not need a StatisticSet but rather a simple counter,
// sum will produce a simple Gauge
metrics.dimension("mod", i % 8); // you can add dimensions to a Metrics whenever you want. All measurements in this Metrics record are dimensioned by this value.
metrics.distribution("some_continuous_value", instantaneous_network_bandwidth); // histograms are aggregated sparsely, and truncated to 2 significant figures (base 10).
Once the metrics
object is dropped from scope, it will export metrics to your desired ingest. If you need to publish metrics at some immediate point, you can manually drop()
the object.
Not every unit of work needs a measurement of how long it took to complete. Simply create a metrics object by calling record_scope_with_behavior
and passing in your desired behavior.
For example:
let mut metrics = metrics_factory.record_scope_with_behavior(
"demo",
MetricsBehavior::SuppressTotalTime,
);
In a distributed system, a unit of work may not fully complete and the metrics
object will fall out of scope, causing any existing dimensions or measurements to be exported. This can lead to confusing behavior if a dimension was expected, but not present.
Using a guarded_dimension
can provide a default value and export it should the object be dropped before expected:
let mut metrics = metrics_factory.record_scope("demo");
let result_dimension = metrics.guarded_dimension("my_api_result", "dropped_early");
// Perform work...
let result = serve_api_request(request);
match result {
Ok(_) => {
// Explicitly set the guarded dimension and overwrite the default value
result_dimension.set("ok")
},
Err(_e) => {
// Explicitly set the guarded dimension and overwrite the default value
result_dimension.set("error");
metrics.sum("errors", 1_u64)
}
}
Latest docs can always be found on docs.rs.
metrics.measurement("name", value)
min
, max
, sum
, and count
of data points received.sum()
instead if you only need sum
or count
.distribution()
instead if you need percentiles of values.StatisticsSet
metrics.distribution("name", value)
Histogram
or ExponentialHistogram
depending on configuration.metrics.sum("name", value)
Adds up all the sum calls for "name" within each reporting period.
Sum
.let _guard = metrics.time("name")
Histogram
or ExponentialHistogram
, depending on configuration.Use cargo ws version minor
to update version.