Files
devops-platform-api/src/main.ts
T
湛兮 9343e74b2c fix: 补齐异常阶段请求日志
- src/common/http/all-exceptions.filter.ts: 记录 guard/pipe 阶段的结构化错误日志
- src/main.ts: 写入请求开始时间并向异常过滤器注入结构化 logger
- src/common/logging: 避免成功拦截器重复记录异常日志
2026-06-12 05:44:03 +08:00

51 lines
1.8 KiB
TypeScript

import { NestFactory } from '@nestjs/core';
import { ConfigService } from '@nestjs/config';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { ApiEnvelopeInterceptor } from './common/http/api-envelope.interceptor';
import { AllExceptionsFilter } from './common/http/all-exceptions.filter';
import { HttpRequestLoggingInterceptor } from './common/logging/http-request-logging.interceptor';
import { StructuredLoggerService } from './common/logging/structured-logger.service';
import { EnvConfig } from './config/env.schema';
type RequestWithStartedAt = {
startedAt?: number;
};
async function bootstrap(): Promise<void> {
const app = await NestFactory.create(AppModule, {
bufferLogs: true,
rawBody: true,
});
const config = app.get(ConfigService<EnvConfig, true>);
const corsOrigin = config.get('CORS_ORIGIN', { infer: true });
const structuredLogger = app.get(StructuredLoggerService);
app.use((request: RequestWithStartedAt, _response: unknown, next: () => void) => {
request.startedAt = Date.now();
next();
});
app.enableCors({
origin: corsOrigin ? corsOrigin.split(',').map((origin) => origin.trim()) : true,
credentials: true,
});
app.useGlobalFilters(new AllExceptionsFilter(structuredLogger));
app.useGlobalInterceptors(
app.get(HttpRequestLoggingInterceptor),
new ApiEnvelopeInterceptor(),
);
const swaggerConfig = new DocumentBuilder()
.setTitle('运维平台 API')
.setDescription('提供 Jenkins、Gitea、通知、发布流程、账号权限和 Agent 运维能力接口。')
.setVersion('0.1.0')
.build();
const document = SwaggerModule.createDocument(app, swaggerConfig);
SwaggerModule.setup('docs', app, document);
await app.listen(config.get('PORT', { infer: true }));
}
void bootstrap();