mirror of
https://github.com/Xevion/xevion.dev.git
synced 2026-01-31 04:26:43 -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!(
|
tracing::info!(
|
||||||
"Loaded {} active sessions from database",
|
session_count = self.sessions.len(),
|
||||||
self.sessions.len()
|
"Loaded active sessions from database"
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -111,7 +111,7 @@ impl SessionManager {
|
|||||||
|
|
||||||
self.sessions.insert(id, session.clone());
|
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)
|
Ok(session)
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ impl SessionManager {
|
|||||||
.execute(&self.pool)
|
.execute(&self.pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
tracing::debug!("Deleted session {}", session_id);
|
tracing::debug!(session_id = %session_id, "Deleted session");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ impl SessionManager {
|
|||||||
self.sessions.retain(|_, session| session.expires_at >= now);
|
self.sessions.retain(|_, session| session.expires_at >= now);
|
||||||
|
|
||||||
if expired_count > 0 {
|
if expired_count > 0 {
|
||||||
tracing::info!("Cleaned up {} expired sessions", expired_count);
|
tracing::info!(expired_count, "Cleaned up expired sessions");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(expired_count)
|
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() {
|
if get_admin_user(pool, &username).await?.is_none() {
|
||||||
create_admin_user(pool, &username, &password).await?;
|
create_admin_user(pool, &username, &password).await?;
|
||||||
tracing::info!("Created admin user: {}", username);
|
tracing::info!(username, "Created admin user");
|
||||||
} else {
|
} else {
|
||||||
tracing::debug!("Admin user '{}' already exists", username);
|
tracing::debug!(username, "Admin user already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
+15
-3
@@ -13,6 +13,17 @@ use tracing_subscriber::registry::LookupSpan;
|
|||||||
const TIMESTAMP_FORMAT: &[FormatItem<'static>] =
|
const TIMESTAMP_FORMAT: &[FormatItem<'static>] =
|
||||||
format_description!("[hour]:[minute]:[second].[subsecond digits:3]");
|
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;
|
pub struct CustomPrettyFormatter;
|
||||||
|
|
||||||
impl<S, N> FormatEvent<S, N> for 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() {
|
if writer.has_ansi_escapes() {
|
||||||
write!(writer, "{}: ", Color::DarkGray.paint(meta.target()))?;
|
write!(writer, "{}: ", Color::DarkGray.paint(&target))?;
|
||||||
} else {
|
} else {
|
||||||
write!(writer, "{}: ", meta.target())?;
|
write!(writer, "{}: ", target)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.format_fields(writer.by_ref(), event)?;
|
ctx.format_fields(writer.by_ref(), event)?;
|
||||||
@@ -189,7 +201,7 @@ where
|
|||||||
.unwrap_or_else(|_| String::from("1970-01-01T00:00:00Z")),
|
.unwrap_or_else(|_| String::from("1970-01-01T00:00:00Z")),
|
||||||
message: message.unwrap_or_default(),
|
message: message.unwrap_or_default(),
|
||||||
level: meta.level().to_string().to_lowercase(),
|
level: meta.level().to_string().to_lowercase(),
|
||||||
target: meta.target().to_string(),
|
target: transform_target(meta.target()),
|
||||||
fields,
|
fields,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -88,7 +88,7 @@ async fn main() {
|
|||||||
.expect("Failed to connect to database");
|
.expect("Failed to connect to database");
|
||||||
|
|
||||||
// Run migrations on startup
|
// Run migrations on startup
|
||||||
tracing::info!("Running database migrations...");
|
tracing::info!("Running database migrations");
|
||||||
sqlx::migrate!().run(&pool).await.unwrap_or_else(|e| {
|
sqlx::migrate!().run(&pool).await.unwrap_or_else(|e| {
|
||||||
tracing::error!(error = %e, "Migration failed");
|
tracing::error!(error = %e, "Migration failed");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
@@ -146,10 +146,8 @@ async fn main() {
|
|||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
enabled = tarpit_state.config.enabled,
|
enabled = tarpit_state.config.enabled,
|
||||||
delay_range_ms = format!(
|
delay_min_ms = tarpit_state.config.delay_min_ms,
|
||||||
"{}-{}",
|
delay_max_ms = tarpit_state.config.delay_max_ms,
|
||||||
tarpit_state.config.delay_min_ms, tarpit_state.config.delay_max_ms
|
|
||||||
),
|
|
||||||
max_global = tarpit_state.config.max_global_connections,
|
max_global = tarpit_state.config.max_global_connections,
|
||||||
max_per_ip = tarpit_state.config.max_connections_per_ip,
|
max_per_ip = tarpit_state.config.max_connections_per_ip,
|
||||||
"Tarpit initialized"
|
"Tarpit initialized"
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ interface RailwayLogEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function railwayFormatter(record: LogRecord): string {
|
function railwayFormatter(record: LogRecord): string {
|
||||||
|
const categoryTarget = record.category.join(":");
|
||||||
const entry: RailwayLogEntry = {
|
const entry: RailwayLogEntry = {
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
level: record.level.toLowerCase(),
|
level: record.level.toLowerCase(),
|
||||||
message: record.message.join(" "),
|
message: record.message.join(" "),
|
||||||
target: record.category.join(":"),
|
target: categoryTarget ? `bun:${categoryTarget}` : "bun",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (record.properties && Object.keys(record.properties).length > 0) {
|
if (record.properties && Object.keys(record.properties).length > 0) {
|
||||||
|
|||||||
@@ -54,13 +54,15 @@ async function loadCollectionFromDisk(
|
|||||||
// Cache the collection
|
// Cache the collection
|
||||||
collectionCache.set(collection, iconSet);
|
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,
|
total: iconSet.info?.total || Object.keys(iconSet.icons).length,
|
||||||
});
|
});
|
||||||
|
|
||||||
return iconSet;
|
return iconSet;
|
||||||
} catch (error) {
|
} 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),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
@@ -239,7 +241,8 @@ export async function renderIconsBatch(
|
|||||||
const svg = renderIconData(iconData, options);
|
const svg = renderIconData(iconData, options);
|
||||||
results.set(identifier, svg);
|
results.set(identifier, svg);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn(`Failed to render icon: ${identifier}`, {
|
logger.warn("Failed to render icon", {
|
||||||
|
identifier,
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
});
|
});
|
||||||
missingIcons.push(identifier);
|
missingIcons.push(identifier);
|
||||||
@@ -277,7 +280,7 @@ export async function getIconForApi(identifier: string): Promise<{
|
|||||||
} | null> {
|
} | null> {
|
||||||
const parsed = parseIdentifier(identifier);
|
const parsed = parseIdentifier(identifier);
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
logger.warn(`Invalid icon identifier: ${identifier}`);
|
logger.warn("Invalid icon identifier", { identifier });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +293,7 @@ export async function getIconForApi(identifier: string): Promise<{
|
|||||||
|
|
||||||
const iconData = getIconData(iconSet, name);
|
const iconData = getIconData(iconSet, name);
|
||||||
if (!iconData) {
|
if (!iconData) {
|
||||||
logger.warn(`Icon not found: ${identifier}`);
|
logger.warn("Icon not found", { identifier });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user