Skip to content

Commit

Permalink
move to opentelemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
aumetra committed Oct 21, 2023
1 parent cc1aa20 commit 9a6dc9b
Show file tree
Hide file tree
Showing 13 changed files with 338 additions and 145 deletions.
290 changes: 239 additions & 51 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exclude = ["xtask"]
members = [
"crates/kitsune-cache",
"crates/kitsune-captcha",
"crates/kitsune-config",
"crates/kitsune-core",
"crates/kitsune-db",
"crates/kitsune-email",
Expand All @@ -22,6 +23,7 @@ members = [
"crates/kitsune-http-signatures",
"crates/kitsune-language",
"crates/kitsune-messaging",
"crates/kitsune-observability",
"crates/kitsune-retry-policies",
"crates/kitsune-search",
"crates/kitsune-storage",
Expand Down
11 changes: 11 additions & 0 deletions crates/kitsune-config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "kitsune-config"
edition.workspace = true
version.workspace = true

[dependencies]
eyre = "0.6.8"
serde = { version = "1.0.189", features = ["derive"] }
smol_str = { version = "0.2.0", features = ["serde"] }
tokio = { version = "1.33.0", features = ["fs"] }
toml = "0.8.2"
File renamed without changes.
6 changes: 4 additions & 2 deletions crates/kitsune-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ async-recursion = "1.0.5"
async-stream = "0.3.5"
async-trait = "0.1.74"
athena = { path = "../../lib/athena" }
autometrics = { version = "0.6.0", default-features = false }
autometrics = { version = "0.6.0", default-features = false, features = [
"metrics",
] }
base64-simd = "0.8.0"
bytes = "1.5.0"
const_format = "0.2.32"
Expand All @@ -34,6 +36,7 @@ img-parts = "0.3.0"
iso8601-timestamp = "0.2.12"
kitsune-cache = { path = "../kitsune-cache" }
kitsune-captcha = { path = "../kitsune-captcha" }
kitsune-config = { path = "../kitsune-config" }
kitsune-db = { path = "../kitsune-db" }
kitsune-email = { path = "../kitsune-email" }
kitsune-embed = { path = "../kitsune-embed" }
Expand Down Expand Up @@ -75,7 +78,6 @@ zxcvbn = { version = "2.2.2", default-features = false }
default = []
mastodon-api = []
meilisearch = ["kitsune-search/meilisearch"]
metrics = ["autometrics/metrics"]

[build-dependencies]
vergen = { version = "8.2.5", features = ["build", "git", "gitcl"] }
Expand Down
9 changes: 4 additions & 5 deletions crates/kitsune-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ extern crate tracing;

pub mod activitypub;
pub mod blocking;
pub mod config;
pub mod consts;
pub mod error;
pub mod event;
Expand All @@ -29,10 +28,6 @@ pub mod webfinger;

use self::{
activitypub::Fetcher,
config::{
CacheConfiguration, CaptchaConfiguration, Configuration, EmailConfiguration,
MessagingConfiguration, SearchConfiguration, StorageConfiguration,
},
job::KitsuneContextRepo,
resolve::PostResolver,
service::{
Expand All @@ -48,6 +43,10 @@ use athena::JobQueue;
use eyre::Context;
use kitsune_cache::{ArcCache, InMemoryCache, NoopCache, RedisCache};
use kitsune_captcha::{hcaptcha::Captcha as HCaptcha, mcaptcha::Captcha as MCaptcha, Captcha};
use kitsune_config::{
CacheConfiguration, CaptchaConfiguration, Configuration, EmailConfiguration,
MessagingConfiguration, SearchConfiguration, StorageConfiguration,
};
use kitsune_db::PgPool;
use kitsune_email::{
lettre::{message::Mailbox, AsyncSmtpTransport, Tokio1Executor},
Expand Down
25 changes: 25 additions & 0 deletions crates/kitsune-observability/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "kitsune-observability"
edition.workspace = true
version.workspace = true

[dependencies]
eyre = "0.6.8"
kitsune-config = { path = "../kitsune-config" }
metrics = "0.21.1"
metrics-opentelemetry = { git = "https://github.com/aumetra/metrics-opentelemetry.git", rev = "7c3176266c215bb9a7cbc31b3c32f75a22824928" }
metrics-tracing-context = "0.14.0"
metrics-util = "0.15.1"
opentelemetry-otlp = { version = "0.13.0", default-features = false, features = [
"http-proto",
"metrics",
"trace",
] }
opentelemetry = { version = "0.20.0", default-features = false, features = [
"rt-tokio",
"trace",
] }
tracing = "0.1.40"
tracing-error = "0.2.0"
tracing-opentelemetry = { version = "0.21.0", default-features = false }
tracing-subscriber = "0.3.17"
46 changes: 46 additions & 0 deletions crates/kitsune-observability/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use eyre::Context;
use kitsune_config::Configuration;
use metrics_opentelemetry::OpenTelemetryRecorder;
use opentelemetry::{metrics::MeterProvider, trace::Tracer};
use std::env;
use tracing_error::ErrorLayer;
use tracing_opentelemetry::OpenTelemetryLayer;
use tracing_subscriber::{
filter::{LevelFilter, Targets},
layer::SubscriberExt,
Layer, Registry,
};

fn initialise_metrics<S, M>(config: &Configuration, meter_provider: M) -> impl Layer<S>
where
S: for<'a> tracing_subscriber::registry::LookupSpan<'a> + tracing::Subscriber,
M: MeterProvider,
{
use metrics_tracing_context::{MetricsLayer, TracingContextLayer};
use metrics_util::layers::Layer as _;

let recorder = TracingContextLayer::all()
.layer(OpenTelemetryRecorder::new(meter_provider.meter("kitsune")));
metrics::set_boxed_recorder(Box::new(recorder)).unwrap();

MetricsLayer::new()
}

fn initialise_logging(config: &Configuration) -> eyre::Result<()> {
let env_filter = env::var("RUST_LOG")
.map_err(eyre::Report::from)
.and_then(|targets| targets.parse().context("Failed to parse RUST_LOG value"))
.unwrap_or_else(|_| Targets::default().with_default(LevelFilter::INFO));

let subscriber = Registry::default()
.with(tracing_subscriber::fmt::layer().with_filter(env_filter))
.with(ErrorLayer::default())
.with(OpenTelemetryLayer::new());

let subscriber = subscriber.with(initialise_metrics(config));

tracing::subscriber::set_global_default(subscriber)
.context("Couldn't install the global tracing subscriber")?;

Ok(())
}
26 changes: 6 additions & 20 deletions kitsune/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ http = "0.2.9"
human-panic = "1.2.1"
hyper = { version = "0.14.27", features = ["deprecated"] }
iso8601-timestamp = "0.2.12"
mimalloc = "0.1.39"
mime = "0.3.17"
mime_guess = { version = "2.0.4", default-features = false }
pkcs8 = "0.10.2"
kitsune-cache = { path = "../crates/kitsune-cache" }
kitsune-captcha = { path = "../crates/kitsune-captcha" }
kitsune-core = { path = "../crates/kitsune-core" }
Expand All @@ -52,6 +48,11 @@ kitsune-language = { path = "../crates/kitsune-language" }
kitsune-search = { path = "../crates/kitsune-search" }
kitsune-storage = { path = "../crates/kitsune-storage" }
kitsune-type = { path = "../crates/kitsune-type" }
metrics = "0.21.1"
mimalloc = "0.1.39"
mime = "0.3.17"
mime_guess = { version = "2.0.4", default-features = false }
pkcs8 = "0.10.2"
oxide-auth = "0.5.4"
oxide-auth-async = "0.1.1"
oxide-auth-axum = "0.3.0"
Expand Down Expand Up @@ -94,13 +95,6 @@ async-graphql = { version = "6.0.9", default-features = false, features = [
], optional = true }
async-graphql-axum = { version = "6.0.9", optional = true }

# "metrics" feature
axum-prometheus = { version = "0.4.0", optional = true }
metrics = { version = "0.21.1", optional = true }
metrics-exporter-prometheus = { version = "0.12.1", optional = true }
metrics-tracing-context = { version = "0.14.0", optional = true }
metrics-util = { version = "0.15.1", optional = true }

# "oidc" feature
openidconnect = { version = "3.4.0", default-features = false, optional = true }

Expand All @@ -111,20 +105,12 @@ serial_test = "2.0.0"
tower = "0.4.13"

[features]
default = ["graphql-api", "mastodon-api", "metrics"]
default = ["graphql-api", "mastodon-api"]
graphql-api = [
"dep:async-graphql",
"dep:async-graphql-axum",
"speedy-uuid/async-graphql",
]
mastodon-api = ["kitsune-core/mastodon-api"]
meilisearch = ["kitsune-core/meilisearch"]
metrics = [
"kitsune-core/metrics",
"dep:axum-prometheus",
"dep:metrics",
"dep:metrics-exporter-prometheus",
"dep:metrics-tracing-context",
"dep:metrics-util",
]
oidc = ["dep:openidconnect"]
1 change: 0 additions & 1 deletion kitsune/src/http/handler/users/inbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ pub async fn post(
State(federation_filter): State<FederationFilterService>,
SignedActivity(author, activity): SignedActivity,
) -> Result<()> {
#[cfg(feature = "metrics")]
increment_counter!("received_activities");

if !federation_filter
Expand Down
8 changes: 0 additions & 8 deletions kitsune/src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,6 @@ pub fn create_router(state: Zustand, server_config: &ServerConfiguration) -> Rou
ServeDir::new(frontend_dir.as_str()).fallback(ServeFile::new(frontend_index_path)),
);

#[cfg(feature = "metrics")]
{
use axum_prometheus::PrometheusMetricLayer;

// Even though this explicity has "prometheus" in the name, it just emits regular `metrics` calls
router = router.layer(PrometheusMetricLayer::new());
}

router
.layer(CatchPanicLayer::new())
.layer(CorsLayer::permissive())
Expand Down
1 change: 0 additions & 1 deletion kitsune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
forbidden_lint_groups
)]

#[cfg(feature = "metrics")]
#[macro_use]
extern crate metrics;

Expand Down
58 changes: 1 addition & 57 deletions kitsune/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::{
};
use tracing::level_filters::LevelFilter;
use tracing_error::ErrorLayer;
use tracing_opentelemetry::OpenTelemetryLayer;
use tracing_subscriber::{filter::Targets, layer::SubscriberExt, Layer, Registry};
use url::Url;

Expand Down Expand Up @@ -50,63 +51,6 @@ fn install_handlers() -> eyre::Result<()> {
Ok(())
}

#[cfg(feature = "metrics")]
fn initialise_metrics<S>(config: &Configuration) -> impl Layer<S>
where
S: for<'a> tracing_subscriber::registry::LookupSpan<'a> + tracing::Subscriber,
{
use axum_prometheus::{
utils::SECONDS_DURATION_BUCKETS, AXUM_HTTP_REQUESTS_DURATION_SECONDS,
PREFIXED_HTTP_REQUESTS_DURATION_SECONDS,
};
use metrics_exporter_prometheus::{Matcher, PrometheusBuilder};
use metrics_tracing_context::{MetricsLayer, TracingContextLayer};
use metrics_util::layers::Layer as _;

let (prometheus_recorder, server_future) = PrometheusBuilder::new()
// Some defaults that would have been set by the `axum-prometheus` crate
.set_buckets_for_metric(
Matcher::Full(
PREFIXED_HTTP_REQUESTS_DURATION_SECONDS
.get()
.map_or(AXUM_HTTP_REQUESTS_DURATION_SECONDS, |s| s.as_str())
.to_string(),
),
SECONDS_DURATION_BUCKETS,
)
.unwrap()
.with_http_listener(([0, 0, 0, 0], config.server.prometheus_port))
.build()
.unwrap();

tokio::spawn(server_future);

let recorder = TracingContextLayer::all().layer(prometheus_recorder);
metrics::set_boxed_recorder(Box::new(recorder)).unwrap();

MetricsLayer::new()
}

fn initialise_logging(_config: &Configuration) -> eyre::Result<()> {
let env_filter = env::var("RUST_LOG")
.map_err(eyre::Report::from)
.and_then(|targets| targets.parse().context("Failed to parse RUST_LOG value"))
.unwrap_or_else(|_| Targets::default().with_default(LevelFilter::INFO));

let subscriber = Registry::default()
.with(tracing_subscriber::fmt::layer().with_filter(env_filter))
.with(ErrorLayer::default());

#[cfg(feature = "metrics")]
#[allow(clippy::used_underscore_binding)]
let subscriber = subscriber.with(initialise_metrics(_config));

tracing::subscriber::set_global_default(subscriber)
.context("Couldn't install the global tracing subscriber")?;

Ok(())
}

fn postgres_url_diagnostics(db_url: &str) -> String {
let url = match Url::parse(db_url) {
Ok(url) => url,
Expand Down

0 comments on commit 9a6dc9b

Please sign in to comment.