로그 파일에서 query 결과가 잘려보이는 오류 수정 (3), 로그 시간 오류 수정

This commit is contained in:
2026-07-04 17:58:58 +09:00
parent 7e2f629681
commit 8269eee996
3 changed files with 26 additions and 4 deletions
+7
View File
@@ -18,6 +18,13 @@ services:
networks: networks:
- proxy-network - proxy-network
restart: unless-stopped restart: unless-stopped
# Synology 기본 db 로그 드라이버는 대량 로그 버스트 시 메시지를 드롭한다.
# json-file(blocking 모드)은 무손실 — 표/SQL 로그 잘림 방지.
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
networks: networks:
proxy-network: proxy-network:
+3 -3
View File
@@ -4,7 +4,7 @@ import { PrismaMariaDb } from "@prisma/adapter-mariadb";
import { format } from "sql-formatter"; import { format } from "sql-formatter";
import { PrismaClient, Prisma } from "@/lib/generated/prisma/client"; import { PrismaClient, Prisma } from "@/lib/generated/prisma/client";
import { logger } from "@/lib/logger"; import { logger, timestamp } from "@/lib/logger";
const globalForPrisma = globalThis as unknown as { const globalForPrisma = globalThis as unknown as {
prisma?: PrismaClient; prisma?: PrismaClient;
@@ -54,7 +54,7 @@ function onQuery(e: Prisma.QueryEvent): void {
const sqlToFormat = isSensitive ? e.query : inlineParams(e.query, e.params); const sqlToFormat = isSensitive ? e.query : inlineParams(e.query, e.params);
const formatted = format(sqlToFormat, { language: "mysql", tabWidth: 2 }); const formatted = format(sqlToFormat, { language: "mysql", tabWidth: 2 });
const ts = new Date().toISOString(); const ts = timestamp();
const tag = level.toUpperCase().padEnd(5); const tag = level.toUpperCase().padEnd(5);
const slowLabel = isSlow ? " [SLOW]" : ""; const slowLabel = isSlow ? " [SLOW]" : "";
const header = `[${ts}] [${tag}] [db:query] ${e.duration}ms${slowLabel}`; const header = `[${ts}] [${tag}] [db:query] ${e.duration}ms${slowLabel}`;
@@ -209,7 +209,7 @@ function logResult(
result: unknown result: unknown
): void { ): void {
if (!logger.isEnabled("debug")) return; if (!logger.isEnabled("debug")) return;
const ts = new Date().toISOString(); const ts = timestamp();
const body = buildResultLog(model, operation, result); const body = buildResultLog(model, operation, result);
writeAll(1, `[${ts}] [DEBUG] [db:result] ${body}\n`); writeAll(1, `[${ts}] [DEBUG] [db:result] ${body}\n`);
} }
+16 -1
View File
@@ -18,6 +18,21 @@ function shouldLog(level: Level): boolean {
return PRIORITY[level] >= PRIORITY[getMinLevel()]; return PRIORITY[level] >= PRIORITY[getMinLevel()];
} }
// TZ 환경변수 기준 로컬 시간 (toISOString은 항상 UTC라 사용하지 않음)
export function timestamp(): string {
const d = new Date();
const pad = (n: number, w = 2) => String(n).padStart(w, "0");
const offMin = -d.getTimezoneOffset();
const sign = offMin >= 0 ? "+" : "-";
const abs = Math.abs(offMin);
return (
`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +
`T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` +
`.${pad(d.getMilliseconds(), 3)}` +
`${sign}${pad(Math.floor(abs / 60))}:${pad(abs % 60)}`
);
}
function write( function write(
level: Level, level: Level,
ctx: string, ctx: string,
@@ -25,7 +40,7 @@ function write(
data?: Record<string, unknown> data?: Record<string, unknown>
): void { ): void {
if (!shouldLog(level)) return; if (!shouldLog(level)) return;
const ts = new Date().toISOString(); const ts = timestamp();
const tag = level.toUpperCase().padEnd(5); const tag = level.toUpperCase().padEnd(5);
const line = data const line = data
? `[${ts}] [${tag}] [${ctx}] ${message} ${JSON.stringify(data)}` ? `[${ts}] [${tag}] [${ctx}] ${message} ${JSON.stringify(data)}`