From 135b9930f6b1740dcb3c04fb45d20fe4cd5b1ebc Mon Sep 17 00:00:00 2001 From: Collin Duncan <3679940+cgduncan7@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:44:12 +0200 Subject: [PATCH] Adding new database logger for logging database related things --- src/app.module.ts | 11 ++- src/email/client.ts | 2 +- src/logger/middleware.ts | 2 +- src/logger/module.ts | 7 +- src/logger/service.database_logger.ts | 72 ++++++++++++++++++++ src/logger/{service.ts => service.logger.ts} | 0 src/recurringReservations/cron.ts | 4 +- src/reservations/controller.ts | 2 +- src/reservations/cron.ts | 6 +- src/reservations/worker.ts | 2 +- src/runner/baanreserveren/service.ts | 2 +- src/waitingList/service.ts | 2 +- 12 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 src/logger/service.database_logger.ts rename src/logger/{service.ts => service.logger.ts} (100%) diff --git a/src/app.module.ts b/src/app.module.ts index 68534dc..46ad06d 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -8,6 +8,7 @@ import { resolve } from 'path' import { EmailModule } from './email/module' import { LoggerMiddleware } from './logger/middleware' import { LoggerModule } from './logger/module' +import { DatabaseLoggerService } from './logger/service.database_logger' import { RecurringReservationsModule } from './recurringReservations/module' import { ReservationsModule } from './reservations/module' import { RunnerModule } from './runner/module' @@ -17,9 +18,12 @@ import { WaitingListModule } from './waitingList/module' imports: [ ConfigModule.forRoot({ isGlobal: true }), TypeOrmModule.forRootAsync({ - imports: [ConfigModule], - inject: [ConfigService], - useFactory: (configService: ConfigService) => ({ + imports: [ConfigModule, LoggerModule], + inject: [ConfigService, DatabaseLoggerService], + useFactory: ( + configService: ConfigService, + databaseLoggerService: DatabaseLoggerService, + ) => ({ type: 'sqlite', database: configService.get( 'DATABASE', @@ -28,6 +32,7 @@ import { WaitingListModule } from './waitingList/module' migrations: [], autoLoadEntities: true, logging: true, + logger: databaseLoggerService, }), }), BullModule.forRootAsync({ diff --git a/src/email/client.ts b/src/email/client.ts index 0c44dce..45e25ac 100644 --- a/src/email/client.ts +++ b/src/email/client.ts @@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config' import * as Imap from 'imap' import { MailParser, ParsedEmail } from 'mailparser-mit' -import { LoggerService } from '../logger/service' +import { LoggerService } from '../logger/service.logger' import { Email } from './types' export enum EmailClientStatus { diff --git a/src/logger/middleware.ts b/src/logger/middleware.ts index 2b8657a..28eceb0 100644 --- a/src/logger/middleware.ts +++ b/src/logger/middleware.ts @@ -1,7 +1,7 @@ import { Inject, Injectable, NestMiddleware } from '@nestjs/common' import { NextFunction, Request, Response } from 'express' -import { LoggerService } from './service' +import { LoggerService } from './service.logger' @Injectable() export class LoggerMiddleware implements NestMiddleware { diff --git a/src/logger/module.ts b/src/logger/module.ts index 31ed920..4de8562 100644 --- a/src/logger/module.ts +++ b/src/logger/module.ts @@ -1,10 +1,11 @@ import { Module } from '@nestjs/common' import { LoggerMiddleware } from './middleware' -import { LoggerService } from './service' +import { DatabaseLoggerService } from './service.database_logger' +import { LoggerService } from './service.logger' @Module({ - providers: [LoggerService, LoggerMiddleware], - exports: [LoggerService, LoggerMiddleware], + providers: [LoggerService, DatabaseLoggerService, LoggerMiddleware], + exports: [LoggerService, DatabaseLoggerService, LoggerMiddleware], }) export class LoggerModule {} diff --git a/src/logger/service.database_logger.ts b/src/logger/service.database_logger.ts new file mode 100644 index 0000000..1e87202 --- /dev/null +++ b/src/logger/service.database_logger.ts @@ -0,0 +1,72 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { Inject, Injectable } from '@nestjs/common' +import { Logger, QueryRunner } from 'typeorm' + +import { LoggerService } from './service.logger' + +@Injectable() +export class DatabaseLoggerService implements Logger { + constructor( + @Inject(LoggerService) + private loggerService: LoggerService, + ) {} + + logQuery( + query: string, + parameters?: any[] | undefined, + _queryRunner?: QueryRunner | undefined, + ) { + this.loggerService.debug('Query', `${query} - ${parameters?.join(',')}`) + } + + logQueryError( + error: string | Error, + query: string, + parameters?: any[] | undefined, + _queryRunner?: QueryRunner | undefined, + ) { + this.loggerService.error( + 'Query error', + `${error}: ${query} - ${parameters?.join(',')}`, + ) + } + + logQuerySlow( + time: number, + query: string, + parameters?: any[] | undefined, + _queryRunner?: QueryRunner | undefined, + ) { + this.loggerService.warn( + 'Slow query', + `${query} - ${parameters?.join(',')} took ${time}`, + ) + } + + logSchemaBuild(message: string, _queryRunner?: QueryRunner | undefined) { + this.log('info', message) + } + + logMigration(message: string, _queryRunner?: QueryRunner | undefined) { + this.log('info', message) + } + + log( + level: 'log' | 'info' | 'warn', + message: any, + _queryRunner?: QueryRunner | undefined, + ) { + let logFn: (message: any) => void + switch (level) { + case 'warn': + logFn = this.loggerService.warn + break + case 'log': + case 'info': + default: + logFn = this.loggerService.log + } + + logFn(message) + } +} diff --git a/src/logger/service.ts b/src/logger/service.logger.ts similarity index 100% rename from src/logger/service.ts rename to src/logger/service.logger.ts diff --git a/src/recurringReservations/cron.ts b/src/recurringReservations/cron.ts index cd8a679..a4c7ff4 100644 --- a/src/recurringReservations/cron.ts +++ b/src/recurringReservations/cron.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common' import { Cron, CronExpression } from '@nestjs/schedule' import dayjs from '../common/dayjs' -import { LoggerService } from '../logger/service' +import { LoggerService } from '../logger/service.logger' import { RecurringReservationsService } from './service' @Injectable() @@ -20,6 +20,7 @@ export class RecurringReservationsCronService { timeZone: 'Europe/Amsterdam', }) async handleRecurringReservations() { + this.loggerService.log('handleRecurringReservations beginning') const dayOfWeek = dayjs().get('day') const recurringReservationsToSchedule = await this.recurringReservationsService.getByDayOfWeek(dayOfWeek) @@ -31,5 +32,6 @@ export class RecurringReservationsCronService { recurringReservation, ) } + this.loggerService.log('handleRecurringReservations ending') } } diff --git a/src/reservations/controller.ts b/src/reservations/controller.ts index d96ced2..c127144 100644 --- a/src/reservations/controller.ts +++ b/src/reservations/controller.ts @@ -16,7 +16,7 @@ import { import { Queue } from 'bull' import { Dayjs } from 'dayjs' -import { LoggerService } from '../logger/service' +import { LoggerService } from '../logger/service.logger' import { RESERVATIONS_QUEUE_NAME } from './config' import { Reservation } from './entity' import { ReservationsService } from './service' diff --git a/src/reservations/cron.ts b/src/reservations/cron.ts index e293f7c..2e9dd96 100644 --- a/src/reservations/cron.ts +++ b/src/reservations/cron.ts @@ -4,7 +4,7 @@ import { Cron, CronExpression } from '@nestjs/schedule' import { Queue } from 'bull' import dayjs from '../common/dayjs' -import { LoggerService } from '../logger/service' +import { LoggerService } from '../logger/service.logger' import { RESERVATIONS_QUEUE_NAME } from './config' import { ReservationsService } from './service' @@ -26,6 +26,7 @@ export class ReservationsCronService { timeZone: 'Europe/Amsterdam', }) async handleDailyReservations() { + this.loggerService.log('handleDailyReservations beginning') const reservationsToPerform = await this.reservationService.getByDate( dayjs().subtract(7, 'days'), ) @@ -35,6 +36,7 @@ export class ReservationsCronService { await this.reservationsQueue.addBulk( reservationsToPerform.map((r) => ({ data: r, opts: { attempts: 1 } })), ) + this.loggerService.log('handleDailyReservations ending') } @Cron(CronExpression.EVERY_DAY_AT_11PM, { @@ -42,6 +44,7 @@ export class ReservationsCronService { timeZone: 'Europe/Amsterdam', }) async cleanUpExpiredReservations() { + this.loggerService.log('cleanUpExpiredReservations beginning') const reservations = await this.reservationService.getByDate() this.loggerService.log( `Found ${reservations.length} reservations to delete`, @@ -49,5 +52,6 @@ export class ReservationsCronService { for (const reservation of reservations) { await this.reservationService.deleteById(reservation.id) } + this.loggerService.log('cleanUpExpiredReservations ending') } } diff --git a/src/reservations/worker.ts b/src/reservations/worker.ts index 0ba7fea..3600743 100644 --- a/src/reservations/worker.ts +++ b/src/reservations/worker.ts @@ -3,7 +3,7 @@ import { Inject } from '@nestjs/common' import { Job } from 'bull' import { instanceToPlain, plainToInstance } from 'class-transformer' -import { LoggerService } from '../logger/service' +import { LoggerService } from '../logger/service.logger' import { BaanReserverenService, NoCourtAvailableError, diff --git a/src/runner/baanreserveren/service.ts b/src/runner/baanreserveren/service.ts index e429d1d..d1fc831 100644 --- a/src/runner/baanreserveren/service.ts +++ b/src/runner/baanreserveren/service.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common' import { instanceToPlain } from 'class-transformer' import { Dayjs } from 'dayjs' import { ElementHandle, Page } from 'puppeteer' -import { LoggerService } from 'src/logger/service' +import { LoggerService } from 'src/logger/service.logger' import dayjs from '../../common/dayjs' import { Reservation } from '../../reservations/entity' diff --git a/src/waitingList/service.ts b/src/waitingList/service.ts index fa38537..545a614 100644 --- a/src/waitingList/service.ts +++ b/src/waitingList/service.ts @@ -6,7 +6,7 @@ import { ReservationsService } from 'src/reservations/service' import dayjs from '../common/dayjs' import { EMAILS_QUEUE_NAME } from '../email/config' import { Email } from '../email/types' -import { LoggerService } from '../logger/service' +import { LoggerService } from '../logger/service.logger' import { RESERVATIONS_QUEUE_NAME } from '../reservations/config' import { WaitingListDetails } from './types'