feat(project): init
This commit is contained in:
39
src/outputs/postgres.rs
Normal file
39
src/outputs/postgres.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
// src/outputs/postgres.rs
|
||||
use super::LogOutput;
|
||||
use crate::model::LogRecord;
|
||||
use async_trait::async_trait;
|
||||
use sqlx::PgPool;
|
||||
|
||||
pub struct PostgresOutput {
|
||||
pool: PgPool,
|
||||
}
|
||||
|
||||
impl PostgresOutput {
|
||||
pub fn new(pool: PgPool) -> Self {
|
||||
Self { pool }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl LogOutput for PostgresOutput {
|
||||
async fn write(&self, record: &LogRecord) {
|
||||
let query = r#"
|
||||
INSERT INTO app_logs (log_level, message, module, created_at)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
"#;
|
||||
|
||||
// 注意:这里的 write 是在后台任务中执行的,就算慢也不会阻塞主业务
|
||||
// 我们忽略错误,因为如果日志系统挂了,不能让它导致业务逻辑崩溃 (Panic)
|
||||
// 生产环境可以考虑加一个 fallback 机制(比如降级写文件)
|
||||
if let Err(e) = sqlx::query(query)
|
||||
.bind(record.level.to_string())
|
||||
.bind(&record.message)
|
||||
.bind(&record.module)
|
||||
.bind(record.timestamp)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
{
|
||||
eprintln!("Failed to write log to PostgreSQL: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user