feat: add logging for typeorm

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2022-04-18 16:26:13 +02:00
parent d3c6deffb4
commit ec398eb160
3 changed files with 110 additions and 5 deletions

View file

@ -28,6 +28,7 @@ import { GroupsModule } from './groups/groups.module';
import { HistoryModule } from './history/history.module'; import { HistoryModule } from './history/history.module';
import { IdentityModule } from './identity/identity.module'; import { IdentityModule } from './identity/identity.module';
import { LoggerModule } from './logger/logger.module'; import { LoggerModule } from './logger/logger.module';
import { TypeormLoggerService } from './logger/typeorm-logger.service';
import { MediaModule } from './media/media.module'; import { MediaModule } from './media/media.module';
import { MonitoringModule } from './monitoring/monitoring.module'; import { MonitoringModule } from './monitoring/monitoring.module';
import { NotesModule } from './notes/notes.module'; import { NotesModule } from './notes/notes.module';
@ -50,9 +51,12 @@ const routes: Routes = [
imports: [ imports: [
RouterModule.forRoutes(routes), RouterModule.forRoutes(routes),
TypeOrmModule.forRootAsync({ TypeOrmModule.forRootAsync({
imports: [ConfigModule], imports: [ConfigModule, LoggerModule],
inject: [databaseConfig.KEY], inject: [databaseConfig.KEY, TypeormLoggerService],
useFactory: (databaseConfig: DatabaseConfig) => { useFactory: (
databaseConfig: DatabaseConfig,
logger: TypeormLoggerService,
) => {
return { return {
type: databaseConfig.type, type: databaseConfig.type,
host: databaseConfig.host, host: databaseConfig.host,
@ -62,6 +66,8 @@ const routes: Routes = [
database: databaseConfig.database, database: databaseConfig.database,
autoLoadEntities: true, autoLoadEntities: true,
synchronize: true, // ToDo: Remove this before release synchronize: true, // ToDo: Remove this before release
logging: true,
logger: logger,
}; };
}, },
}), }),

View file

@ -6,9 +6,10 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ConsoleLoggerService } from './console-logger.service'; import { ConsoleLoggerService } from './console-logger.service';
import { TypeormLoggerService } from './typeorm-logger.service';
@Module({ @Module({
providers: [ConsoleLoggerService], providers: [ConsoleLoggerService, TypeormLoggerService],
exports: [ConsoleLoggerService], exports: [ConsoleLoggerService, TypeormLoggerService],
}) })
export class LoggerModule {} export class LoggerModule {}

View file

@ -0,0 +1,98 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*
* The code in this class is based on:
* https://github.com/typeorm/typeorm/blob/master/src/logger/AdvancedConsoleLogger.ts
*/
import { Injectable } from '@nestjs/common';
import { Logger, QueryRunner } from 'typeorm';
import { PlatformTools } from 'typeorm/platform/PlatformTools';
import { ConsoleLoggerService } from './console-logger.service';
@Injectable()
export class TypeormLoggerService implements Logger {
constructor(private readonly logger: ConsoleLoggerService) {
this.logger.setContext('TypeORM');
this.logger.setSkipColor(true);
}
log(level: 'log' | 'info' | 'warn', message: unknown, _?: QueryRunner): void {
switch (level) {
case 'log':
case 'info':
this.logger.log(message);
break;
case 'warn':
this.logger.warn(message);
}
}
logMigration(message: string, _?: QueryRunner): void {
// eslint-disable-next-line local-rules/correct-logger-context
this.logger.log(message, 'migration');
}
logQuery(query: string, parameters?: unknown[], _?: QueryRunner): void {
const sql =
query +
(parameters && parameters.length
? ' -- PARAMETERS: ' + this.stringifyParams(parameters)
: '');
// eslint-disable-next-line local-rules/correct-logger-context
this.logger.debug(PlatformTools.highlightSql(sql), 'query');
}
logQueryError(
error: string | Error,
query: string,
parameters?: unknown[],
_?: QueryRunner,
): void {
const sql =
query +
(parameters && parameters.length
? ` -- PARAMETERS: ${this.stringifyParams(parameters)}`
: '');
this.logger.debug(PlatformTools.highlightSql(sql));
// eslint-disable-next-line local-rules/correct-logger-context
this.logger.debug(error.toString(), 'queryError');
}
logQuerySlow(
time: number,
query: string,
parameters?: unknown[],
_?: QueryRunner,
): void {
const sql =
query +
(parameters && parameters.length
? ` -- PARAMETERS: ${this.stringifyParams(parameters)}`
: '');
/* eslint-disable local-rules/correct-logger-context */
this.logger.warn(PlatformTools.highlightSql(sql), 'querySlow');
this.logger.warn(`execution time: ${time}`, 'querySlow');
/* eslint-enable local-rules/correct-logger-context */
}
logSchemaBuild(message: string, _?: QueryRunner): void {
// eslint-disable-next-line local-rules/correct-logger-context
this.logger.debug(message, 'schemaBuild');
}
/**
* Converts parameters to a string.
* Sometimes parameters can have circular objects and therefore we are handle this case too.
*/
protected stringifyParams(parameters: unknown[]): string {
try {
return JSON.stringify(parameters);
} catch (error) {
// most probably circular objects in parameters
return parameters.toString();
}
}
}