Files
web-temp/layers/server/plugins/nitroPlugin.ts
2025-10-31 15:30:06 +09:00

69 lines
2.7 KiB
TypeScript

import type { RenderResponse } from 'nitropack'
import type { H3Event } from 'h3'
import { defineNitroPlugin } from 'nitropack/runtime'
import { getTrueClientIp } from '#layers/utils/apiUtil'
function generateRequestId(): string {
return Date.now().toString(36) + Math.random().toString(36).substring(2)
}
function getIpAddress(event: H3Event): string {
return getTrueClientIp(event.node.req as any) || 'unknown'
}
export default defineNitroPlugin((nitroApp) => {
// 정적 파일 체크 함수 추가
const isStaticFile = (path: string): boolean => {
return /\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/i.test(path)
}
// 헬스체크 경로 체크 함수 추가
const isHealthCheck = (path: string): boolean => {
return path === '/health'
}
nitroApp.hooks.hook('request', (event) => {
// 정적 파일 요청은 로깅 제외
if (isStaticFile(event.path) || isHealthCheck(event.path)) {
return
}
// 상세 로깅을 위한 정보 수집
const startTime = Date.now()
const userAgent = event.node.req.headers['user-agent'] || ''
const method = event.method || ''
const headers = JSON.stringify(event.node.req.headers, null, 2)
const requestId = generateRequestId()
if (process.env.NODE_ENV !== 'development') {
console.log(
`Request Info {"requestId":"${requestId}", "type":"request","method":"${method}","url":"${event.path}","userIp":"${getIpAddress(event)}","userAgent":"${userAgent}", "headers" : "${headers}" }`
)
// 요청 완료 후 응답 상태 코드 로깅
event.node.res.on('finish', () => {
console.log(
`Response Info {"requestId":"${requestId}","type":"response","method":"${method}","url":"${event.path}","statusCode":${event.node.res.statusCode},"responseTime":"${Date.now() - startTime}ms","userIp":"${getIpAddress(event)}","userAgent":"${userAgent}","statusMessage":"${event.node.res.statusMessage}","responseHeader": ${JSON.stringify(event.node.res.getHeaders(), null, 2)}}`
)
console.log(
'==========================================================================================================================================================================================================================================================='
)
})
}
})
nitroApp.hooks.hook('error', (error) => {
console.error('[Nitro Error]', {
message: error.message,
stack: error.stack,
timestamp: new Date().toISOString()
})
})
// 응답 헤더에서 'x-powered-by' 제거
nitroApp.hooks.hook('render:response', (response: Partial<RenderResponse>) => {
if (response?.headers) {
delete response.headers['x-powered-by']
}
})
})