diff --git a/Cargo.lock b/Cargo.lock
index dc949bbe..63502687 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1490,7 +1490,7 @@ dependencies = [
"http 1.1.0",
"hyper 1.5.0",
"hyper-util",
- "rustls 0.23.10",
+ "rustls 0.23.23",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.26.0",
@@ -1698,6 +1698,7 @@ dependencies = [
"metrics",
"metrics-exporter-prometheus",
"sentry",
+ "sentry-tracing",
"serde",
"serde_json",
"sqlx",
@@ -2349,7 +2350,7 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash",
- "rustls 0.23.10",
+ "rustls 0.23.23",
"socket2 0.5.7",
"thiserror",
"tokio",
@@ -2366,7 +2367,7 @@ dependencies = [
"rand",
"ring 0.17.8",
"rustc-hash",
- "rustls 0.23.10",
+ "rustls 0.23.23",
"slab",
"thiserror",
"tinyvec",
@@ -2599,7 +2600,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
- "rustls 0.23.10",
+ "rustls 0.23.23",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"serde",
@@ -2809,25 +2810,24 @@ version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
dependencies = [
- "log",
"ring 0.17.8",
"rustls-pki-types",
- "rustls-webpki 0.102.4",
+ "rustls-webpki 0.102.8",
"subtle",
"zeroize",
]
[[package]]
name = "rustls"
-version = "0.23.10"
+version = "0.23.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
+checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
dependencies = [
"log",
"once_cell",
"ring 0.17.8",
"rustls-pki-types",
- "rustls-webpki 0.102.4",
+ "rustls-webpki 0.102.8",
"subtle",
"zeroize",
]
@@ -2882,9 +2882,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
-version = "0.102.4"
+version = "0.102.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
+checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
dependencies = [
"ring 0.17.8",
"rustls-pki-types",
@@ -3002,13 +3002,13 @@ checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
[[package]]
name = "sentry"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5484316556650182f03b43d4c746ce0e3e48074a21e2f51244b648b6542e1066"
+checksum = "3a7332159e544e34db06b251b1eda5e546bd90285c3f58d9c8ff8450b484e0da"
dependencies = [
"httpdate",
"reqwest 0.12.8",
- "rustls 0.22.4",
+ "rustls 0.23.23",
"sentry-backtrace",
"sentry-contexts",
"sentry-core",
@@ -3022,9 +3022,9 @@ dependencies = [
[[package]]
name = "sentry-backtrace"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40aa225bb41e2ec9d7c90886834367f560efc1af028f1c5478a6cce6a59c463a"
+checksum = "565ec31ad37bab8e6d9f289f34913ed8768347b133706192f10606dabd5c6bc4"
dependencies = [
"backtrace",
"once_cell",
@@ -3034,9 +3034,9 @@ dependencies = [
[[package]]
name = "sentry-contexts"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a8dd746da3d16cb8c39751619cefd4fcdbd6df9610f3310fd646b55f6e39910"
+checksum = "e860275f25f27e8c0c7726ce116c7d5c928c5bba2ee73306e52b20a752298ea6"
dependencies = [
"hostname",
"libc",
@@ -3048,9 +3048,9 @@ dependencies = [
[[package]]
name = "sentry-core"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161283cfe8e99c8f6f236a402b9ccf726b201f365988b5bb637ebca0abbd4a30"
+checksum = "653942e6141f16651273159f4b8b1eaeedf37a7554c00cd798953e64b8a9bf72"
dependencies = [
"once_cell",
"rand",
@@ -3061,9 +3061,9 @@ dependencies = [
[[package]]
name = "sentry-debug-images"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc6b25e945fcaa5e97c43faee0267eebda9f18d4b09a251775d8fef1086238a"
+checksum = "2a60bc2154e6df59beed0ac13d58f8dfaf5ad20a88548a53e29e4d92e8e835c2"
dependencies = [
"findshlibs",
"once_cell",
@@ -3072,9 +3072,9 @@ dependencies = [
[[package]]
name = "sentry-panic"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc74f229c7186dd971a9491ffcbe7883544aa064d1589bd30b83fb856cd22d63"
+checksum = "105e3a956c8aa9dab1e4087b1657b03271bfc49d838c6ae9bfc7c58c802fd0ef"
dependencies = [
"sentry-backtrace",
"sentry-core",
@@ -3082,9 +3082,9 @@ dependencies = [
[[package]]
name = "sentry-tracing"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd3c5faf2103cd01eeda779ea439b68c4ee15adcdb16600836e97feafab362ec"
+checksum = "64e75c831b4d8b34a5aec1f65f67c5d46a26c7c5d3c7abd8b5ef430796900cf8"
dependencies = [
"sentry-backtrace",
"sentry-core",
@@ -3094,9 +3094,9 @@ dependencies = [
[[package]]
name = "sentry-types"
-version = "0.34.0"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d68cdf6bc41b8ff3ae2a9c4671e97426dcdd154cc1d4b6b72813f285d6b163f"
+checksum = "2d4203359e60724aa05cf2385aaf5d4f147e837185d7dd2b9ccf1ee77f4420c8"
dependencies = [
"debugid",
"hex",
@@ -3819,7 +3819,7 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
- "rustls 0.23.10",
+ "rustls 0.23.23",
"rustls-pki-types",
"tokio",
]
@@ -4233,7 +4233,7 @@ dependencies = [
"base64 0.22.1",
"log",
"once_cell",
- "rustls 0.23.10",
+ "rustls 0.23.23",
"rustls-pki-types",
"url",
"webpki-roots 0.26.6",
diff --git a/Cargo.toml b/Cargo.toml
index af0f6674..c605303a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,13 +15,13 @@ futures = "0.3.30"
lazy_static = "1.4.0"
metrics = "0.23.0"
reqwest = { version = "0.12.7" , default-features = false, features = ["rustls-tls", "trust-dns"]}
-sentry = { version = "0.34.0", default-features = false, features = ["backtrace", "contexts", "panic", "debug-images", "reqwest", "rustls"] } # replace native-tls with rustls
+sentry = { version = "0.36.0", default-features = false, features = ["backtrace", "contexts", "panic", "debug-images", "reqwest", "rustls"] } # replace native-tls with rustls
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.117"
signal-hook = "0.3.17"
sqlx = { version = "0.8.2", features = ["runtime-tokio", "postgres", "time", "macros", "uuid"] }
tokio = { version = "1.36.0", features = ["full"] }
-tracing = "0.1.40"
+tracing = "0.1"
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] }
uuid = { version = "1.7.0", features = ["serde"] }
diff --git a/PluralKit.API/PluralKit.API.csproj b/PluralKit.API/PluralKit.API.csproj
index ea792b98..e35518dd 100644
--- a/PluralKit.API/PluralKit.API.csproj
+++ b/PluralKit.API/PluralKit.API.csproj
@@ -31,6 +31,7 @@
+
diff --git a/PluralKit.API/Program.cs b/PluralKit.API/Program.cs
index d3466d4f..4f746b57 100644
--- a/PluralKit.API/Program.cs
+++ b/PluralKit.API/Program.cs
@@ -14,6 +14,16 @@ public class Program
await BuildInfoService.LoadVersion();
var host = CreateHostBuilder(args).Build();
var config = host.Services.GetRequiredService();
+
+ // Initialize Sentry SDK, and make sure it gets dropped at the end
+ using var _ = SentrySdk.Init(opts =>
+ {
+ opts.Dsn = config.SentryUrl ?? "";
+ opts.Release = BuildInfoService.FullVersion;
+ opts.AutoSessionTracking = true;
+ // opts.DisableTaskUnobservedTaskExceptionCapture();
+ });
+
await host.Services.GetRequiredService().InitAsync(config);
await host.RunAsync();
}
diff --git a/PluralKit.API/Startup.cs b/PluralKit.API/Startup.cs
index a564cbdc..ecb91710 100644
--- a/PluralKit.API/Startup.cs
+++ b/PluralKit.API/Startup.cs
@@ -62,8 +62,13 @@ public class Startup
await ctx.Response.WriteJSON(400, "{\"message\":\"400: Bad Request\",\"code\":0}");
else if (exc.Error is not PKError)
+ {
await ctx.Response.WriteJSON(500, "{\"message\":\"500: Internal Server Error\",\"code\":0}");
+ var sentryEvent = new SentryEvent(exc.Error);
+ SentrySdk.CaptureEvent(sentryEvent);
+ }
+
// for some reason, if we don't specifically cast to ModelParseError, it uses the base's ToJson method
else if (exc.Error is ModelParseError fe)
await ctx.Response.WriteJSON(fe.ResponseCode, JsonConvert.SerializeObject(fe.ToJson()));
diff --git a/PluralKit.API/packages.lock.json b/PluralKit.API/packages.lock.json
index 8c8be7c4..adc4279b 100644
--- a/PluralKit.API/packages.lock.json
+++ b/PluralKit.API/packages.lock.json
@@ -28,6 +28,12 @@
"Microsoft.AspNetCore.Mvc.Versioning": "5.1.0"
}
},
+ "Sentry": {
+ "type": "Direct",
+ "requested": "[4.13.0, )",
+ "resolved": "4.13.0",
+ "contentHash": "Wfw3M1WpFcrYaGzPm7QyUTfIOYkVXQ1ry6p4WYjhbLz9fPwV23SGQZTFDpdox67NHM0V0g1aoQ4YKLm4ANtEEg=="
+ },
"Serilog.AspNetCore": {
"type": "Direct",
"requested": "[9.0.0, )",
diff --git a/crates/libpk/Cargo.toml b/crates/libpk/Cargo.toml
index 4b084038..40d430c8 100644
--- a/crates/libpk/Cargo.toml
+++ b/crates/libpk/Cargo.toml
@@ -21,3 +21,4 @@ uuid = { workspace = true }
config = "0.14.0"
json-subscriber = { version = "0.2.2", features = ["env-filter"] }
metrics-exporter-prometheus = { version = "0.15.3", default-features = false, features = ["tokio", "http-listener", "tracing"] }
+sentry-tracing = "0.36.0"
diff --git a/crates/libpk/src/lib.rs b/crates/libpk/src/lib.rs
index ee7a6536..39643fb6 100644
--- a/crates/libpk/src/lib.rs
+++ b/crates/libpk/src/lib.rs
@@ -5,6 +5,8 @@ use metrics_exporter_prometheus::PrometheusBuilder;
use sentry::IntoDsn;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
+use sentry_tracing::event_from_event;
+
pub mod db;
pub mod state;
pub mod util;
@@ -14,8 +16,20 @@ pub use crate::_config::CONFIG as config;
// functions in this file are only used by the main function below
-pub fn init_logging(component: &str) -> anyhow::Result<()> {
+pub fn init_logging(component: &str) {
+ // todo: clean up the sentry duplication
if config.json_log {
+ let sentry_layer =
+ sentry_tracing::layer().event_mapper(|md, ctx| match md.metadata().level() {
+ &tracing::Level::ERROR => {
+ // for some reason this works, but letting the library handle it doesn't
+ let event = event_from_event(md, ctx);
+ sentry::capture_event(event);
+ sentry_tracing::EventMapping::Ignore
+ }
+ _ => sentry_tracing::EventMapping::Ignore,
+ });
+
let mut layer = json_subscriber::layer();
layer.inner_layer_mut().add_static_field(
"component",
@@ -23,15 +37,26 @@ pub fn init_logging(component: &str) -> anyhow::Result<()> {
);
tracing_subscriber::registry()
.with(layer)
+ .with(sentry_layer)
.with(EnvFilter::from_default_env())
.init();
} else {
- tracing_subscriber::fmt()
- .with_env_filter(EnvFilter::from_default_env())
+ let sentry_layer =
+ sentry_tracing::layer().event_mapper(|md, ctx| match md.metadata().level() {
+ &tracing::Level::ERROR => {
+ // for some reason this works, but letting the library handle it doesn't
+ let event = event_from_event(md, ctx);
+ sentry::capture_event(event);
+ sentry_tracing::EventMapping::Ignore
+ }
+ _ => sentry_tracing::EventMapping::Ignore,
+ });
+
+ tracing_subscriber::registry()
+ .with(tracing_subscriber::fmt::layer())
+ .with(sentry_layer)
.init();
}
-
- Ok(())
}
pub fn init_metrics() -> anyhow::Result<()> {
@@ -61,7 +86,7 @@ macro_rules! main {
fn main() -> anyhow::Result<()> {
let _sentry_guard = libpk::init_sentry();
// we might also be able to use env!("CARGO_CRATE_NAME") here
- libpk::init_logging($component)?;
+ libpk::init_logging($component);
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()