mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-17 15:51:23 +01:00
set up opentelemetry for metrics
Also adds an `allow_prometheus` option (disabled by default) to expose a `/metrics` endpoint that returns Prometheus data.
This commit is contained in:
parent
94fda7c875
commit
a0b92c82e8
5 changed files with 97 additions and 2 deletions
|
|
@ -60,6 +60,8 @@ pub(crate) struct Config {
|
|||
#[serde(default = "false_fn")]
|
||||
pub(crate) allow_jaeger: bool,
|
||||
#[serde(default = "false_fn")]
|
||||
pub(crate) allow_prometheus: bool,
|
||||
#[serde(default = "false_fn")]
|
||||
pub(crate) tracing_flame: bool,
|
||||
#[serde(default)]
|
||||
pub(crate) proxy: ProxyConfig,
|
||||
|
|
|
|||
|
|
@ -412,6 +412,15 @@ fn routes(config: &Config) -> Router {
|
|||
.put(c2s::send_state_event_for_empty_key_route),
|
||||
);
|
||||
|
||||
let router = if config.allow_prometheus {
|
||||
router.route(
|
||||
"/metrics",
|
||||
get(|| async { observability::METRICS.export() }),
|
||||
)
|
||||
} else {
|
||||
router
|
||||
};
|
||||
|
||||
let router = router
|
||||
.route(
|
||||
"/_matrix/client/r0/rooms/:room_id/initialSync",
|
||||
|
|
|
|||
|
|
@ -3,13 +3,17 @@
|
|||
|
||||
use std::{fs::File, io::BufWriter};
|
||||
|
||||
use opentelemetry::KeyValue;
|
||||
use opentelemetry_sdk::Resource;
|
||||
use once_cell::sync::Lazy;
|
||||
use opentelemetry::{metrics::MeterProvider, KeyValue};
|
||||
use opentelemetry_sdk::{metrics::SdkMeterProvider, Resource};
|
||||
use tracing_flame::{FlameLayer, FlushGuard};
|
||||
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Layer, Registry};
|
||||
|
||||
use crate::{config::Config, error, utils::error::Result};
|
||||
|
||||
/// Globally accessible metrics state
|
||||
pub(crate) static METRICS: Lazy<Metrics> = Lazy::new(Metrics::new);
|
||||
|
||||
/// Cleans up resources relating to observability when [`Drop`]ped
|
||||
pub(crate) struct Guard {
|
||||
/// Drop guard used to flush [`tracing_flame`] data on exit
|
||||
|
|
@ -85,3 +89,43 @@ fn standard_resource() -> Resource {
|
|||
env!("CARGO_PKG_NAME"),
|
||||
)]))
|
||||
}
|
||||
|
||||
/// Holds state relating to metrics
|
||||
pub(crate) struct Metrics {
|
||||
/// Internal state for OpenTelemetry metrics
|
||||
///
|
||||
/// We never directly read from [`SdkMeterProvider`], but it needs to
|
||||
/// outlive all calls to `self.otel_state.0.gather()`, otherwise
|
||||
/// metrics collection will fail.
|
||||
otel_state: (prometheus::Registry, SdkMeterProvider),
|
||||
}
|
||||
|
||||
impl Metrics {
|
||||
/// Initializes metric-collecting and exporting facilities
|
||||
fn new() -> Self {
|
||||
// Set up OpenTelemetry state
|
||||
let registry = prometheus::Registry::new();
|
||||
let exporter = opentelemetry_prometheus::exporter()
|
||||
.with_registry(registry.clone())
|
||||
.build()
|
||||
.expect("exporter configuration should be valid");
|
||||
let provider = SdkMeterProvider::builder()
|
||||
.with_reader(exporter)
|
||||
.with_resource(standard_resource())
|
||||
.build();
|
||||
let _meter = provider.meter(env!("CARGO_PKG_NAME"));
|
||||
|
||||
// TODO: Add some metrics
|
||||
|
||||
Metrics {
|
||||
otel_state: (registry, provider),
|
||||
}
|
||||
}
|
||||
|
||||
/// Export metrics to a string suitable for consumption by e.g. Prometheus
|
||||
pub(crate) fn export(&self) -> String {
|
||||
prometheus::TextEncoder::new()
|
||||
.encode_to_string(&self.otel_state.0.gather())
|
||||
.expect("should be able to encode metrics")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue