mirror of
https://github.com/Xevion/xevion.dev.git
synced 2026-01-31 00:26:31 -06:00
refactor: standardize structured logging across Rust and TypeScript
Convert string interpolation to structured fields in tracing/LogTape calls. Add target prefixes (rust::, bun:) to differentiate processes in combined logs.
This commit is contained in:
+7
-7
@@ -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<dyn std::error::
|
||||
|
||||
if get_admin_user(pool, &username).await?.is_none() {
|
||||
create_admin_user(pool, &username, &password).await?;
|
||||
tracing::info!("Created admin user: {}", username);
|
||||
tracing::info!(username, "Created admin user");
|
||||
} else {
|
||||
tracing::debug!("Admin user '{}' already exists", username);
|
||||
tracing::debug!(username, "Admin user already exists");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
+15
-3
@@ -13,6 +13,17 @@ use tracing_subscriber::registry::LookupSpan;
|
||||
const TIMESTAMP_FORMAT: &[FormatItem<'static>] =
|
||||
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<S, N> FormatEvent<S, N> 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,
|
||||
};
|
||||
|
||||
|
||||
+3
-5
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user