diff --git a/.env.example b/.env.example index c304264..c9e5984 100644 --- a/.env.example +++ b/.env.example @@ -5,5 +5,8 @@ DATABASE_URL=postgres://greact:pG3526l4@194.36.208.86:5433/cloud # Optional. When set, POST /api/ingest requires x-api-key: . INGEST_API_KEY= +# Optional. Logs POST /api/ingest request metadata without x-api-key. +INGEST_DEBUG_LOG= + # Poll interval for GET /api/current/events SSE snapshots. CURRENT_EVENTS_POLL_MS=1000 diff --git a/docker-compose.yml b/docker-compose.yml index a231116..4fe08ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ services: restart: unless-stopped environment: NODE_ENV: production + BRANCH: ${branch:-} PORT: ${PORT} DATABASE_URL: ${DATABASE_URL} INGEST_API_KEY: ${INGEST_API_KEY} diff --git a/src/main.ts b/src/main.ts index d3efa04..eafb9ba 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,30 @@ -import { ValidationPipe } from '@nestjs/common'; +import { Logger, ValidationPipe } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import compression from 'compression'; import { AppModule } from './app.module'; +import { DbService } from './db/db.service'; + +type CurrentDatabaseRow = { + database: string; +}; + +function getMaskedDatabaseUrl(): string | undefined { + const databaseUrl = process.env.DATABASE_URL; + if (!databaseUrl) { + return undefined; + } + + try { + const url = new URL(databaseUrl); + const username = url.username ? `${url.username}:***@` : ''; + return `${url.protocol}//${username}${url.host}${url.pathname}`; + } catch { + return databaseUrl.replace(/:\/\/([^:]+):([^@]+)@/, '://$1:***@'); + } +} -/** Запускает HTTP API со сжатием и глобальной валидацией DTO. */ async function bootstrap() { + const logger = new Logger('Bootstrap'); const app = await NestFactory.create(AppModule); app.use(compression()); app.setGlobalPrefix('api'); @@ -18,6 +38,20 @@ async function bootstrap() { ); await app.listen(process.env.PORT as string); + + const db = app.get(DbService); + const currentDatabase = await db.query( + 'SELECT current_database() AS database', + ); + + logger.log({ + event: 'cloud.started', + port: process.env.PORT, + branch: process.env.BRANCH ?? process.env.branch ?? '', + database: currentDatabase.rows[0]?.database, + databaseUrl: getMaskedDatabaseUrl(), + ingestDebugLog: process.env.INGEST_DEBUG_LOG ?? '', + }); } void bootstrap();