mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Make Logger an interface.
This commit is contained in:
committed by
Joachim Van Herwegen
parent
5c218193ab
commit
3685b7c659
@@ -1,27 +1,10 @@
|
||||
import { Logger } from './Logger';
|
||||
import type { BasicLogger } from './Logger';
|
||||
import { WrappingLogger } from './Logger';
|
||||
import type { Logger } from './Logger';
|
||||
import type { LoggerFactory } from './LoggerFactory';
|
||||
import type { LogLevel } from './LogLevel';
|
||||
|
||||
/**
|
||||
* Wraps around another {@link Logger} that can be set lazily.
|
||||
*/
|
||||
class WrappingLogger extends Logger {
|
||||
public logger: BasicLogger;
|
||||
|
||||
public constructor(logger: BasicLogger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public log(level: LogLevel, message: string): Logger {
|
||||
this.logger.log(level, message);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary {@link LoggerFactory} that creates buffered {@link WrappingLogger}s
|
||||
* Temporary {@link LoggerFactory} that buffers log messages in memory
|
||||
* until the {@link TemporaryLoggerFactory#switch} method is called.
|
||||
*/
|
||||
class TemporaryLoggerFactory implements LoggerFactory {
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { LogLevel } from './LogLevel';
|
||||
*
|
||||
* @see getLoggerFor on how to instantiate loggers.
|
||||
*/
|
||||
export type BasicLogger = {
|
||||
export interface SimpleLogger {
|
||||
/**
|
||||
* Log the given message at the given level.
|
||||
* If the internal level is higher than the given level, the message may be voided.
|
||||
@@ -13,15 +13,15 @@ export type BasicLogger = {
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
log: (level: LogLevel, message: string) => BasicLogger;
|
||||
};
|
||||
log: (level: LogLevel, message: string) => SimpleLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs messages, with convenience methods to log on a specific level.
|
||||
*
|
||||
* @see getLoggerFor on how to instantiate loggers.
|
||||
*/
|
||||
export abstract class Logger implements BasicLogger {
|
||||
export interface Logger extends SimpleLogger {
|
||||
/**
|
||||
* Log the given message at the given level.
|
||||
* If the internal level is higher than the given level, the message may be voided.
|
||||
@@ -29,59 +29,97 @@ export abstract class Logger implements BasicLogger {
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
public abstract log(level: LogLevel, message: string): Logger;
|
||||
log: (level: LogLevel, message: string) => Logger;
|
||||
|
||||
/**
|
||||
* Log a message at the 'error' level.
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
public error(message: string): Logger {
|
||||
return this.log('error', message);
|
||||
}
|
||||
error: (message: string) => Logger;
|
||||
|
||||
/**
|
||||
* Log a message at the 'warn' level.
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
public warn(message: string): Logger {
|
||||
return this.log('warn', message);
|
||||
}
|
||||
warn: (message: string) => Logger;
|
||||
|
||||
/**
|
||||
* Log a message at the 'info' level.
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
public info(message: string): Logger {
|
||||
return this.log('info', message);
|
||||
}
|
||||
info: (message: string) => Logger;
|
||||
|
||||
/**
|
||||
* Log a message at the 'verbose' level.
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
public verbose(message: string): Logger {
|
||||
return this.log('verbose', message);
|
||||
}
|
||||
verbose: (message: string) => Logger;
|
||||
|
||||
/**
|
||||
* Log a message at the 'debug' level.
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
public debug(message: string): Logger {
|
||||
return this.log('debug', message);
|
||||
}
|
||||
debug: (message: string) => Logger;
|
||||
|
||||
/**
|
||||
* Log a message at the 'silly' level.
|
||||
* @param message - The message to log.
|
||||
* @param meta - Optional metadata to include in the log message.
|
||||
*/
|
||||
silly: (message: string) => Logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class that implements all additional {@link BaseLogger} methods,
|
||||
* leaving only the implementation of {@link SimpleLogger}.
|
||||
*/
|
||||
export abstract class BaseLogger implements Logger {
|
||||
public abstract log(level: LogLevel, message: string): Logger;
|
||||
|
||||
public error(message: string): Logger {
|
||||
return this.log('error', message);
|
||||
}
|
||||
|
||||
public warn(message: string): Logger {
|
||||
return this.log('warn', message);
|
||||
}
|
||||
|
||||
public info(message: string): Logger {
|
||||
return this.log('info', message);
|
||||
}
|
||||
|
||||
public verbose(message: string): Logger {
|
||||
return this.log('verbose', message);
|
||||
}
|
||||
|
||||
public debug(message: string): Logger {
|
||||
return this.log('debug', message);
|
||||
}
|
||||
|
||||
public silly(message: string): Logger {
|
||||
return this.log('silly', message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@link BaseLogger} around a {@link SimpleLogger},
|
||||
* which can be swapped out a runtime.
|
||||
*/
|
||||
export class WrappingLogger extends BaseLogger {
|
||||
public logger: SimpleLogger;
|
||||
|
||||
public constructor(logger: SimpleLogger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public log(level: LogLevel, message: string): this {
|
||||
this.logger.log(level, message);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Logger } from './Logger';
|
||||
import { BaseLogger } from './Logger';
|
||||
import type { LogLevel } from './LogLevel';
|
||||
|
||||
/**
|
||||
* A logger that does nothing on a log message.
|
||||
*/
|
||||
export class VoidLogger extends Logger {
|
||||
export class VoidLogger extends BaseLogger {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public log(level: LogLevel, message: string, meta?: any): Logger {
|
||||
public log(level: LogLevel, message: string, meta?: any): this {
|
||||
// Do nothing
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { Logger } from './Logger';
|
||||
import type { LoggerFactory } from './LoggerFactory';
|
||||
import { VoidLogger } from './VoidLogger';
|
||||
|
||||
@@ -9,7 +8,7 @@ export class VoidLoggerFactory implements LoggerFactory {
|
||||
private readonly logger = new VoidLogger();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public createLogger(label: string): Logger {
|
||||
public createLogger(label: string): VoidLogger {
|
||||
return this.logger;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { Logger as WinstonInnerLogger } from 'winston';
|
||||
import { Logger } from './Logger';
|
||||
import { BaseLogger } from './Logger';
|
||||
import type { LogLevel } from './LogLevel';
|
||||
|
||||
/**
|
||||
* A WinstonLogger implements the {@link Logger} interface using a given winston logger.
|
||||
*/
|
||||
export class WinstonLogger extends Logger {
|
||||
export class WinstonLogger extends BaseLogger {
|
||||
private readonly logger: WinstonInnerLogger;
|
||||
|
||||
public constructor(logger: WinstonInnerLogger) {
|
||||
|
||||
@@ -1,44 +1,95 @@
|
||||
import { Logger } from '../../../src/logging/Logger';
|
||||
import { BaseLogger, WrappingLogger } from '../../../src/logging/Logger';
|
||||
import type { SimpleLogger } from '../../../src/logging/Logger';
|
||||
|
||||
describe('Logger', (): void => {
|
||||
let logger: Logger;
|
||||
beforeEach(async(): Promise<void> => {
|
||||
logger = new (Logger as any)();
|
||||
logger.log = jest.fn();
|
||||
describe('a BaseLogger', (): void => {
|
||||
let logger: BaseLogger;
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
logger = new (BaseLogger as any)();
|
||||
logger.log = jest.fn();
|
||||
});
|
||||
|
||||
it('delegates error to log.', async(): Promise<void> => {
|
||||
logger.error('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('error', 'my message');
|
||||
});
|
||||
|
||||
it('warn delegates to log.', async(): Promise<void> => {
|
||||
logger.warn('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('warn', 'my message');
|
||||
});
|
||||
|
||||
it('info delegates to log.', async(): Promise<void> => {
|
||||
logger.info('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('info', 'my message');
|
||||
});
|
||||
|
||||
it('verbose delegates to log.', async(): Promise<void> => {
|
||||
logger.verbose('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('verbose', 'my message');
|
||||
});
|
||||
|
||||
it('debug delegates to log.', async(): Promise<void> => {
|
||||
logger.debug('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('debug', 'my message');
|
||||
});
|
||||
|
||||
it('silly delegates to log.', async(): Promise<void> => {
|
||||
logger.silly('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('silly', 'my message');
|
||||
});
|
||||
});
|
||||
|
||||
it('Error delegates to log.', async(): Promise<void> => {
|
||||
logger.error('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('error', 'my message');
|
||||
});
|
||||
describe('a WrappingLogger', (): void => {
|
||||
let logger: SimpleLogger;
|
||||
let wrapper: WrappingLogger;
|
||||
|
||||
it('Warn delegates to log.', async(): Promise<void> => {
|
||||
logger.warn('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('warn', 'my message');
|
||||
});
|
||||
beforeEach(async(): Promise<void> => {
|
||||
logger = { log: jest.fn() };
|
||||
wrapper = new WrappingLogger(logger);
|
||||
});
|
||||
|
||||
it('Info delegates to log.', async(): Promise<void> => {
|
||||
logger.info('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('info', 'my message');
|
||||
});
|
||||
it('Verbose delegates to log.', async(): Promise<void> => {
|
||||
logger.verbose('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('verbose', 'my message');
|
||||
});
|
||||
it('error delegates to the internal logger.', async(): Promise<void> => {
|
||||
wrapper.error('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('error', 'my message');
|
||||
});
|
||||
|
||||
it('Debug delegates to log.', async(): Promise<void> => {
|
||||
logger.debug('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('debug', 'my message');
|
||||
});
|
||||
it('warn delegates to the internal logger.', async(): Promise<void> => {
|
||||
wrapper.warn('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('warn', 'my message');
|
||||
});
|
||||
|
||||
it('Silly delegates to log.', async(): Promise<void> => {
|
||||
logger.silly('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('silly', 'my message');
|
||||
it('info delegates to the internal logger.', async(): Promise<void> => {
|
||||
wrapper.info('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('info', 'my message');
|
||||
});
|
||||
|
||||
it('verbose delegates to the internal logger.', async(): Promise<void> => {
|
||||
wrapper.verbose('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('verbose', 'my message');
|
||||
});
|
||||
|
||||
it('debug delegates to the internal logger.', async(): Promise<void> => {
|
||||
wrapper.debug('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('debug', 'my message');
|
||||
});
|
||||
|
||||
it('silly delegates to the internal logger.', async(): Promise<void> => {
|
||||
wrapper.silly('my message');
|
||||
expect(logger.log).toHaveBeenCalledTimes(1);
|
||||
expect(logger.log).toHaveBeenCalledWith('silly', 'my message');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user