database config

This commit is contained in:
hannathkadher
2025-04-22 21:44:46 +04:00
parent fcb27155d8
commit cff947a84a
3 changed files with 40 additions and 30 deletions

View File

@ -104,7 +104,8 @@ import { winstonLoggerOptions } from '../logger/services/winston.logger';
], ],
namingStrategy: new SnakeNamingStrategy(), namingStrategy: new SnakeNamingStrategy(),
synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))), synchronize: Boolean(JSON.parse(configService.get('DB_SYNC'))),
logging: true, logging: ['query', 'error', 'warn', 'schema', 'migration'],
logger: typeOrmLogger, logger: typeOrmLogger,
extra: { extra: {
charset: 'utf8mb4', charset: 'utf8mb4',

View File

@ -2,48 +2,56 @@ import { Logger as WinstonLogger } from 'winston';
import { Logger as TypeOrmLogger } from 'typeorm'; import { Logger as TypeOrmLogger } from 'typeorm';
import { requestContext } from '@app/common/context/request-context'; import { requestContext } from '@app/common/context/request-context';
const ERROR_THRESHOLD = 2000;
export class TypeOrmWinstonLogger implements TypeOrmLogger { export class TypeOrmWinstonLogger implements TypeOrmLogger {
constructor( constructor(private readonly logger: WinstonLogger) {}
private readonly logger: WinstonLogger,
private readonly slowQueryThreshold = 500, // ms private getContext() {
) {} const context = requestContext.getStore();
return {
requestId: context?.requestId ?? 'N/A',
userId: context?.userId ?? null,
};
}
private extractTable(query: string): string {
const match =
query.match(/from\s+["`]?(\w+)["`]?/i) ||
query.match(/into\s+["`]?(\w+)["`]?/i);
return match?.[1] ?? 'unknown';
}
logQuery(query: string, parameters?: any[]) { logQuery(query: string, parameters?: any[]) {
const context = requestContext.getStore(); const context = this.getContext();
const requestId = context?.requestId ?? 'N/A'; this.logger.debug(`[DB][QUERY] ${query}`, {
const start = Date.now(); ...context,
table: this.extractTable(query),
const timeout = setTimeout(() => {
const duration = Date.now() - start;
const isSlow = duration > this.slowQueryThreshold;
this.logger[isSlow ? 'warn' : 'debug'](`[DB][QUERY] ${query}`, {
requestId,
parameters, parameters,
duration: `${duration}ms`,
isSlow,
}); });
}, 0);
// Just ensures the setTimeout fires after this function returns
clearTimeout(timeout);
} }
logQueryError(error: string | Error, query: string, parameters?: any[]) { logQueryError(error: string | Error, query: string, parameters?: any[]) {
const requestId = requestContext.getStore()?.requestId ?? 'N/A'; const context = this.getContext();
this.logger.error(`[DB][ERROR] ${query}`, { this.logger.error(`[DB][ERROR] ${query}`, {
requestId, ...context,
table: this.extractTable(query),
parameters, parameters,
error, error,
}); });
} }
logQuerySlow(time: number, query: string, parameters?: any[]) { logQuerySlow(time: number, query: string, parameters?: any[]) {
const requestId = requestContext.getStore()?.requestId ?? 'N/A'; const context = this.getContext();
this.logger.warn(`🔥 [DB][SLOW > ${time}ms] ${query}`, { const severity = time > ERROR_THRESHOLD ? 'error' : 'warn';
requestId, const label = severity === 'error' ? 'VERY SLOW' : 'SLOW';
this.logger[severity](`[DB][${label} > ${time}ms] ${query}`, {
...context,
table: this.extractTable(query),
parameters, parameters,
time, duration: `${time}ms`,
severity,
}); });
} }

View File

@ -2,7 +2,8 @@ import { utilities as nestWinstonModuleUtilities } from 'nest-winston';
import * as winston from 'winston'; import * as winston from 'winston';
export const winstonLoggerOptions: winston.LoggerOptions = { export const winstonLoggerOptions: winston.LoggerOptions = {
level: 'debug', level:
process.env.AZURE_POSTGRESQL_DATABASE === 'development' ? 'debug' : 'error',
transports: [ transports: [
new winston.transports.Console({ new winston.transports.Console({
format: winston.format.combine( format: winston.format.combine(