sentry-rust
sentry-rust copied to clipboard
Sentry Tracing not working for me
I don't know if I missunderstand the documentation for sentry tracing integration but I can not get event capturing to work. This my test code:
#[tokio::main]
#[tracing::instrument]
async fn main() -> Result<(), Box<dyn Error>> {
dotenv().ok();
let _guard = sentry::init((
"https://...",
sentry::ClientOptions {
release: sentry::release_name!(),
sample_rate: 1.0,
attach_stacktrace: true,
..Default::default()
},
));
let tracing_layer =
tracing_subscriber::fmt::layer().with_filter(filter::filter_fn(|metadata| {
vec![Level::INFO, Level::ERROR, Level::WARN].contains(metadata.level())
}));
let sentry_layer = sentry_tracing::layer();
let _ = tracing_subscriber::registry()
.with(tracing_layer)
.with(sentry_layer)
.init();
test_sentry();
const VERSION: &str = env!("CARGO_PKG_VERSION");
info!("Starting application with version {}", VERSION);
panic!("A panic");
Ok(())
}
#[tracing::instrument]
fn test_sentry() {
error!("Testing");
}
This is my cargo.toml
dependencies
[dependencies]
reqwest = { version = "0.11.13", features = ["multipart", "json"] }
tokio = { version = "1.2", features = ["full"] }
serde_json = "1.0"
serde = "1.0"
lapin = "2.1.1"
futures-lite = "1.12.0"
tracing = "0.1.37"
tracing-subscriber = "0.3.16"
tracing-test = "0.1"
dotenv = "0.15.0"
base64 = "0.13.1"
async-trait = "0.1.64"
web-push = "0.9.3"
sentry = {version = "0.23.0", default-features = false, features = ["backtrace", "log", "contexts", "panic", "transport", "reqwest", "rustls", "tracing"]}
lettre = "0.10.2"
regex = "1.5"
sentry-tracing = "0.30.0"
The panic event is recieved in Sentry but not the "Testing" error. Do anyone know what I am doing wrong?
This example does have one problem in it, but I doubt it might be causing this.
Sentry is incompatible with #[tokio::main]
in the sense that tokio starts a bunch of worker threads, and calling sentry::init
in there means that the configured client is not correctly propagated to all the other threads that were already spawned.
However in your example everything is straight-line code without any await
in between that might be "work-stealed" to a different thread.
But to be completely safe, please move the sentry::init
to the main thread, and spawn the tokio runtime from there. Unfortunately, you have to give up the convenience of #[tokio::main]
for that :-(
This example does have one problem in it, but I doubt it might be causing this.
Sentry is incompatible with
#[tokio::main]
in the sense that tokio starts a bunch of worker threads, and callingsentry::init
in there means that the configured client is not correctly propagated to all the other threads that were already spawned. However in your example everything is straight-line code without anyawait
in between that might be "work-stealed" to a different thread.But to be completely safe, please move the
sentry::init
to the main thread, and spawn the tokio runtime from there. Unfortunately, you have to give up the convenience of#[tokio::main]
for that :-(
Do you have some example code of what you mean? How can I use the async runtime without #[tokio::main]
?
https://docs.rs/tokio/latest/tokio/runtime/index.html has some examples.
Ait thank you, I am going to try it and get back to you
This does not work for me, is this how you meant it should look?
fn set_up_tracing() {
let tracing_layer =
tracing_subscriber::fmt::layer().with_filter(filter::filter_fn(|metadata| {
vec![Level::INFO, Level::ERROR, Level::WARN].contains(metadata.level())
}));
let sentry_layer = sentry_tracing::layer();
let _ = tracing_subscriber::registry()
.with(tracing_layer)
.with(sentry_layer)
.init();
}
#[tracing::instrument]
fn main() {
dotenv().ok();
let _guard = sentry::init((
"...",
sentry::ClientOptions {
release: sentry::release_name!(),
sample_rate: 1.0,
..Default::default()
},
));
set_up_tracing();
const VERSION: &str = env!("CARGO_PKG_VERSION");
info!("Starting application with version {}", VERSION);
test_sentry();
}
#[tracing::instrument]
fn test_sentry() {
error!("Testing");
}
This is pretty close to the code we use ourselves:
https://github.com/getsentry/symbolicator/blob/ddf55813bb3ce01a5285a58539cfb9b1c5a138de/crates/symbolicator/src/logging.rs#L50-L60
Though we use the fmt
builder/subscriber directly.
What is the output of the tracing log itself? Also, you can pass the debug: true
flag to sentry::ClientOptions
and see if that helps with figuring this out.
As a drive-by review: You are using vec![].contains
in the filter_fn, which I believe will be called for every event, and will allocate/free a Vec
every time.
Thank you for the tip, I have fixed it now. When I pass debug to true I get the following output
[sentry] enabled sentry client for DSN ...
2023-04-14T10:38:38.245827Z INFO communication_service: Starting application with version 0.1.2
2023-04-14T10:38:38.246747Z ERROR test_sentry: communication_service: Testing
[sentry] dropping client guard -> disposing client
[sentry] client close; request transport to shut down
I'm seeing similar behaviour, any updates?
I am as well. Also confusing is the hello world example in the sentry-tracing
readme uses #[tokio::main]?
Sentry is incompatible with
#[tokio::main]
in the sense that tokio starts a bunch of worker threads, and callingsentry::init
in there means that the configured client is not correctly propagated to all the other threads that were already spawned. However in your example everything is straight-line code without anyawait
in between that might be "work-stealed" to a different thread.
@Swatinem , is this still the case? The official sentry_tracing crate docs use #[tokio::main]
in their example code, but it also seems to have been like that at the time you wrote your comment. If it's still the case, you might want to update the docs.
@Swatinem any update here?
We have updated the docs since then. It seems the doc example was valid in the sense that it compiled, but it did not assert that it actually works correctly.
Either way, your log output does not show that any event / transaction was captured either.