feat(storage): add structured logging with Pino

Setup nestjs-pino for structured JSON logging in production and
pretty-printed colorized logs in development. Health/metrics
endpoints excluded from auto-logging to reduce noise.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-26 13:18:58 +01:00
parent 1c844f4f5d
commit 8692b0824e
4 changed files with 393 additions and 109 deletions

View file

@ -37,6 +37,9 @@
"dotenv": "^16.4.7",
"drizzle-kit": "^0.30.2",
"drizzle-orm": "^0.38.3",
"nestjs-pino": "^4.6.1",
"pino-http": "^11.0.0",
"pino-pretty": "^13.1.3",
"postgres": "^3.4.5",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1"

View file

@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ThrottlerModule } from '@nestjs/throttler';
import { LoggerModule } from 'nestjs-pino';
import { DatabaseModule } from './db/database.module';
import { HealthModule } from '@manacore/shared-nestjs-health';
import { MetricsModule } from '@manacore/shared-nestjs-metrics';
@ -18,6 +19,16 @@ import { AdminModule } from './admin/admin.module';
ConfigModule.forRoot({
isGlobal: true,
}),
LoggerModule.forRoot({
pinoHttp: {
transport:
process.env.NODE_ENV !== 'production'
? { target: 'pino-pretty', options: { colorize: true, singleLine: true } }
: undefined,
level: process.env.NODE_ENV !== 'production' ? 'debug' : 'info',
autoLogging: { ignore: (req) => ['/health', '/metrics'].includes((req as any).url) },
},
}),
ThrottlerModule.forRoot([
{
ttl: 60000, // 60 seconds

View file

@ -3,10 +3,12 @@ import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { Logger } from 'nestjs-pino';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const app = await NestFactory.create(AppModule, { bufferLogs: true });
app.useLogger(app.get(Logger));
const configService = app.get(ConfigService);
const port = configService.get<number>('PORT') || 3016;
@ -38,8 +40,9 @@ async function bootstrap() {
SwaggerModule.setup('api/docs', app, document);
await app.listen(port);
console.log(`Storage backend running on http://localhost:${port}`);
console.log(`Swagger docs at http://localhost:${port}/api/docs`);
const logger = app.get(Logger);
logger.log(`Storage backend running on http://localhost:${port}`);
logger.log(`Swagger docs at http://localhost:${port}/api/docs`);
}
bootstrap();

479
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff