From cf5f68a17ce57cd7854cc0f4ffc03af8d9ebc184 Mon Sep 17 00:00:00 2001 From: Olivier Desenfans Date: Tue, 20 Sep 2022 10:47:46 +0200 Subject: [PATCH] Feature: support Sentry (#23) Problem: developers would like to keep an eye on logs, especially errors. Solution: add support for Sentry. The application now logs errors to Sentry + warnings as breadcrumbs. The API server uses sentry-actix for logging of 500 errors. --- Cargo.toml | 3 +++ src/main.rs | 33 ++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ffcb3d8..9efb681 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,9 @@ lapin = "2.1.1" libp2p = { version = "0.47.0", features = ["serde", "tcp-tokio", "dns-tokio"] } libp2p-tcp = { version = "0.35.0", features = ["tokio"] } log = "0.4.17" +# Note: by default, the sentry package requires OpenSSL. We use rustls instead to avoid depending on system packages. +sentry = { version = "0.27.0", features = ["log", "panic", "reqwest", "rustls"], default-features = false } +sentry-actix = "0.27.0" serde = { version = "1.0.144", features = ["derive"] } serde_json = "1.0.85" serde_yaml = "0.9.11" diff --git a/src/main.rs b/src/main.rs index 27344af..8ab7f19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,17 @@ use std::path::PathBuf; +use actix_web::{App, HttpServer, middleware}; use actix_web::web::Data; -use actix_web::{middleware, App, HttpServer}; use clap::Parser; use futures::StreamExt; use lapin::message::Delivery; use lapin::options::BasicAckOptions; -use libp2p::multiaddr::Protocol; use libp2p::{gossipsub, identity, Multiaddr, PeerId}; +use libp2p::multiaddr::Protocol; use log::{debug, error, info, warn}; -use crate::gossipsub::GossipsubMessage; +use crate::config::AppConfig; +use crate::gossipsub::GossipsubMessage; use crate::message_queue::RabbitMqClient; use crate::p2p::network::P2PClient; @@ -133,6 +134,21 @@ async fn p2p_loop( } } +fn configure_logging() { + let mut log_builder = env_logger::builder(); + let logger = sentry::integrations::log::SentryLogger::with_dest(log_builder.build()); + log::set_boxed_logger(Box::new(logger)).expect("setting global logger should succeed"); + log::set_max_level(log::LevelFilter::Info); +} + +fn configure_sentry(app_config: &AppConfig) -> Option { + app_config.sentry.dsn.as_ref().map(|dsn| sentry::init(( + dsn.clone(), sentry::ClientOptions { + release: sentry::release_name!(), + ..Default::default() + }))) +} + pub struct AppState { pub app_config: config::AppConfig, pub p2p_client: std::sync::Mutex, @@ -141,18 +157,20 @@ pub struct AppState { #[actix_web::main] async fn main() -> Result<(), Box> { - env_logger::init(); + configure_logging(); let args = CliArgs::parse(); debug!("CLI args: {:?}", args); + let app_config = read_config(&args.config); + debug!("Config: {:?}", app_config); + + let _sentry_guard = configure_sentry(&app_config); + let id_keys = load_p2p_private_key(&args.private_key_file); let peer_id = PeerId::from(id_keys.public()); info!("Peer ID: {:?}", peer_id); - let app_config = read_config(&args.config); - debug!("Config: {:?}", app_config); - let (mut network_client, network_events, network_event_loop) = p2p::network::new(id_keys).await?; @@ -195,6 +213,7 @@ async fn main() -> Result<(), Box> { .app_data(Data::clone(&app_data)) // enable logger - always register actix-web Logger middleware last .wrap(middleware::Logger::default()) + .wrap(sentry_actix::Sentry::new()) // register HTTP requests handlers .configure(http::config) })