diff --git a/src/auth.rs b/src/auth.rs index d827792..a3e7248 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -72,8 +72,8 @@ impl SessionManager { } tracing::info!( - "Loaded {} active sessions from database", - self.sessions.len() + session_count = self.sessions.len(), + "Loaded active sessions from database" ); Ok(()) @@ -111,7 +111,7 @@ impl SessionManager { self.sessions.insert(id, session.clone()); - tracing::debug!("Created session {} for user {}", id, user_id); + tracing::debug!(session_id = %id, user_id, "Created session"); Ok(session) } @@ -139,7 +139,7 @@ impl SessionManager { .execute(&self.pool) .await?; - tracing::debug!("Deleted session {}", session_id); + tracing::debug!(session_id = %session_id, "Deleted session"); Ok(()) } @@ -157,7 +157,7 @@ impl SessionManager { self.sessions.retain(|_, session| session.expires_at >= now); if expired_count > 0 { - tracing::info!("Cleaned up {} expired sessions", expired_count); + tracing::info!(expired_count, "Cleaned up expired sessions"); } Ok(expired_count) @@ -234,9 +234,9 @@ pub async fn ensure_admin_user(pool: &PgPool) -> Result<(), Box] = format_description!("[hour]:[minute]:[second].[subsecond digits:3]"); +/// Transform tracing target from `api::*` to `rust::*` for combined log differentiation +fn transform_target(target: &str) -> String { + if target == "api" { + "rust".to_string() + } else if let Some(rest) = target.strip_prefix("api::") { + format!("rust::{rest}") + } else { + target.to_string() + } +} + pub struct CustomPrettyFormatter; impl FormatEvent for CustomPrettyFormatter @@ -63,10 +74,11 @@ where } } + let target = transform_target(meta.target()); if writer.has_ansi_escapes() { - write!(writer, "{}: ", Color::DarkGray.paint(meta.target()))?; + write!(writer, "{}: ", Color::DarkGray.paint(&target))?; } else { - write!(writer, "{}: ", meta.target())?; + write!(writer, "{}: ", target)?; } ctx.format_fields(writer.by_ref(), event)?; @@ -189,7 +201,7 @@ where .unwrap_or_else(|_| String::from("1970-01-01T00:00:00Z")), message: message.unwrap_or_default(), level: meta.level().to_string().to_lowercase(), - target: meta.target().to_string(), + target: transform_target(meta.target()), fields, }; diff --git a/src/main.rs b/src/main.rs index 70c7eed..3df4cf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -88,7 +88,7 @@ async fn main() { .expect("Failed to connect to database"); // Run migrations on startup - tracing::info!("Running database migrations..."); + tracing::info!("Running database migrations"); sqlx::migrate!().run(&pool).await.unwrap_or_else(|e| { tracing::error!(error = %e, "Migration failed"); std::process::exit(1); @@ -146,10 +146,8 @@ async fn main() { tracing::info!( enabled = tarpit_state.config.enabled, - delay_range_ms = format!( - "{}-{}", - tarpit_state.config.delay_min_ms, tarpit_state.config.delay_max_ms - ), + delay_min_ms = tarpit_state.config.delay_min_ms, + delay_max_ms = tarpit_state.config.delay_max_ms, max_global = tarpit_state.config.max_global_connections, max_per_ip = tarpit_state.config.max_connections_per_ip, "Tarpit initialized" diff --git a/web/src/lib/logger.ts b/web/src/lib/logger.ts index 57a16d8..5f99c80 100644 --- a/web/src/lib/logger.ts +++ b/web/src/lib/logger.ts @@ -10,11 +10,12 @@ interface RailwayLogEntry { } function railwayFormatter(record: LogRecord): string { + const categoryTarget = record.category.join(":"); const entry: RailwayLogEntry = { timestamp: new Date().toISOString(), level: record.level.toLowerCase(), message: record.message.join(" "), - target: record.category.join(":"), + target: categoryTarget ? `bun:${categoryTarget}` : "bun", }; if (record.properties && Object.keys(record.properties).length > 0) { diff --git a/web/src/lib/server/icons.ts b/web/src/lib/server/icons.ts index ddc3296..6e39ed1 100644 --- a/web/src/lib/server/icons.ts +++ b/web/src/lib/server/icons.ts @@ -54,13 +54,15 @@ async function loadCollectionFromDisk( // Cache the collection collectionCache.set(collection, iconSet); - logger.debug(`Loaded icon collection: ${collection}`, { + logger.debug("Loaded icon collection", { + collection, total: iconSet.info?.total || Object.keys(iconSet.icons).length, }); return iconSet; } catch (error) { - logger.warn(`Failed to load icon collection: ${collection}`, { + logger.warn("Failed to load icon collection", { + collection, error: error instanceof Error ? error.message : String(error), }); return null; @@ -239,7 +241,8 @@ export async function renderIconsBatch( const svg = renderIconData(iconData, options); results.set(identifier, svg); } catch (error) { - logger.warn(`Failed to render icon: ${identifier}`, { + logger.warn("Failed to render icon", { + identifier, error: error instanceof Error ? error.message : String(error), }); missingIcons.push(identifier); @@ -277,7 +280,7 @@ export async function getIconForApi(identifier: string): Promise<{ } | null> { const parsed = parseIdentifier(identifier); if (!parsed) { - logger.warn(`Invalid icon identifier: ${identifier}`); + logger.warn("Invalid icon identifier", { identifier }); return null; } @@ -290,7 +293,7 @@ export async function getIconForApi(identifier: string): Promise<{ const iconData = getIconData(iconSet, name); if (!iconData) { - logger.warn(`Icon not found: ${identifier}`); + logger.warn("Icon not found", { identifier }); return null; }