From 8269eee996b6883abce5247d360ef21e6afa4635 Mon Sep 17 00:00:00 2001 From: jisangs Date: Sat, 4 Jul 2026 17:58:58 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20query=20=EA=B2=B0=EA=B3=BC=EA=B0=80=20?= =?UTF-8?q?=EC=9E=98=EB=A0=A4=EB=B3=B4=EC=9D=B4=EB=8A=94=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95=20(3),=20=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.stage.yml | 7 +++++++ lib/db.ts | 6 +++--- lib/logger.ts | 17 ++++++++++++++++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/docker-compose.stage.yml b/docker-compose.stage.yml index 8cd76bb..330ac3d 100644 --- a/docker-compose.stage.yml +++ b/docker-compose.stage.yml @@ -18,6 +18,13 @@ services: networks: - proxy-network restart: unless-stopped + # Synology 기본 db 로그 드라이버는 대량 로그 버스트 시 메시지를 드롭한다. + # json-file(blocking 모드)은 무손실 — 표/SQL 로그 잘림 방지. + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" networks: proxy-network: diff --git a/lib/db.ts b/lib/db.ts index 55d7bb9..695f6aa 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -4,7 +4,7 @@ import { PrismaMariaDb } from "@prisma/adapter-mariadb"; import { format } from "sql-formatter"; 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 { prisma?: PrismaClient; @@ -54,7 +54,7 @@ function onQuery(e: Prisma.QueryEvent): void { const sqlToFormat = isSensitive ? e.query : inlineParams(e.query, e.params); const formatted = format(sqlToFormat, { language: "mysql", tabWidth: 2 }); - const ts = new Date().toISOString(); + const ts = timestamp(); const tag = level.toUpperCase().padEnd(5); const slowLabel = isSlow ? " [SLOW]" : ""; const header = `[${ts}] [${tag}] [db:query] ${e.duration}ms${slowLabel}`; @@ -209,7 +209,7 @@ function logResult( result: unknown ): void { if (!logger.isEnabled("debug")) return; - const ts = new Date().toISOString(); + const ts = timestamp(); const body = buildResultLog(model, operation, result); writeAll(1, `[${ts}] [DEBUG] [db:result] ${body}\n`); } diff --git a/lib/logger.ts b/lib/logger.ts index 45fab84..0bb5179 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -18,6 +18,21 @@ function shouldLog(level: Level): boolean { 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( level: Level, ctx: string, @@ -25,7 +40,7 @@ function write( data?: Record ): void { if (!shouldLog(level)) return; - const ts = new Date().toISOString(); + const ts = timestamp(); const tag = level.toUpperCase().padEnd(5); const line = data ? `[${ts}] [${tag}] [${ctx}] ${message} ${JSON.stringify(data)}`