diff --git a/src/controllers/admin.ts b/src/controllers/admin.ts index 321e082..7a4bcf0 100644 --- a/src/controllers/admin.ts +++ b/src/controllers/admin.ts @@ -9,7 +9,6 @@ import { logger } from '../utils/logger'; const publicRoutes = new Hono(); const protectedRoutes = new Hono(); -const isRepoListDebugEnabled = process.env.REPO_LIST_DEBUG_LOGS === 'true'; // --- Public Routes --- @@ -48,33 +47,27 @@ protectedRoutes.get('/repositories', async (c) => { }; try { - if (isRepoListDebugEnabled) { - logger.debug('开始获取仓库列表', requestContext); - } + logger.debug('开始获取仓库列表', requestContext); const { repos, totalCount } = await giteaService.listAllRepositories(page, limit, query); - if (isRepoListDebugEnabled) { - logger.debug('仓库搜索接口返回成功', { - ...requestContext, - reposCount: repos.length, - totalCount, - sampleRepos: repos - .slice(0, 3) - .map((repo) => (typeof repo.full_name === 'string' ? repo.full_name : null)), - }); - } + logger.debug('仓库搜索接口返回成功', { + ...requestContext, + reposCount: repos.length, + totalCount, + sampleRepos: repos + .slice(0, 3) + .map((repo) => (typeof repo.full_name === 'string' ? repo.full_name : null)), + }); const webhookUrl = c.req.url.replace(/\/admin\/api\/repositories.*$/, '/webhook/gitea'); const fullNames = repos .map((repo) => (typeof repo.full_name === 'string' ? repo.full_name : null)) .filter((name): name is string => name !== null); - if (isRepoListDebugEnabled) { - logger.debug('准备批量读取项目级提示词', { - ...requestContext, - fullNamesCount: fullNames.length, - fullNamesSample: fullNames.slice(0, 5), - }); - } + logger.debug('准备批量读取项目级提示词', { + ...requestContext, + fullNamesCount: fullNames.length, + fullNamesSample: fullNames.slice(0, 5), + }); let promptMap: Record; try { diff --git a/src/services/gitea.ts b/src/services/gitea.ts index 244c53a..9fd2045 100644 --- a/src/services/gitea.ts +++ b/src/services/gitea.ts @@ -3,8 +3,6 @@ import config from '../config'; import { toErrorLogMeta } from '../utils/error-log'; import { logger } from '../utils/logger'; -const isRepoListDebugEnabled = process.env.REPO_LIST_DEBUG_LOGS === 'true'; - export interface LineComment { path: string; line: number; @@ -426,9 +424,7 @@ export const giteaService: GiteaService = { }; try { - if (isRepoListDebugEnabled) { - logger.debug('开始请求 Gitea 仓库搜索接口', requestContext); - } + logger.debug('开始请求 Gitea 仓库搜索接口', requestContext); const response = await giteaAdminClient.get('/repos/search', { params: { @@ -438,15 +434,13 @@ export const giteaService: GiteaService = { }, }); - if (isRepoListDebugEnabled) { - logger.debug('Gitea 仓库搜索接口返回成功', { - ...requestContext, - status: response.status, - contentType: response.headers['content-type'] ?? null, - dataCount: Array.isArray(response.data?.data) ? response.data.data.length : null, - headerTotalCount: response.headers['x-total-count'] ?? null, - }); - } + logger.debug('Gitea 仓库搜索接口返回成功', { + ...requestContext, + status: response.status, + contentType: response.headers['content-type'] ?? null, + dataCount: Array.isArray(response.data?.data) ? response.data.data.length : null, + headerTotalCount: response.headers['x-total-count'] ?? null, + }); const totalCount = Number.parseInt(response.headers['x-total-count'] || '0', 10); return { repos: response.data.data, totalCount }; diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 21c4b45..32e15e4 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -1,58 +1,90 @@ -// 简单的日志实用工具 +import pino from 'pino'; -/** - * 日志级别 - */ export enum LogLevel { - DEBUG = 'DEBUG', - INFO = 'INFO', - WARN = 'WARN', - ERROR = 'ERROR', + DEBUG = 'debug', + INFO = 'info', + WARN = 'warn', + ERROR = 'error', } -/** - * 格式化时间 - */ -function formatTime(): string { - return new Date().toISOString(); -} +type LogMeta = Record; +type ErrorWithCode = Error & { code?: unknown }; -/** - * 格式化日志消息 - */ -function formatMessage(level: LogLevel, message: string, meta?: any): string { - const timestamp = formatTime(); - - let formattedMessage = `[${timestamp}] [${level}] ${message}`; - - if (meta) { - try { - formattedMessage += ` - ${JSON.stringify(meta)}`; - } catch (_error) { - formattedMessage += ` - ${meta}`; - } +function resolveLogLevel(rawLevel: string | undefined): LogLevel { + if (!rawLevel) { + return LogLevel.INFO; } - return formattedMessage; + const normalized = rawLevel.toLowerCase(); + if (normalized === LogLevel.DEBUG) return LogLevel.DEBUG; + if (normalized === LogLevel.INFO) return LogLevel.INFO; + if (normalized === LogLevel.WARN) return LogLevel.WARN; + if (normalized === LogLevel.ERROR) return LogLevel.ERROR; + return LogLevel.INFO; +} + +function toLogMeta(meta: unknown): LogMeta | undefined { + if (meta === undefined) { + return undefined; + } + + if (meta instanceof Error) { + const maybeCode = (meta as ErrorWithCode).code; + const code = + typeof maybeCode === 'string' || typeof maybeCode === 'number' ? maybeCode : undefined; + + return { + error: { + name: meta.name, + message: meta.message, + stack: meta.stack, + ...(code !== undefined ? { code } : {}), + }, + }; + } + + if (typeof meta === 'object' && meta !== null) { + return meta as LogMeta; + } + + return { meta }; +} + +const baseLogger = pino({ + level: resolveLogLevel(process.env.LOG_LEVEL), + base: null, + timestamp: pino.stdTimeFunctions.isoTime, + formatters: { + level(label) { + return { level: label.toUpperCase() }; + }, + }, +}); + +function writeLog(level: LogLevel, message: string, meta?: unknown): void { + const logMeta = toLogMeta(meta); + if (logMeta) { + baseLogger[level](logMeta, message); + return; + } + + baseLogger[level](message); } -/** - * 日志实用工具 - */ export const logger = { - debug(message: string, meta?: any) { - console.debug(formatMessage(LogLevel.DEBUG, message, meta)); + debug(message: string, meta?: unknown): void { + writeLog(LogLevel.DEBUG, message, meta); }, - info(message: string, meta?: any) { - console.info(formatMessage(LogLevel.INFO, message, meta)); + info(message: string, meta?: unknown): void { + writeLog(LogLevel.INFO, message, meta); }, - warn(message: string, meta?: any) { - console.warn(formatMessage(LogLevel.WARN, message, meta)); + warn(message: string, meta?: unknown): void { + writeLog(LogLevel.WARN, message, meta); }, - error(message: string, meta?: any) { - console.error(formatMessage(LogLevel.ERROR, message, meta)); + error(message: string, meta?: unknown): void { + writeLog(LogLevel.ERROR, message, meta); }, };