@@ -158,15 +158,66 @@ struct Args {
158158 health_check_interval : u64 ,
159159}
160160
161+ /// Initialize Sentry error monitoring
162+ /// Enabled by default - can be disabled by setting SENTRY_DSN="" or overridden with custom DSN
163+ fn init_sentry ( ) -> Option < sentry:: ClientInitGuard > {
164+ // Default DSN for Platform Network error monitoring
165+ const DEFAULT_DSN : & str = "https://56a006330cecdc120766a602a5091eb9@o4510579978272768.ingest.us.sentry.io/4510579979911168" ;
166+
167+ // Allow override or disable via env var (empty string disables)
168+ let dsn = std:: env:: var ( "SENTRY_DSN" ) . unwrap_or_else ( |_| DEFAULT_DSN . to_string ( ) ) ;
169+
170+ if dsn. is_empty ( ) {
171+ return None ;
172+ }
173+
174+ let environment = std:: env:: var ( "ENVIRONMENT" ) . unwrap_or_else ( |_| "production" . to_string ( ) ) ;
175+
176+ let guard = sentry:: init ( (
177+ dsn,
178+ sentry:: ClientOptions {
179+ release : sentry:: release_name!( ) ,
180+ environment : Some ( environment. into ( ) ) ,
181+ // SECURITY: Do not send PII (IP addresses, headers, etc.)
182+ send_default_pii : false ,
183+ // Only sample 100% of errors, 10% of transactions
184+ sample_rate : 1.0 ,
185+ traces_sample_rate : 0.1 ,
186+ // Attach stacktraces to all events
187+ attach_stacktrace : true ,
188+ ..Default :: default ( )
189+ } ,
190+ ) ) ;
191+
192+ tracing:: info!( "Sentry error monitoring initialized" ) ;
193+ Some ( guard)
194+ }
195+
161196#[ tokio:: main]
162197async fn main ( ) -> Result < ( ) > {
163- // Initialize logging
164- tracing_subscriber:: fmt ( )
198+ // Initialize Sentry error monitoring (optional - requires SENTRY_DSN env var)
199+ // SECURITY: DSN must be provided via environment variable, never hardcode
200+ let _sentry_guard = init_sentry ( ) ;
201+
202+ // Initialize logging with Sentry integration
203+ let subscriber = tracing_subscriber:: fmt ( )
165204 . with_env_filter (
166205 tracing_subscriber:: EnvFilter :: try_from_default_env ( )
167206 . unwrap_or_else ( |_| "info,platform=debug" . into ( ) ) ,
168207 )
169- . init ( ) ;
208+ . finish ( ) ;
209+
210+ // Add Sentry layer to capture ERROR and WARN level events
211+ use tracing_subscriber:: layer:: SubscriberExt ;
212+ let subscriber =
213+ subscriber. with (
214+ sentry_tracing:: layer ( ) . event_filter ( |metadata| match * metadata. level ( ) {
215+ tracing:: Level :: ERROR => sentry_tracing:: EventFilter :: Event ,
216+ tracing:: Level :: WARN => sentry_tracing:: EventFilter :: Breadcrumb ,
217+ _ => sentry_tracing:: EventFilter :: Ignore ,
218+ } ) ,
219+ ) ;
220+ tracing:: subscriber:: set_global_default ( subscriber) . expect ( "Failed to set tracing subscriber" ) ;
170221
171222 let args = Args :: parse ( ) ;
172223
0 commit comments