From e7323aaaee4658f4f1ffea54a23199d768341839 Mon Sep 17 00:00:00 2001 From: Sijmen Date: Mon, 2 Jan 2023 20:09:21 +0100 Subject: [PATCH] Set up Sentry transactions --- Cargo.lock | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 3 +- src/sentry.rs | 52 ++++++++++++++++++++++++++++---- 4 files changed, 132 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1e2308..7e53180 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -422,6 +422,40 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -708,6 +742,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.23" @@ -839,12 +879,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "ipnet" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "iso8601" version = "0.5.1" @@ -890,6 +952,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -1504,6 +1572,7 @@ name = "rooster" version = "0.1.0" dependencies = [ "anyhow", + "env_logger", "figment", "icalendar", "log", @@ -1529,6 +1598,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.36.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "rustls" version = "0.20.7" diff --git a/Cargo.toml b/Cargo.toml index 23ce5c0..8ffca2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ log = "0.4.17" serde = "1.0.152" figment = "0.10.8" anyhow = "1.0.68" +env_logger = "0.10.0" [profile.release] lto = "thin" diff --git a/src/main.rs b/src/main.rs index 6f4856e..7603f54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,7 +70,7 @@ fn get_event_kind(description: &str) -> &str { async fn ics(url: &str) -> String { let source = match Source::from_url(url) { Some(source) => source, - None => return "Must be a rooster.utwente.nl or mytimetable.tudelft.nl URL".to_string() + None => return "Must be a rooster.utwente.nl or mytimetable.tudelft.nl URL".to_string(), }; let calendar = get_calendar(url).await.unwrap(); @@ -123,6 +123,7 @@ async fn ics(url: &str) -> String { #[launch] fn rocket() -> _ { + env_logger::init(); rocket::build() .attach(sentry::RocketSentry::fairing()) .mount("/", routes![index, generate_url, ics]) diff --git a/src/sentry.rs b/src/sentry.rs index 02f30d8..41cf6c1 100644 --- a/src/sentry.rs +++ b/src/sentry.rs @@ -1,12 +1,12 @@ +// Based on https://github.com/intgr/rocket-sentry (MIT) // Copyright (c) 2019-2022 Marti Raudsepp -// Taken from https://github.com/intgr/rocket-sentry under MIT use std::sync::{Arc, Mutex}; use rocket::fairing::{Fairing, Info, Kind}; use rocket::serde::Deserialize; -use rocket::{fairing, Build, Rocket}; -use sentry::{ClientInitGuard, ClientOptions}; +use rocket::{fairing, Build, Data, Request, Response, Rocket}; +use sentry::{ClientInitGuard, ClientOptions, Transaction}; use log::{error, info}; @@ -34,6 +34,8 @@ impl RocketSentry { info!("Sending event to Sentry: {}", event.event_id); Some(event) })), + release: sentry::release_name!(), + traces_sample_rate: 1.0, ..Default::default() }, )); @@ -43,9 +45,9 @@ impl RocketSentry { let mut self_guard = self.guard.lock().unwrap(); *self_guard = Some(guard); - info!("Sentry enabled."); + info!("Sentry enabled"); } else { - error!("Sentry did not initialize."); + error!("Sentry did not initialize"); } } } @@ -55,7 +57,7 @@ impl Fairing for RocketSentry { fn info(&self) -> Info { Info { name: "rocket-sentry", - kind: Kind::Ignite | Kind::Singleton, + kind: Kind::Ignite | Kind::Request | Kind::Response | Kind::Singleton, } } @@ -75,4 +77,42 @@ impl Fairing for RocketSentry { } Ok(rocket) } + + async fn on_request(&self, request: &mut Request<'_>, _data: &mut Data<'_>) { + let name = format!("{} {}", request.method(), request.uri().path()); + info!("Starting Sentry transaction: {}", name); + let context = sentry::TransactionContext::new(&name, ""); + let transaction = sentry::start_transaction(context); + request.local_cache(|| Some(transaction)); + } + + async fn on_response<'r>(&self, request: &'r Request<'_>, _response: &mut Response<'r>) { + let transaction: &Option = request.local_cache(|| None); + if let Some(transaction) = transaction { + + let transaction = transaction.clone(); + + let mut url = url::Url::parse(&std::env::var("BASE_URL").unwrap()).unwrap(); + url.set_path(&request.uri().to_string()); + + let headers = request + .headers() + .iter() + .map(|header| (header.name().to_string(), header.value().to_string())) + .collect(); + + let sentry_request = sentry::protocol::Request { + url: Some(url), + method: Some(request.method().to_string()), + headers, + ..Default::default() + }; + + transaction.set_request(sentry_request); + transaction.finish(); + + let name = format!("{} {}", request.method(), request.uri().path()); + info!("Finished Sentry transaction: {}", name); + } + } }