diff --git a/server/src/middleware/error-handler.ts b/server/src/middleware/error-handler.ts index 35a298db..e9d6c5a8 100644 --- a/server/src/middleware/error-handler.ts +++ b/server/src/middleware/error-handler.ts @@ -26,6 +26,9 @@ export function errorHandler( ? { message: err.message, stack: err.stack, name: err.name } : { raw: err }; + // Attach the real error so pino-http can include it in its response log + res.locals.serverError = errObj; + logger.error( { err: errObj, method: req.method, url: req.originalUrl }, "Unhandled error: %s %s — %s", diff --git a/server/src/middleware/logger.ts b/server/src/middleware/logger.ts index bfcebd22..8f915b85 100644 --- a/server/src/middleware/logger.ts +++ b/server/src/middleware/logger.ts @@ -2,8 +2,20 @@ import path from "node:path"; import fs from "node:fs"; import pino from "pino"; import { pinoHttp } from "pino-http"; +import { readConfigFile } from "../config-file.js"; +import { resolveDefaultLogsDir, resolveHomeAwarePath } from "../home-paths.js"; -const logDir = path.resolve(process.cwd(), ".paperclip", "logs"); +function resolveServerLogDir(): string { + const envOverride = process.env.PAPERCLIP_LOG_DIR?.trim(); + if (envOverride) return resolveHomeAwarePath(envOverride); + + const fileLogDir = readConfigFile()?.logging.logDir?.trim(); + if (fileLogDir) return resolveHomeAwarePath(fileLogDir); + + return resolveDefaultLogsDir(); +} + +const logDir = resolveServerLogDir(); fs.mkdirSync(logDir, { recursive: true }); const logFile = path.join(logDir, "server.log"); @@ -32,10 +44,22 @@ export const logger = pino({ export const httpLogger = pinoHttp({ logger, + customLogLevel(_req, res, err) { + if (err || res.statusCode >= 500) return "error"; + if (res.statusCode >= 400) return "warn"; + return "info"; + }, customSuccessMessage(req, res) { return `${req.method} ${req.url} ${res.statusCode}`; }, customErrorMessage(req, res) { return `${req.method} ${req.url} ${res.statusCode}`; }, + customProps(_req, res) { + const serverError = (res as any).locals?.serverError; + if (serverError) { + return { serverError }; + } + return {}; + }, });