diff --git a/Cargo.toml b/Cargo.toml index 506d7c8..ee72ef1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,27 +1,31 @@ [package] name = "misarch-media" -version = "0.1.0" -edition = "2021" +version = "0.3.0" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -async-graphql = { version = "6.0.11", features = ["bson", "chrono", "uuid", "log"] } -async-graphql-axum = "6.0.11" -tokio = { version = "1.8", features = ["macros", "rt-multi-thread"] } -hyper = "1.0.1" -axum = { version = "0.6.0", features = ["headers", "macros"] } -serde = "1.0.193" -futures = "0.3.30" -bson = "2.8.1" -clap = { version = "4.4.13", features = ["derive"] } -uuid = { version = "1.6.1", features = ["v4", "serde"] } +async-graphql = { version = "7.0.16", features = ["bson", "chrono", "uuid", "log"] } +async-graphql-axum = "7.0.16" +tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] } +hyper = "1.6.0" +axum = { version = "0.8.3", features = ["macros"] } +serde = "1.0.219" +futures = "0.3.31" +bson = "2.14.0" +clap = { version = "4.5.37", features = ["derive"] } +uuid = { version = "1.16.0", features = ["v4", "serde"] } json = "0.12.4" -log = "0.4.20" -simple_logger = "4.3.3" -serde_json = "1.0.113" +log = "0.4.27" +simple_logger = "5.0.0" +serde_json = "1.0.140" rust-s3 = "0.33.0" mime = "0.3.17" -url = "2.5.0" -reqwest = { version = "0.12.3", features = ["json"] } -once_cell = "1.19.0" +url = "2.5.4" +reqwest = { version = "0.12.15", features = ["json"] } +opentelemetry = "0.30.0" +opentelemetry_sdk = { version = "0.30.0", features = ["rt-tokio"]} +opentelemetry-otlp = "0.30.0" +axum-otel-metrics = { version = "0.12.0" } +once_cell = "1.21.3" diff --git a/src/main.rs b/src/main.rs index 4669d40..22b9623 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,13 +11,22 @@ use axum::{ http::{HeaderMap, StatusCode}, response::{self, IntoResponse}, routing::get, - Router, Server, + Router, }; use clap::{arg, command, Parser}; use s3::{creds::Credentials, Bucket, BucketConfiguration, Region}; use log::{info, Level}; +use once_cell::sync::Lazy; +use axum_otel_metrics::HttpMetricsLayerBuilder; +use axum_otel_metrics::HttpMetricsLayer; + +use opentelemetry::global; +use opentelemetry_sdk::metrics::{PeriodicReader, SdkMeterProvider, Temporality}; +use opentelemetry_sdk::Resource; +use opentelemetry_otlp::WithExportConfig; + mod authorization; mod event; mod graphql; @@ -101,6 +110,37 @@ async fn graphql_handler( schema.execute(req).await.into() } +static RESOURCE: Lazy = Lazy::new(|| { + Resource::builder() + .with_service_name("media") + .build() +}); + +/// Initializes OpenTelemetry metrics exporter and sets the global meter provider. +fn init_otlp() -> HttpMetricsLayer { + let exporter = opentelemetry_otlp::MetricExporter::builder() + .with_http() + .with_endpoint("http://otel-collector:4318/v1/metrics") + .with_temporality(Temporality::default()) + .build() + .unwrap(); + + let reader = PeriodicReader::builder(exporter) + .with_interval(std::time::Duration::from_secs(5)) + .build(); + + let provider = SdkMeterProvider::builder() + .with_reader(reader) + .with_resource(RESOURCE.clone()) + .build(); + + global::set_meter_provider(provider.clone()); + + HttpMetricsLayerBuilder::new() + .with_provider(provider.clone()) + .build() +} + /// Starts media service on port 8000. async fn start_service() { let media_data_bucket = initialize_minio_media_data_bucket().await; @@ -111,14 +151,18 @@ async fn start_service() { .enable_federation() .finish(); + let metrics = init_otlp(); + let app = Router::new() .route("/", get(graphiql).post(graphql_handler)) .route("/health", get(StatusCode::OK)) - .with_state(schema); + .with_state(schema) + .layer(metrics); info!("GraphiQL IDE: http://0.0.0.0:8080"); - Server::bind(&"0.0.0.0:8080".parse().unwrap()) - .serve(app.into_make_service()) + + let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap(); + axum::serve(listener, app) .await .unwrap(); }