rocket-sentry 1.2.0

Simplifies integration between the Rocket web framework and Sentry application monitoring system.
Documentation
#[macro_use]
extern crate rocket;

use rocket::{Build, Rocket};
use rocket_sentry::RocketSentry;
use sentry::{Hub, TransactionContext, TransactionOrSpan};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

#[get("/performance")]
fn performance() -> String {
    let duration = Duration::from_millis(500);
    thread::sleep(duration);
    format!("Waited {duration:?}")
}

#[get("/performance/<id>")]
fn performance_with_id(id: u16) -> String {
    // Wait as long as the id in seconds
    let duration = Duration::from_secs(id.into());
    thread::sleep(duration);
    format!("Waited {duration:?} for id {id}")
}

#[get("/performance?<param1>&<param2>")]
fn performance_with_parameter(param1: String, param2: u32) -> String {
    let duration = Duration::from_millis(250);
    thread::sleep(duration);
    format!("Waited {duration:?} for param {param1} - {param2}")
}

#[get("/performance/skip")]
fn performance_skipped() -> String {
    let duration = Duration::from_millis(100);
    thread::sleep(duration);
    format!("Waited {duration:?}\nTransaction will be dropped")
}

#[get("/performance/random")]
fn performance_rng() -> String {
    let duration = Duration::from_millis(100);
    thread::sleep(duration);
    format!("Waited {duration:?}\nTransaction MIGHT be dropped")
}

#[get("/performance/multiple_spans")]
fn performance_with_multiple_spans() -> String {
    let duration = Duration::from_millis(150);
    thread::sleep(duration);
    let parent = Hub::current().configure_scope(|scope| scope.get_span());
    let op_name = "some operation";
    let child_1_name = "child 1";
    let child_1: TransactionOrSpan = match parent {
        Some(parent) => parent.start_child(op_name, child_1_name).into(),
        None => {
            let context = TransactionContext::new(child_1_name, op_name);
            sentry::start_transaction(context).into()
        }
    };

    thread::sleep(duration);
    sentry::capture_message("some message", sentry::Level::Warning);
    let child_2 = child_1.start_child(op_name, "child 2");
    thread::sleep(duration);
    child_2.finish();
    child_1.finish();
    "Waited some time with multiple spans".to_string()
}

#[launch]
fn rocket() -> Rocket<Build> {
    let rocket_instance = rocket::build();
    // Get the default configured sample rate from `Rocket.toml`
    let default_rate = rocket_instance
        .figment()
        .extract_inner::<f32>("sentry_traces_sample_rate")
        .unwrap();
    let traces_sampler = move |ctx: &TransactionContext| -> f32 {
        match ctx.name() {
            "GET /performance/skip" => {
                log::warn!("Dropping performance transaction");
                0.
            }
            "GET /performance/random" => {
                log::warn!("Sending performance transaction half the time");
                0.
            }
            _ => {
                log::warn!("Sending performance transaction using default rate");
                default_rate
            }
        }
    };
    let rocket_sentry = RocketSentry::builder()
        .traces_sampler(Arc::new(traces_sampler))
        .build();
    rocket_instance.attach(rocket_sentry).mount(
        "/",
        routes![
            performance,
            performance_with_id,
            performance_with_parameter,
            performance_skipped,
            performance_rng,
            performance_with_multiple_spans,
        ],
    )
}