@@ -19,13 +19,14 @@ use tucana::shared::module_status::StatusVariant;
1919use crate :: client:: runtime_execution:: TaurusRuntimeExecutionService ;
2020use crate :: client:: runtime_status:: TaurusRuntimeStatusService ;
2121use crate :: config:: Config ;
22- use crate :: telemetry:: { self , TelemetrySettings } ;
22+ use crate :: telemetry:: { self , TelemetrySettings , errors } ;
2323
2424pub async fn run ( ) {
2525 load_env_file ( ) ;
2626
2727 let config = Config :: new ( ) ;
2828 let telemetry = init_telemetry ( & config) ;
29+ install_panic_logging ( ) ;
2930 let engine = ExecutionEngine :: new ( ) ;
3031 let client = connect_nats ( & config) . await ;
3132
@@ -54,6 +55,12 @@ pub async fn run() {
5455 && !err. is_cancelled ( )
5556 {
5657 log:: warn!( "Runtime status heartbeat task ended unexpectedly: {}" , err) ;
58+ errors:: record (
59+ "task" ,
60+ "runtime_status_heartbeat.task" ,
61+ & err,
62+ "mode=dynamic" ,
63+ ) ;
5764 }
5865 }
5966 update_stopped_status ( runtime_status_service. as_ref ( ) ) . await ;
@@ -76,6 +83,31 @@ fn init_telemetry(config: &Config) -> telemetry::Telemetry {
7683 . unwrap_or_else ( |error| panic ! ( "failed to initialize telemetry: {error}" ) )
7784}
7885
86+ fn install_panic_logging ( ) {
87+ std:: panic:: set_hook ( Box :: new ( move |panic_info| {
88+ let message = if let Some ( message) = panic_info. payload ( ) . downcast_ref :: < & str > ( ) {
89+ * message
90+ } else if let Some ( message) = panic_info. payload ( ) . downcast_ref :: < String > ( ) {
91+ message. as_str ( )
92+ } else {
93+ "<non-string panic payload>"
94+ } ;
95+
96+ let location = panic_info
97+ . location ( )
98+ . map ( |location| {
99+ format ! (
100+ "{}:{}:{}" ,
101+ location. file( ) ,
102+ location. line( ) ,
103+ location. column( )
104+ )
105+ } )
106+ . unwrap_or_else ( || "unknown" . into ( ) ) ;
107+ errors:: panic ( message, & location) ;
108+ } ) ) ;
109+ }
110+
79111fn environment_label ( environment : & Environment ) -> & ' static str {
80112 match environment {
81113 Environment :: Development => "development" ,
@@ -98,6 +130,7 @@ async fn connect_nats(config: &Config) -> async_nats::Client {
98130 client
99131 }
100132 Err ( err) => {
133+ errors:: record ( "transport" , "nats.connect" , & err, "component=nats" ) ;
101134 panic ! ( "Failed to connect to NATS server: {}" , err) ;
102135 }
103136 }
@@ -113,6 +146,12 @@ fn spawn_health_task(config: &Config) -> Option<JoinHandle<()>> {
113146 Ok ( address) => address,
114147 Err ( err) => {
115148 log:: error!( "Failed to parse gRPC address: {:?}" , err) ;
149+ errors:: record (
150+ "configuration" ,
151+ "health.address.parse" ,
152+ & err,
153+ "service=health" ,
154+ ) ;
116155 return None ;
117156 }
118157 } ;
@@ -125,6 +164,7 @@ fn spawn_health_task(config: &Config) -> Option<JoinHandle<()>> {
125164 . await
126165 {
127166 log:: error!( "Health server error: {:?}" , err) ;
167+ errors:: record ( "server" , "health.serve" , & err, "service=health" ) ;
128168 } else {
129169 log:: info!( "Health server stopped gracefully" ) ;
130170 }
@@ -223,6 +263,12 @@ fn read_module_status_identifiers(definition_path: &str) -> Vec<String> {
223263 "Failed to read module definitions for runtime status: {:?}" ,
224264 err
225265 ) ;
266+ errors:: record_message (
267+ "configuration" ,
268+ "definitions.read_modules" ,
269+ format ! ( "{err:?}" ) ,
270+ format ! ( "path={definition_path}" ) ,
271+ ) ;
226272 Vec :: new ( )
227273 }
228274 }
0 commit comments