Skip to content

Commit

Permalink
feat(winston): integrate winston logger
Browse files Browse the repository at this point in the history
add @kibibit/nestjs-winston to support logging with winston, and a mock service for the test to
disable logging alltogether for the test applications
  • Loading branch information
thatkookooguy committed May 18, 2021
1 parent 4e2817a commit f3793d5
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 41 deletions.
295 changes: 266 additions & 29 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
"dependencies": {
"@kibibit/consologo": "^1.2.0",
"@kibibit/kb-error": "^1.0.3",
"@kibibit/nestjs-winston": "0.5.0",
"@nestjs/common": "^7.6.11",
"@nestjs/core": "^7.6.11",
"@nestjs/mongoose": "^7.0.4",
Expand All @@ -139,8 +140,10 @@
"rimraf": "^3.0.2",
"rxjs": "^6.6.3",
"smee-client": "^1.2.2",
"bytes": "^3.1.0",
"swagger-ui-express": "^4.1.6",
"uuid": "^8.3.2"
"uuid": "^8.3.2",
"winston": "^3.3.3"
},
"config": {
"commitizen": {
Expand Down
2 changes: 1 addition & 1 deletion server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"generate-barrels": "barrelsby --delete -d ./src -l below -q --exclude spec.ts",
"generate-barrels": "barrelsby --delete -d ./src -l below -q --exclude spec.ts --exclude __mocks__",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
Expand Down
4 changes: 4 additions & 0 deletions server/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

import { WinstonModule } from '@kibibit/nestjs-winston';

import { ApiModule } from '@kb-api';
import { ConfigModule } from '@kb-config';
import { EventsGateway, EventsModule } from '@kb-events';
Expand All @@ -10,6 +13,7 @@ import { AppController } from './app.controller';

@Module({
imports: [
WinstonModule.forRoot({}),
ApiModule,
ScheduleModule.forRoot(),
EventsModule,
Expand Down
10 changes: 7 additions & 3 deletions server/src/bootstrap-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { NestExpressApplication } from '@nestjs/platform-express';
import { WsAdapter } from '@nestjs/platform-ws';

import { terminalConsoleLogo } from '@kibibit/consologo';
import { WINSTON_MODULE_NEST_PROVIDER } from '@kibibit/nestjs-winston';

import { AppModule } from '@kb-app';
import { ConfigService } from '@kb-config';
Expand All @@ -17,10 +18,13 @@ const config = new ConfigService();
const appRoot = config.appRoot;

export async function bootstrap(): Promise<NestExpressApplication> {
terminalConsoleLogo('kibibit server template', [
'change this in server/src/bootstrap-application.ts'
terminalConsoleLogo(config.packageDetails.name, [
`version ${ config.packageDetails.version }`
]);
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
logger: false
});
app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));
app.useWebSocketAdapter(new WsAdapter(app));
app.useGlobalFilters(new KbNotFoundExceptionFilter(appRoot));
app.useGlobalPipes(new ValidationPipe());
Expand Down
15 changes: 15 additions & 0 deletions server/src/config/__mocks__/winston.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import winston, { createLogger } from 'winston';

import {
winstonInstance
} from '@kibibit/nestjs-winston';

winstonInstance.logger = createLogger({
transports: [
new winston.transports.Console({
silent: true,
level: 'debug'
})
]
});
27 changes: 20 additions & 7 deletions server/src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import { camelCase, get } from 'lodash';
import nconf from 'nconf';
import SmeeClient from 'smee-client';

import { Logger } from '@nestjs/common';
import { WinstonLogger } from '@kibibit/nestjs-winston';

import { ConfigValidationError } from '@kb-errors';
import { ApiInfo } from '@kb-models';

import { AchievibitConfig } from './achievibit-config.model';

import './winston.config';

const appRoot = findRoot(__dirname, (dir) => {
const packagePath = join(dir, 'package.json');
const isPackageJsonExists = pathExistsSync(packagePath);
Expand All @@ -34,14 +36,13 @@ const appRoot = findRoot(__dirname, (dir) => {
return false;
});
const environment = get(process, 'env.NODE_ENV', 'development');
const eventLogger: Logger = new Logger('SmeeEvents');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(eventLogger as any).info = eventLogger.log;
const defaultConfigFilePath = join(appRoot, 'defaults.env.json');
const configFilePath = join(appRoot, `${ environment }.env.json`);

const packageDetails = new ApiInfo(readJSONSync(join(appRoot, 'package.json')));

const eventLogger: WinstonLogger = new WinstonLogger('SmeeEvents');

interface IEvents {
close(): void;
}
Expand Down Expand Up @@ -70,7 +71,7 @@ let configService: ConfigService;
*/
@Exclude()
export class ConfigService extends AchievibitConfig {
private logger: Logger = new Logger('ConfigService');
private logger: WinstonLogger = new WinstonLogger('ConfigService');

private readonly mode: string = environment;

Expand Down Expand Up @@ -113,12 +114,24 @@ export class ConfigService extends AchievibitConfig {
target:
`http://localhost:${ this.port }/${ this.webhookDestinationUrl }`,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
logger: eventLogger as any
logger: {
error(...data: any[]) {
const message = data.shift();
console.log(data);
const metadata = data.length ? { data } : undefined;
eventLogger.error(message, metadata);
},
info(...data: any[]) {
const message = data.shift();
const metadata = data.length ? { data } : undefined;
eventLogger.info(message, metadata);
}
}
});
}

if (!events) {
this.logger.log('Starting to listen to events from Proxy');
// this.logger.log('Starting to listen to events from Proxy');
events = this.smee.start();
}
} else {
Expand Down
1 change: 1 addition & 0 deletions server/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './achievibit-config.model';
export * from './config.module';
export * from './config.service';
export * from './json-schema.validator';
export * from './winston.config';
80 changes: 80 additions & 0 deletions server/src/config/winston.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { basename } from 'path';

import bytes from 'bytes';
import winston, { createLogger } from 'winston';

import {
utilities as nestWinstonModuleUtilities,
winstonInstance
} from '@kibibit/nestjs-winston';

const fiveMegaBytes = bytes('5MB');

const omitMeta = [
'file',
'env'
];

// console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);

winstonInstance.logger = createLogger({
transports: [
new winston.transports.Console({
level: 'debug',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.ms(),
nestWinstonModuleUtilities.format.nestLike('achievibit', omitMeta),
)
}),
new winston.transports.File({
level: 'debug',
filename: '../logs/server.log',
maxsize: fiveMegaBytes,
maxFiles: 5,
tailable: true
})
],
exceptionHandlers: [
new winston.transports.File({
level: 'debug',
filename: '../logs/exceptions.log',
maxsize: fiveMegaBytes,
maxFiles: 5,
tailable: true
})
],
handleExceptions: true,
format: winston.format.combine(
winston.format((info) => {
info.env = process.env.NODE_ENV;
const filename = getCallerFile();

if (filename) {
info.file = basename(getCallerFile());
}
return info;
})(),
winston.format.timestamp(),
winston.format.splat(),
winston.format.json()
)
});

function getCallerFile(): string {
try {
const err = new Error();
let callerfile;
Error.prepareStackTrace = function (err, stack) { return stack; };
const currentfile = (err.stack as any).shift().getFileName();

while (err.stack.length) {
callerfile = (err.stack as any).shift().getFileName();

if (currentfile !== callerfile &&
!callerfile.includes('node_modules') &&
!callerfile.includes('internal/process')) return callerfile;
}
} catch (err) { }
return '';
}
4 changes: 4 additions & 0 deletions server/test-tools/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import '../src/config/winston.config';

jest.mock('../src/config/winston.config');

const nativeConsoleError = global.console.warn;

global.console.warn = (...args) => {
Expand Down

0 comments on commit f3793d5

Please sign in to comment.