mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-27 02:24:54 +00:00
database config
This commit is contained in:
@ -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',
|
||||||
|
|||||||
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user