Skip to content

Commit b6ed5d9

Browse files
committed
feat: added panic hook
1 parent fc8fc37 commit b6ed5d9

5 files changed

Lines changed: 82 additions & 3 deletions

File tree

crates/taurus/src/app/mod.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ use tucana::shared::module_status::StatusVariant;
1919
use crate::client::runtime_execution::TaurusRuntimeExecutionService;
2020
use crate::client::runtime_status::TaurusRuntimeStatusService;
2121
use crate::config::Config;
22-
use crate::telemetry::{self, TelemetrySettings};
22+
use crate::telemetry::{self, TelemetrySettings, errors};
2323

2424
pub 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+
79111
fn 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
}

crates/taurus/src/app/worker.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use tucana::shared::execution_result;
1212
use tucana::shared::{ExecutionFlow, ExecutionResult, NodeExecutionResult, Value};
1313

1414
use crate::client::runtime_execution::TaurusRuntimeExecutionService;
15-
use crate::telemetry::metrics;
15+
use crate::telemetry::{errors, metrics};
1616

1717
pub fn spawn_worker(
1818
client: async_nats::Client,
@@ -33,6 +33,12 @@ pub fn spawn_worker(
3333
}
3434
Err(err) => {
3535
log::error!("Failed to subscribe to 'execution.*': {:?}", err);
36+
errors::record(
37+
"transport",
38+
"nats.subscribe",
39+
&err,
40+
"subject=execution.* queue=taurus",
41+
);
3642
return;
3743
}
3844
};
@@ -93,6 +99,16 @@ async fn process_execution_message(
9399
err,
94100
&message.payload
95101
);
102+
errors::record(
103+
"serialization",
104+
"execution_flow.decode",
105+
&err,
106+
format!(
107+
"subject={} payload_bytes={}",
108+
message.subject,
109+
message.payload.len()
110+
),
111+
);
96112
if let Some(execution_service) = runtime_execution_service.as_mut() {
97113
execution_service
98114
.update_runtime_execution(build_decode_error_result(requested_execution_id))

crates/taurus/src/client/runtime_execution.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use tucana::{
1111
},
1212
};
1313

14+
use crate::telemetry::errors;
15+
1416
pub struct TaurusRuntimeExecutionService {
1517
client: ExecutionServiceClient<Channel>,
1618
aquila_token: String,
@@ -60,6 +62,12 @@ impl TaurusRuntimeExecutionService {
6062
}
6163
Err(err) => {
6264
log::error!("Failed to update RuntimeExecution: {:?}", err);
65+
errors::record(
66+
"transport",
67+
"aquila.execution.update",
68+
&err,
69+
"service=runtime_execution",
70+
);
6371
}
6472
}
6573
}

crates/taurus/src/client/runtime_status.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use tucana::{
1111
shared::{ModuleStatus, module_status::StatusVariant},
1212
};
1313

14+
use crate::telemetry::errors;
15+
1416
pub struct TaurusRuntimeStatusService {
1517
channel: Channel,
1618
identifiers: Vec<String>,
@@ -59,6 +61,12 @@ impl TaurusRuntimeStatusService {
5961
}
6062
Err(err) => {
6163
log::error!("Failed to update RuntimeStatus: {:?}", err);
64+
errors::record(
65+
"transport",
66+
"aquila.runtime_status.update",
67+
&err,
68+
"service=runtime_status",
69+
);
6270
}
6371
}
6472
}
@@ -71,6 +79,7 @@ fn now_unix_seconds() -> i64 {
7179
Ok(time) => time.as_secs() as i64,
7280
Err(err) => {
7381
log::error!("cannot get current system time: {:?}", err);
82+
errors::record("system", "time.now", &err, "clock=system");
7483
0
7584
}
7685
}

crates/taurus/src/telemetry/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pub mod metrics;
22

3-
pub use code0_flow::flow_telemetry::{OpenTelemetry, Telemetry, TelemetrySettings};
3+
pub use code0_flow::flow_telemetry::{OpenTelemetry, Telemetry, TelemetrySettings, errors};

0 commit comments

Comments
 (0)