From 5e9d923d03f196f43107df5dfe1745eb9f8ac3a2 Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Sat, 18 Sep 2021 16:29:30 -0500 Subject: [PATCH] Instrument for OpenTelemetry --- Cargo.lock | 428 +++++++++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 6 +- src/config.rs | 14 +- src/main.rs | 31 +++- 4 files changed, 428 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e48c966..fa952a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -282,6 +282,38 @@ version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +[[package]] +name = "async-stream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atty" version = "0.2.14" @@ -401,7 +433,6 @@ dependencies = [ "libc", "num-integer", "num-traits", - "time 0.1.43", "winapi", ] @@ -450,6 +481,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + [[package]] name = "crossbeam-epoch" version = "0.9.5" @@ -532,6 +573,12 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31586bda1b136406162e381a3185a506cdfc1631708dd40cba2f6628d8634499" +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + [[package]] name = "fnv" version = "1.0.7" @@ -671,16 +718,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "gethostname" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "getrandom" version = "0.2.3" @@ -746,12 +783,65 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +[[package]] +name = "httpdate" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" + +[[package]] +name = "hyper" +version = "0.14.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "idna" version = "0.2.3" @@ -782,6 +872,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -909,6 +1008,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + [[package]] name = "ntapi" version = "0.3.6" @@ -959,6 +1064,42 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "opentelemetry" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf9b1c4e9a6c4de793c632496fa490bdc0e1eea73f0c91394f7b6990935d22" +dependencies = [ + "async-trait", + "crossbeam-channel", + "futures", + "js-sys", + "lazy_static", + "percent-encoding", + "pin-project", + "rand", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f19d4b43842433c420c548c985d158f5628bba5b518e0be64627926d19889992" +dependencies = [ + "async-trait", + "futures", + "http", + "opentelemetry", + "prost", + "thiserror", + "tokio", + "tonic", + "tonic-build", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -1005,6 +1146,16 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "pict-rs" version = "0.3.0-alpha.33" @@ -1020,6 +1171,8 @@ dependencies = [ "mime", "num_cpus", "once_cell", + "opentelemetry", + "opentelemetry-otlp", "rand", "serde", "serde_json", @@ -1032,11 +1185,12 @@ dependencies = [ "tokio-util", "tracing", "tracing-actix-web", - "tracing-bunyan-formatter", "tracing-error", "tracing-futures", "tracing-log", + "tracing-opentelemetry", "tracing-subscriber", + "url", ] [[package]] @@ -1122,6 +1276,57 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "prost" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355f634b43cdd80724ee7848f95770e7e70eefa6dcf14fea676216573b8fd603" +dependencies = [ + "bytes", + "heck", + "itertools", + "log", + "multimap", + "petgraph", + "prost", + "prost-types", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "600d2f334aa05acb02a755e217ef1ab6dea4d51b58b7846588b747edec04efba" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "603bbd6394701d13f3f25aada59c7de9d35a6a5887cfc156181234a44002771b" +dependencies = [ + "bytes", + "prost", +] + [[package]] name = "quote" version = "1.0.9" @@ -1206,6 +1411,15 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "ring" version = "0.16.20" @@ -1543,6 +1757,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -1581,16 +1809,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "time" version = "0.2.27" @@ -1665,13 +1883,36 @@ dependencies = [ "libc", "memchr", "mio", + "num_cpus", "once_cell", "parking_lot", "pin-project-lite", "signal-hook-registry", + "tokio-macros", "winapi", ] +[[package]] +name = "tokio-io-timeout" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90c49f106be240de154571dd31fbe48acb10ba6c6dd6f6517ad603abffa42de9" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio-rustls" version = "0.22.0" @@ -1683,6 +1924,17 @@ dependencies = [ "webpki", ] +[[package]] +name = "tokio-stream" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.6.8" @@ -1697,6 +1949,81 @@ dependencies = [ "tokio", ] +[[package]] +name = "tonic" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796c5e1cd49905e65dd8e700d4cb1dffcbfdb4fc9d017de08c1a537afd83627c" +dependencies = [ + "async-stream", + "async-trait", + "base64", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b52d07035516c2b74337d2ac7746075e7dcae7643816c1b12c5ff8a7484c08" +dependencies = [ + "proc-macro2", + "prost-build", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60422bc7fefa2f3ec70359b8ff1caff59d785877eb70595904605bcc412470f" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "rand", + "slab", + "tokio", + "tokio-stream", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + [[package]] name = "tracing" version = "0.1.27" @@ -1734,23 +2061,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tracing-bunyan-formatter" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c408910c9b7eabc0215fe2b4a89f8ec95581a91cea1f7619f7c78caf14cbc2a1" -dependencies = [ - "chrono", - "gethostname", - "log", - "serde", - "serde_json", - "tracing", - "tracing-core", - "tracing-log", - "tracing-subscriber", -] - [[package]] name = "tracing-core" version = "0.1.20" @@ -1791,6 +2101,19 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "599f388ecb26b28d9c1b2e4437ae019a7b336018b45ed911458cd9ebf91129f6" +dependencies = [ + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + [[package]] name = "tracing-serde" version = "0.1.2" @@ -1823,6 +2146,12 @@ dependencies = [ "tracing-serde", ] +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + [[package]] name = "twoway" version = "0.2.2" @@ -1923,6 +2252,16 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -2012,6 +2351,17 @@ dependencies = [ "webpki", ] +[[package]] +name = "which" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9" +dependencies = [ + "either", + "lazy_static", + "libc", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index e4e3b51..0b74d17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,8 @@ futures-util = "0.3.17" mime = "0.3.1" num_cpus = "1.13" once_cell = "1.4.0" +opentelemetry = { version = "0.16", features = ["rt-tokio"] } +opentelemetry-otlp = "0.9" rand = "0.8.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -34,9 +36,9 @@ tokio = { version = "1", default-features = false, features = ["fs", "io-util", tokio-util = { version = "0.6", default-features = false, features = ["codec"] } tracing = "0.1.15" tracing-actix-web = { version = "0.4.0-beta.8" } -tracing-bunyan-formatter = "0.2.6" tracing-error = "0.1.2" tracing-futures = "0.2.4" tracing-log = "0.1.2" +tracing-opentelemetry = "0.15" tracing-subscriber = { version = "0.2.5", features = ["fmt", "tracing-log"] } -# uuid = { version = "0.8", features = ["v4"] } +url = "2.2" diff --git a/src/config.rs b/src/config.rs index 5fe2f2b..5c3412e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,5 @@ use std::{collections::HashSet, net::SocketAddr, path::PathBuf}; +use url::Url; #[derive(Clone, Debug, structopt::StructOpt)] pub(crate) struct Config { @@ -74,8 +75,13 @@ pub(crate) struct Config { )] api_key: Option, - #[structopt(short, long, help = "Enable json logging for the pict-rs server")] - json_logging: bool, + #[structopt( + short, + long, + env = "PICTRS_OPENTELEMETRY_URL", + help = "Enable json logging for the pict-rs server" + )] + opentelemetry_url: Option, } impl Config { @@ -117,8 +123,8 @@ impl Config { self.api_key.as_deref() } - pub(crate) fn json_logging(&self) -> bool { - self.json_logging + pub(crate) fn opentelemetry_url(&self) -> Option<&Url> { + self.opentelemetry_url.as_ref() } } diff --git a/src/main.rs b/src/main.rs index 31edb19..08e1490 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,8 @@ use futures_util::{ Stream, }; use once_cell::sync::Lazy; +use opentelemetry::{sdk::Resource, KeyValue}; +use opentelemetry_otlp::WithExportConfig; use std::{ collections::HashSet, future::{ready, Future}, @@ -29,11 +31,10 @@ use tokio::{ }; use tracing::{debug, error, info, instrument, subscriber::set_global_default, Span}; use tracing_actix_web::TracingLogger; -use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer}; use tracing_error::ErrorLayer; use tracing_futures::Instrument; use tracing_log::LogTracer; -use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; +use tracing_subscriber::{fmt::format::FmtSpan, layer::SubscriberExt, EnvFilter, Registry}; mod config; mod error; @@ -793,17 +794,35 @@ async fn filename_by_alias( #[actix_rt::main] async fn main() -> Result<(), anyhow::Error> { - let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); LogTracer::init()?; + let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); + let format_layer = tracing_subscriber::fmt::layer() + .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE) + .pretty(); + let subscriber = Registry::default() .with(env_filter) + .with(format_layer) .with(ErrorLayer::default()); - if CONFIG.json_logging() { - let formatting_layer = BunyanFormattingLayer::new("pict-rs".into(), std::io::stdout); + if let Some(url) = CONFIG.opentelemetry_url() { + let tracer = + opentelemetry_otlp::new_pipeline() + .tracing() + .with_trace_config(opentelemetry::sdk::trace::config().with_resource( + Resource::new(vec![KeyValue::new("service.name", "pict-rs")]), + )) + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint(url.as_str()), + ) + .install_batch(opentelemetry::runtime::Tokio)?; - let subscriber = subscriber.with(JsonStorageLayer).with(formatting_layer); + let otel_layer = tracing_opentelemetry::layer().with_tracer(tracer); + + let subscriber = subscriber.with(otel_layer); set_global_default(subscriber)?; } else {