diff --git a/control-core/src/machines/manager.rs b/control-core/src/machines/manager.rs index 9098de8e..b39d5764 100644 --- a/control-core/src/machines/manager.rs +++ b/control-core/src/machines/manager.rs @@ -44,7 +44,7 @@ impl MachineManager { let device_grouping_result = group_devices_by_identification(device_identifications); tracing::info!( - "Device Groups {:?}", + "Device Groups {}", device_grouping_result.device_groups.len() ); diff --git a/docs/logging.md b/docs/logging.md index 4ea1614b..5c3d9bc9 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -308,15 +308,32 @@ pub fn my_function() { ### Structured Logging +**Important**: When logging to journald (systemd's logging service), key-value pairs in event logs are not properly captured. Instead, include structured data using string formatting within the message itself. + ```rust use tracing::{info, instrument}; +// ❌ Don't use key-value pairs in event logs (won't work with journald) +info!( + user_id = %user.id, + email = %user.email, + "Updating user profile" +); + +// ✅ Use string formatting instead (works with journald) +info!( + "Updating user profile user_id={} email={}", + user.id, + user.email +); + +// ✅ Spans can still use structured fields #[instrument(fields(user_id = %user.id, operation = "update"))] pub fn update_user(user: &User) { info!( - user_id = %user.id, - email = %user.email, - "Updating user profile" + "Updating user profile user_id={} email={}", + user.id, + user.email ); } ``` @@ -353,11 +370,11 @@ use anyhow::Result; pub fn operation_with_error_handling() -> Result<()> { match risky_operation() { Ok(result) => { - info!(result = ?result, "Operation completed successfully"); + info!("Operation completed successfully result={:?}", result); Ok(()) } Err(e) => { - error!(error = %e, "Operation failed"); + error!("Operation failed error={}", e); Err(e) } } diff --git a/server/src/logging/opentelemetry.rs b/server/src/logging/opentelemetry.rs index be5fa3d7..25827fb1 100644 --- a/server/src/logging/opentelemetry.rs +++ b/server/src/logging/opentelemetry.rs @@ -103,10 +103,10 @@ where let tracer = tracer_provider.tracer(SERVICE_NAME); tracing::info!( - service_name = SERVICE_NAME, - service_namespace = SERVICE_NAMESPACE, - endpoint = OTLP_ENDPOINT, - "OpenTelemetry tracer initialized with channel-based exporter" + "OpenTelemetry tracer initialized with channel-based exporter service_name={} namespace={} endpoint={}", + SERVICE_NAME, + SERVICE_NAMESPACE, + OTLP_ENDPOINT ); Box::new(tracing_opentelemetry::layer().with_tracer(tracer)) @@ -137,7 +137,7 @@ fn spawn_exporter_thread(receiver: Receiver>) { exporter } Err(error) => { - tracing::error!(%error, "Failed to create OTLP exporter"); + tracing::error!("Failed to create OTLP exporter error={}", error); return; } }; @@ -146,7 +146,7 @@ fn spawn_exporter_thread(receiver: Receiver>) { while let Ok(spans) = receiver.recv() { if !spans.is_empty() { if let Err(error) = export_spans(&exporter, spans).await { - tracing::warn!(%error, "Failed to export span batch"); + tracing::warn!("Failed to export span batch error={}", error); } } } diff --git a/server/src/rest/handlers/machine_mutation.rs b/server/src/rest/handlers/machine_mutation.rs index 92fbf1d6..1027dc37 100644 --- a/server/src/rest/handlers/machine_mutation.rs +++ b/server/src/rest/handlers/machine_mutation.rs @@ -49,9 +49,9 @@ async fn _post_machine_mutate( // log tracing::info!( - machine = %body.machine_identification_unique, - data = ?body.data, - "Mutating machine" + "Mutating machine machine={} data={:?}", + body.machine_identification_unique, + body.data, ); let span = tracing::info_span!("machine_mutate", machine = %body.machine_identification_unique); let _span = span.enter(); diff --git a/server/src/socketio/init.rs b/server/src/socketio/init.rs index 6d1f2ab7..9dc2cbe0 100644 --- a/server/src/socketio/init.rs +++ b/server/src/socketio/init.rs @@ -65,9 +65,9 @@ fn setup_disconnection(socket: SocketRef, namespace_id: NamespaceId, app_state: // Spawn async task to avoid blocking and potential deadlocks smol::spawn(async move { tracing::debug!( - socket = ?socket.id, - namespace = %namespace_id, - "Socket disconnected from namespace", + "Socket disconnected from namespace socket={:?} namespace={}", + socket.id, + namespace_id, ); let mut socketio_namespaces_guard = app_state.socketio_setup.namespaces.write().await; @@ -116,9 +116,9 @@ fn setup_connection(socket: SocketRef, namespace_id: NamespaceId, app_state: Arc } Err(err) => { tracing::warn!( - socket = ?socket_clone.id, - namespace = %namespace_id_clone, - "Couln't subscribe socket to namespace, disconnecting: {:?}", + "Couldn't subscribe socket to namespace, disconnecting socket={:?} namespace={} error={:?}", + socket_clone.id, + namespace_id_clone, err ); let _ = socket_clone.disconnect(); @@ -133,8 +133,8 @@ fn setup_connection(socket: SocketRef, namespace_id: NamespaceId, app_state: Arc .detach(); tracing::info!( - socket = ?socket.id, - namespace = %namespace_id, - "Socket connected to namespace", + "Socket connected to namespace socket={:?} namespace={}", + socket.id, + namespace_id, ); }