Merge branch 'dev' of https://git.hanasys.jp/qcast3/onsitesurvey into feature/survey

This commit is contained in:
Dayoung 2025-06-18 15:13:17 +09:00
commit 3084f292a7

View File

@ -15,9 +15,14 @@ interface ApiLogData {
body: string | undefined body: string | undefined
} }
/* 현재 날짜 반환 함수 (YYYY-MM-DD 형식) */
const getCurrentDate = (): string => {
return new Date().toISOString().split('T')[0]
}
/* 날짜별 로그 파일 경로 생성 함수 */ /* 날짜별 로그 파일 경로 생성 함수 */
const getLogFilePath = (): string => { const getLogFilePath = (): string => {
const today = new Date().toISOString().split('T')[0] // YYYY-MM-DD 형식 const today: string = getCurrentDate()
return join(process.cwd(), 'logs', `onsite-survey-${today}.log`) return join(process.cwd(), 'logs', `onsite-survey-${today}.log`)
} }
@ -25,15 +30,10 @@ const getLogFilePath = (): string => {
class DailyLogger { class DailyLogger {
private currentDate: string private currentDate: string
private logger: pino.Logger private logger: pino.Logger
private destination: ReturnType<typeof pino.destination> private destination?: ReturnType<typeof pino.destination>
constructor() { constructor() {
this.currentDate = new Date().toISOString().split('T')[0] this.currentDate = getCurrentDate()
this.destination = pino.destination({
dest: getLogFilePath(),
mkdir: true,
sync: false,
})
this.logger = this.createLogger() this.logger = this.createLogger()
/* kill signal 핸들러 등록 */ /* kill signal 핸들러 등록 */
@ -42,14 +42,31 @@ class DailyLogger {
} }
private async handleShutdown(): Promise<void> { private async handleShutdown(): Promise<void> {
this.destination.flushSync() if (isProduction && this.destination) {
this.destination.end() this.destination.flushSync()
this.destination.end()
}
this.logger.flush()
} }
private createLogger(): pino.Logger { private createLogger(): pino.Logger {
if (!isProduction) return pino({ level: 'silent' })
/* 기존 destination 종료 */
if (this.destination) {
this.destination.flushSync()
this.destination.end()
}
/* 새로운 destination 생성 */
this.destination = pino.destination({
dest: getLogFilePath(),
mkdir: true,
sync: false,
})
return pino( return pino(
{ {
level: isProduction ? 'info' : 'silent', level: 'info',
timestamp: pino.stdTimeFunctions.isoTime, timestamp: pino.stdTimeFunctions.isoTime,
}, },
this.destination, this.destination,
@ -57,24 +74,16 @@ class DailyLogger {
} }
public info(obj: any, msg?: string): void { public info(obj: any, msg?: string): void {
const today = new Date().toISOString().split('T')[0] try {
const today: string = getCurrentDate()
if (today !== this.currentDate) { if (today !== this.currentDate) {
/* 기존 destination 종료 */ this.currentDate = today
this.destination.flushSync() this.logger = this.createLogger()
this.destination.end() }
this.logger.info(obj, msg)
/* 새로운 destination 생성 */ } catch (error) {
this.destination = pino.destination({ console.error(`[DailyLogger] Failed to write log: ${error}`)
dest: getLogFilePath(),
mkdir: true,
sync: false,
})
this.currentDate = today
this.logger = this.createLogger()
} }
this.logger.info(obj, msg)
} }
} }
@ -83,13 +92,26 @@ const dailyLogger = new DailyLogger()
/* API 로그 기록 함수 */ /* API 로그 기록 함수 */
export const writeApiLog = async (request: NextRequest, responseStatus: number): Promise<void> => { export const writeApiLog = async (request: NextRequest, responseStatus: number): Promise<void> => {
if (!isProduction) return
let bodyString: string | undefined
if (
request.method === 'POST' &&
(request.headers.get('content-type') === 'multipart/form-data' || request.headers.get('content-type') === 'application/x-www-form-urlencoded')
) {
const formData = await request.formData()
bodyString = JSON.stringify(Object.fromEntries(formData))
} else {
bodyString = await request.text()
}
const logData: ApiLogData = { const logData: ApiLogData = {
responseStatus: responseStatus, responseStatus: responseStatus,
method: request.method, method: request.method,
url: request.url, url: request.url,
// headers: Object.fromEntries(request.headers), // headers: Object.fromEntries(request.headers),
query: Object.fromEntries(new URL(request.url).searchParams), query: Object.fromEntries(new URL(request.url).searchParams),
body: request.body ? await request.text() : undefined, body: bodyString,
} }
dailyLogger.info(logData, 'API Request') dailyLogger.info(logData, 'API Request')
} }