Skip to content

Commit 1039741

Browse files
committed
feat(sentry): improve error tracking with hotkey context
- Capture WARN as events (not just breadcrumbs) - Add INFO as breadcrumbs for context - Set hotkey as Sentry user ID for filtering - Add panic hook to capture panics before crash - Add session tracking - Add server_name and netuid tags - Flush Sentry on panic for reliability
1 parent f45d41c commit 1039741

1 file changed

Lines changed: 49 additions & 5 deletions

File tree

bins/validator-node/src/main.rs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,33 +180,62 @@ fn init_sentry() -> Option<sentry::ClientInitGuard> {
180180
}
181181

182182
let environment = std::env::var("ENVIRONMENT").unwrap_or_else(|_| "production".to_string());
183+
let hostname = std::env::var("HOSTNAME").unwrap_or_else(|_| "unknown".to_string());
183184

184185
let guard = sentry::init((
185186
dsn,
186187
sentry::ClientOptions {
187188
release: sentry::release_name!(),
188189
environment: Some(environment.into()),
190+
server_name: Some(hostname.into()),
189191
// SECURITY: Do not send PII (IP addresses, headers, etc.)
190192
send_default_pii: false,
191-
// Only sample 100% of errors, 10% of transactions
193+
// Capture 100% of errors and warnings
192194
sample_rate: 1.0,
193195
traces_sample_rate: 0.1,
194196
// Attach stacktraces to all events
195197
attach_stacktrace: true,
198+
// Auto-enable session tracking
199+
auto_session_tracking: true,
200+
// Capture panic info
196201
..Default::default()
197202
},
198203
));
199204

200-
tracing::info!("Sentry error monitoring initialized");
205+
// Start a new session
206+
sentry::start_session();
207+
208+
// Set initial context
209+
sentry::configure_scope(|scope| {
210+
scope.set_tag("netuid", std::env::var("NETUID").unwrap_or_else(|_| "unknown".to_string()));
211+
scope.set_tag("node_type", "validator");
212+
});
213+
214+
eprintln!("[Sentry] Error monitoring initialized (env: {})",
215+
std::env::var("ENVIRONMENT").unwrap_or_else(|_| "production".to_string()));
201216
Some(guard)
202217
}
203218

204219
#[tokio::main]
205220
async fn main() -> Result<()> {
206-
// Initialize Sentry error monitoring (optional - requires SENTRY_DSN env var)
207-
// SECURITY: DSN must be provided via environment variable, never hardcode
221+
// Initialize Sentry error monitoring FIRST (before anything else)
222+
// This ensures we capture all errors from the very start
208223
let _sentry_guard = init_sentry();
209224

225+
// Set up panic hook to capture panics in Sentry
226+
let default_panic = std::panic::take_hook();
227+
std::panic::set_hook(Box::new(move |panic_info| {
228+
// Capture panic in Sentry
229+
sentry::capture_message(
230+
&format!("PANIC: {}", panic_info),
231+
sentry::Level::Fatal,
232+
);
233+
// Flush Sentry before crashing
234+
sentry::Hub::current().client().map(|c| c.flush(Some(std::time::Duration::from_secs(2))));
235+
// Call default panic handler
236+
default_panic(panic_info);
237+
}));
238+
210239
// Initialize logging with Sentry integration
211240
let subscriber = tracing_subscriber::fmt()
212241
.with_env_filter(
@@ -221,12 +250,16 @@ async fn main() -> Result<()> {
221250
subscriber.with(
222251
sentry_tracing::layer().event_filter(|metadata| match *metadata.level() {
223252
tracing::Level::ERROR => sentry_tracing::EventFilter::Event,
224-
tracing::Level::WARN => sentry_tracing::EventFilter::Breadcrumb,
253+
tracing::Level::WARN => sentry_tracing::EventFilter::Event, // Capture warnings as events too
254+
tracing::Level::INFO => sentry_tracing::EventFilter::Breadcrumb, // INFO as breadcrumbs for context
225255
_ => sentry_tracing::EventFilter::Ignore,
226256
}),
227257
);
228258
tracing::subscriber::set_global_default(subscriber).expect("Failed to set tracing subscriber");
229259

260+
// Log that Sentry is ready
261+
info!("Sentry error monitoring initialized - capturing ERROR and WARN events");
262+
230263
let args = Args::parse();
231264

232265
info!("Starting validator node...");
@@ -272,6 +305,17 @@ async fn main() -> Result<()> {
272305
info!("Validator hotkey: {}", keypair.ss58_address());
273306
debug!("Validator hotkey (hex): {}", keypair.hotkey().to_hex());
274307

308+
// Set Sentry user context with hotkey for error tracking
309+
sentry::configure_scope(|scope| {
310+
scope.set_user(Some(sentry::User {
311+
id: Some(keypair.ss58_address()),
312+
username: Some(keypair.hotkey().to_hex()[..16].to_string()),
313+
..Default::default()
314+
}));
315+
scope.set_tag("hotkey", keypair.ss58_address());
316+
scope.set_tag("hotkey_hex", &keypair.hotkey().to_hex()[..16]);
317+
});
318+
275319
// Set VALIDATOR_HOTKEY env var for challenge containers
276320
// This allows challenge containers to authenticate and sign P2P messages
277321
std::env::set_var("VALIDATOR_HOTKEY", keypair.hotkey().to_hex());

0 commit comments

Comments
 (0)