mirror of
https://github.com/LemmyNet/lemmy
synced 2024-11-10 06:54:12 +00:00
Remove opentelemetry (#4741)
* Remove opentelemetry * remove unused deps, use backtrace * always print db migration messages regardless of log level (fixes #4725) * fix ci * Remove useless root span builder --------- Co-authored-by: SleeplessOne1917 <28871516+SleeplessOne1917@users.noreply.github.com>
This commit is contained in:
parent
ef49a0eb8d
commit
c90ee3094d
10 changed files with 489 additions and 1095 deletions
|
@ -157,7 +157,7 @@ steps:
|
|||
CARGO_HOME: .cargo_home
|
||||
commands:
|
||||
- rustup component add clippy
|
||||
- cargo clippy --workspace --tests --all-targets --features console -- -D warnings
|
||||
- cargo clippy --workspace --tests --all-targets -- -D warnings
|
||||
when: *slow_check_paths
|
||||
|
||||
cargo_build:
|
||||
|
|
1344
Cargo.lock
generated
1344
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
21
Cargo.toml
21
Cargo.toml
|
@ -37,15 +37,6 @@ debug = 0
|
|||
|
||||
[features]
|
||||
embed-pictrs = ["pict-rs"]
|
||||
# This feature requires building with `tokio_unstable` flag, see documentation:
|
||||
# https://docs.rs/tokio/latest/tokio/#unstable-features
|
||||
console = [
|
||||
"console-subscriber",
|
||||
"opentelemetry",
|
||||
"opentelemetry-otlp",
|
||||
"tracing-opentelemetry",
|
||||
"reqwest-tracing/opentelemetry_0_16",
|
||||
]
|
||||
json-log = ["tracing-subscriber/json"]
|
||||
default = []
|
||||
|
||||
|
@ -117,9 +108,7 @@ actix-web = { version = "4.8.0", default-features = false, features = [
|
|||
"cookies",
|
||||
] }
|
||||
tracing = "0.1.40"
|
||||
tracing-actix-web = { version = "0.7.11", default-features = false }
|
||||
tracing-error = "0.2.0"
|
||||
tracing-log = "0.2.0"
|
||||
tracing-actix-web = { version = "0.7.10", default-features = false }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
url = { version = "2.5.2", features = ["serde"] }
|
||||
reqwest = { version = "0.11.27", default-features = false, features = [
|
||||
|
@ -154,8 +143,6 @@ itertools = "0.13.0"
|
|||
futures = "0.3.30"
|
||||
http = "0.2.12"
|
||||
rosetta-i18n = "0.1.3"
|
||||
opentelemetry = { version = "0.19.0", features = ["rt-tokio"] }
|
||||
tracing-opentelemetry = { version = "0.19.0" }
|
||||
ts-rs = { version = "7.1.1", features = [
|
||||
"serde-compat",
|
||||
"chrono-impl",
|
||||
|
@ -188,8 +175,6 @@ diesel-async = { workspace = true }
|
|||
actix-web = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-actix-web = { workspace = true }
|
||||
tracing-error = { workspace = true }
|
||||
tracing-log = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
url = { workspace = true }
|
||||
reqwest = { workspace = true }
|
||||
|
@ -197,10 +182,6 @@ reqwest-middleware = { workspace = true }
|
|||
reqwest-tracing = { workspace = true }
|
||||
clokwerk = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tracing-opentelemetry = { workspace = true, optional = true }
|
||||
opentelemetry = { workspace = true, optional = true }
|
||||
console-subscriber = { version = "0.4.0", optional = true }
|
||||
opentelemetry-otlp = { version = "0.12.0", optional = true }
|
||||
pict-rs = { version = "0.5.16", optional = true }
|
||||
rustls = { workspace = true }
|
||||
tokio.workspace = true
|
||||
|
|
|
@ -2,7 +2,6 @@ use anyhow::Context;
|
|||
use diesel::{connection::SimpleConnection, Connection, PgConnection};
|
||||
use diesel_migrations::{EmbeddedMigrations, MigrationHarness};
|
||||
use lemmy_utils::error::LemmyError;
|
||||
use tracing::info;
|
||||
|
||||
const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
||||
|
||||
|
@ -34,7 +33,7 @@ pub fn run(db_url: &str) -> Result<(), LemmyError> {
|
|||
// transaction as `REPLACEABLE_SCHEMA`. This code will be becone less hacky when the conditional
|
||||
// setup of things in `REPLACEABLE_SCHEMA` is done without using the number of pending
|
||||
// migrations.
|
||||
info!("Running Database migrations (This may take a long time)...");
|
||||
println!("Running Database migrations (This may take a long time)...");
|
||||
let migrations = conn
|
||||
.pending_migrations(MIGRATIONS)
|
||||
.map_err(|e| anyhow::anyhow!("Couldn't determine pending migrations: {e}"))?;
|
||||
|
@ -60,7 +59,7 @@ pub fn run(db_url: &str) -> Result<(), LemmyError> {
|
|||
|
||||
Ok(())
|
||||
})?;
|
||||
info!("Database migrations complete.");
|
||||
println!("Database migrations complete.");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ full = [
|
|||
"dep:actix-web",
|
||||
"dep:serde_json",
|
||||
"dep:anyhow",
|
||||
"dep:tracing-error",
|
||||
"dep:http",
|
||||
"dep:deser-hjson",
|
||||
"dep:regex",
|
||||
|
@ -53,7 +52,6 @@ full = [
|
|||
[dependencies]
|
||||
regex = { workspace = true, optional = true }
|
||||
tracing = { workspace = true, optional = true }
|
||||
tracing-error = { workspace = true, optional = true }
|
||||
itertools = { workspace = true, optional = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use cfg_if::cfg_if;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::{backtrace::Backtrace, fmt::Debug};
|
||||
use strum::{Display, EnumIter};
|
||||
|
||||
#[derive(Display, Debug, Serialize, Deserialize, Clone, PartialEq, Eq, EnumIter, Hash)]
|
||||
|
@ -186,14 +186,13 @@ pub enum LemmyErrorType {
|
|||
cfg_if! {
|
||||
if #[cfg(feature = "full")] {
|
||||
|
||||
use tracing_error::SpanTrace;
|
||||
use std::fmt;
|
||||
pub type LemmyResult<T> = Result<T, LemmyError>;
|
||||
|
||||
pub struct LemmyError {
|
||||
pub error_type: LemmyErrorType,
|
||||
pub inner: anyhow::Error,
|
||||
pub context: SpanTrace,
|
||||
pub context: Backtrace,
|
||||
}
|
||||
|
||||
/// Maximum number of items in an array passed as API parameter. See [[LemmyErrorType::TooManyItems]]
|
||||
|
@ -208,7 +207,7 @@ cfg_if! {
|
|||
LemmyError {
|
||||
error_type: LemmyErrorType::Unknown(format!("{}", &cause)),
|
||||
inner: cause,
|
||||
context: SpanTrace::capture(),
|
||||
context: Backtrace::capture(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +252,7 @@ cfg_if! {
|
|||
LemmyError {
|
||||
error_type,
|
||||
inner,
|
||||
context: SpanTrace::capture(),
|
||||
context: Backtrace::capture(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +266,7 @@ cfg_if! {
|
|||
self.map_err(|error| LemmyError {
|
||||
error_type,
|
||||
inner: error.into(),
|
||||
context: SpanTrace::capture(),
|
||||
context: Backtrace::capture(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
57
src/lib.rs
57
src/lib.rs
|
@ -1,17 +1,10 @@
|
|||
pub mod api_routes_http;
|
||||
pub mod code_migrations;
|
||||
pub mod prometheus_metrics;
|
||||
pub mod root_span_builder;
|
||||
pub mod scheduled_tasks;
|
||||
pub mod session_middleware;
|
||||
#[cfg(feature = "console")]
|
||||
pub mod telemetry;
|
||||
|
||||
use crate::{
|
||||
code_migrations::run_advanced_migrations,
|
||||
root_span_builder::QuieterRootSpanBuilder,
|
||||
session_middleware::SessionMiddleware,
|
||||
};
|
||||
use crate::{code_migrations::run_advanced_migrations, session_middleware::SessionMiddleware};
|
||||
use activitypub_federation::config::{FederationConfig, FederationMiddleware};
|
||||
use actix_cors::Cors;
|
||||
use actix_web::{
|
||||
|
@ -55,14 +48,9 @@ use prometheus_metrics::serve_prometheus;
|
|||
use reqwest_middleware::ClientBuilder;
|
||||
use reqwest_tracing::TracingMiddleware;
|
||||
use serde_json::json;
|
||||
use std::{env, ops::Deref, time::Duration};
|
||||
use std::{ops::Deref, time::Duration};
|
||||
use tokio::signal::unix::SignalKind;
|
||||
use tracing::subscriber::set_global_default;
|
||||
use tracing_actix_web::TracingLogger;
|
||||
use tracing_error::ErrorLayer;
|
||||
use tracing_log::LogTracer;
|
||||
use tracing_subscriber::{filter::Targets, layer::SubscriberExt, Layer, Registry};
|
||||
use url::Url;
|
||||
use tracing_actix_web::{DefaultRootSpanBuilder, TracingLogger};
|
||||
|
||||
/// Timeout for HTTP requests while sending activities. A longer timeout provides better
|
||||
/// compatibility with other ActivityPub software that might allocate more time for synchronous
|
||||
|
@ -119,7 +107,7 @@ pub struct CmdArgs {
|
|||
/// Placing the main function in lib.rs allows other crates to import it and embed Lemmy
|
||||
pub async fn start_lemmy_server(args: CmdArgs) -> LemmyResult<()> {
|
||||
// Print version number to log
|
||||
println!("Lemmy v{VERSION}");
|
||||
println!("Starting Lemmy v{VERSION}");
|
||||
|
||||
// return error 503 while running db migrations and startup tasks
|
||||
let mut startup_server_handle = None;
|
||||
|
@ -318,7 +306,7 @@ fn create_http_server(
|
|||
))
|
||||
.wrap(middleware::Compress::default())
|
||||
.wrap(cors_config)
|
||||
.wrap(TracingLogger::<QuieterRootSpanBuilder>::new())
|
||||
.wrap(TracingLogger::<DefaultRootSpanBuilder>::new())
|
||||
.wrap(ErrorHandlers::new().default_handler(jsonify_plain_text_errors))
|
||||
.app_data(Data::new(context.clone()))
|
||||
.app_data(Data::new(rate_limit_cell.clone()))
|
||||
|
@ -373,38 +361,3 @@ fn cors_config(settings: &Settings) -> Cors {
|
|||
.max_age(3600),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_logging(opentelemetry_url: &Option<Url>) -> LemmyResult<()> {
|
||||
LogTracer::init()?;
|
||||
|
||||
let log_description = env::var("RUST_LOG").unwrap_or_else(|_| "info".into());
|
||||
|
||||
let targets = log_description
|
||||
.trim()
|
||||
.trim_matches('"')
|
||||
.parse::<Targets>()?;
|
||||
|
||||
let format_layer = {
|
||||
#[cfg(feature = "json-log")]
|
||||
let layer = tracing_subscriber::fmt::layer().with_ansi(false).json();
|
||||
#[cfg(not(feature = "json-log"))]
|
||||
let layer = tracing_subscriber::fmt::layer().with_ansi(false);
|
||||
|
||||
layer.with_filter(targets.clone())
|
||||
};
|
||||
|
||||
let subscriber = Registry::default()
|
||||
.with(format_layer)
|
||||
.with(ErrorLayer::default());
|
||||
|
||||
if let Some(_url) = opentelemetry_url {
|
||||
#[cfg(feature = "console")]
|
||||
telemetry::init_tracing(_url.as_ref(), subscriber, targets)?;
|
||||
#[cfg(not(feature = "console"))]
|
||||
tracing::error!("Feature `console` must be enabled for opentelemetry tracing");
|
||||
} else {
|
||||
set_global_default(subscriber)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -1,12 +1,18 @@
|
|||
use clap::Parser;
|
||||
use lemmy_server::{init_logging, start_lemmy_server, CmdArgs};
|
||||
use lemmy_utils::{error::LemmyResult, settings::SETTINGS};
|
||||
use lemmy_server::{start_lemmy_server, CmdArgs};
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
pub extern crate rustls;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() -> LemmyResult<()> {
|
||||
init_logging(&SETTINGS.opentelemetry_url)?;
|
||||
let filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::INFO.into())
|
||||
.from_env_lossy();
|
||||
tracing_subscriber::fmt().with_env_filter(filter).init();
|
||||
|
||||
let args = CmdArgs::parse();
|
||||
|
||||
rustls::crypto::ring::default_provider()
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
use actix_web::{http::StatusCode, ResponseError};
|
||||
use tracing::Span;
|
||||
use tracing_actix_web::RootSpanBuilder;
|
||||
|
||||
// Code in this module adapted from DefaultRootSpanBuilder
|
||||
// https://github.com/LukeMathWalker/tracing-actix-web/blob/main/src/root_span_builder.rs
|
||||
// and root_span!
|
||||
// https://github.com/LukeMathWalker/tracing-actix-web/blob/main/src/root_span_macro.rs
|
||||
|
||||
pub struct QuieterRootSpanBuilder;
|
||||
|
||||
impl RootSpanBuilder for QuieterRootSpanBuilder {
|
||||
fn on_request_start(request: &actix_web::dev::ServiceRequest) -> Span {
|
||||
let request_id = tracing_actix_web::root_span_macro::private::get_request_id(request);
|
||||
|
||||
tracing::info_span!(
|
||||
"HTTP request",
|
||||
http.method = %request.method(),
|
||||
http.scheme = request.connection_info().scheme(),
|
||||
http.host = %request.connection_info().host(),
|
||||
http.target = %request.uri().path(),
|
||||
http.status_code = tracing::field::Empty,
|
||||
otel.kind = "server",
|
||||
otel.status_code = tracing::field::Empty,
|
||||
trace_id = tracing::field::Empty,
|
||||
request_id = %request_id,
|
||||
exception.message = tracing::field::Empty,
|
||||
// Not proper OpenTelemetry, but their terminology is fairly exception-centric
|
||||
exception.details = tracing::field::Empty,
|
||||
)
|
||||
}
|
||||
|
||||
fn on_request_end<B>(
|
||||
span: tracing::Span,
|
||||
outcome: &Result<actix_web::dev::ServiceResponse<B>, actix_web::Error>,
|
||||
) {
|
||||
match &outcome {
|
||||
Ok(response) => {
|
||||
if let Some(error) = response.response().error() {
|
||||
// use the status code already constructed for the outgoing HTTP response
|
||||
handle_error(span, response.status(), error.as_response_error());
|
||||
} else {
|
||||
let code: i32 = response.response().status().as_u16().into();
|
||||
span.record("http.status_code", code);
|
||||
span.record("otel.status_code", "OK");
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
let response_error = error.as_response_error();
|
||||
handle_error(span, response_error.status_code(), response_error);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_error(span: Span, status_code: StatusCode, response_error: &dyn ResponseError) {
|
||||
let code: i32 = status_code.as_u16().into();
|
||||
|
||||
span.record("http.status_code", code);
|
||||
|
||||
if status_code.is_client_error() {
|
||||
span.record("otel.status_code", "OK");
|
||||
} else {
|
||||
span.record("otel.status_code", "ERROR");
|
||||
}
|
||||
|
||||
// pre-formatting errors is a workaround for https://github.com/tokio-rs/tracing/issues/1565
|
||||
let display_error = format!("{response_error}");
|
||||
|
||||
tracing::info_span!(
|
||||
parent: None,
|
||||
"Error encountered while processing the incoming HTTP request"
|
||||
)
|
||||
.in_scope(|| {
|
||||
if status_code.is_client_error() {
|
||||
tracing::warn!("{}", display_error);
|
||||
} else {
|
||||
tracing::error!("{}", display_error);
|
||||
}
|
||||
});
|
||||
|
||||
span.record("exception.message", tracing::field::display(display_error));
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
use console_subscriber::ConsoleLayer;
|
||||
use lemmy_utils::error::LemmyResult;
|
||||
use opentelemetry::{
|
||||
sdk::{propagation::TraceContextPropagator, Resource},
|
||||
KeyValue,
|
||||
};
|
||||
use opentelemetry_otlp::WithExportConfig;
|
||||
use tracing::{subscriber::set_global_default, Subscriber};
|
||||
use tracing_subscriber::{filter::Targets, layer::SubscriberExt, registry::LookupSpan, Layer};
|
||||
|
||||
pub fn init_tracing<S>(opentelemetry_url: &str, subscriber: S, targets: Targets) -> LemmyResult<()>
|
||||
where
|
||||
S: Subscriber + for<'a> LookupSpan<'a> + Send + Sync + 'static,
|
||||
{
|
||||
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
|
||||
|
||||
let console_layer = ConsoleLayer::builder()
|
||||
.with_default_env()
|
||||
.server_addr(([0, 0, 0, 0], 6669))
|
||||
.event_buffer_capacity(1024 * 1024)
|
||||
.spawn();
|
||||
|
||||
let subscriber = subscriber.with(console_layer);
|
||||
|
||||
let tracer = opentelemetry_otlp::new_pipeline()
|
||||
.tracing()
|
||||
.with_trace_config(
|
||||
opentelemetry::sdk::trace::config()
|
||||
.with_resource(Resource::new(vec![KeyValue::new("service.name", "lemmy")])),
|
||||
)
|
||||
.with_exporter(
|
||||
opentelemetry_otlp::new_exporter()
|
||||
.tonic()
|
||||
.with_endpoint(opentelemetry_url),
|
||||
)
|
||||
.install_batch(opentelemetry::runtime::Tokio)?;
|
||||
|
||||
let otel_layer = tracing_opentelemetry::layer()
|
||||
.with_tracer(tracer)
|
||||
.with_filter(targets);
|
||||
|
||||
let subscriber = subscriber.with(otel_layer);
|
||||
|
||||
set_global_default(subscriber)?;
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in a new issue