Update version to 0.0.16, add Appender and AppenderFactory classes, refactor LoggerFactory methods, and implement logging functionality with tests.
This commit is contained in:
@@ -27,7 +27,7 @@ export default class LoggerFactory {
|
||||
return LoggerFactory._loggers.get(category) as Logger;
|
||||
}
|
||||
|
||||
public static applyApppender(appender: IAppender): Disposable {
|
||||
public static applyAppender(appender: IAppender): Disposable {
|
||||
LoggerFactory._appenders.add(appender);
|
||||
|
||||
return new Disposable(() => LoggerFactory._appenders.delete(appender));
|
||||
@@ -40,10 +40,10 @@ export default class LoggerFactory {
|
||||
}
|
||||
|
||||
private static applyConsoleAppender(): void {
|
||||
LoggerFactory.applyApppender(new ConsoleAppender());
|
||||
LoggerFactory.applyAppender(new ConsoleAppender());
|
||||
}
|
||||
|
||||
private static applyRemoteAppender(): void {
|
||||
LoggerFactory.applyApppender(new TechnikerMeAppender());
|
||||
LoggerFactory.applyAppender(new TechnikerMeAppender());
|
||||
}
|
||||
}
|
||||
|
||||
62
src/appenders/Appender.ts
Normal file
62
src/appenders/Appender.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import {LoggingLevelType} from '../level/LoggingLevel';
|
||||
import ILogMessage from './LogMessage';
|
||||
|
||||
export type AppenderOptions = {
|
||||
domain?: string;
|
||||
};
|
||||
|
||||
export default class Appender {
|
||||
private readonly _logRecorderUrl: string = 'https://logserver.techniker.me/api/logs';
|
||||
private readonly _domain: string = typeof window !== 'undefined' ? (window.location?.hostname ?? '') : '';
|
||||
private readonly _logMessageQueue: ILogMessage[] = [];
|
||||
private _pendingPostLogMessagePromise: Promise<Response | undefined> | undefined = undefined;
|
||||
|
||||
constructor(logRecorderUrl: string, {domain}: AppenderOptions) {
|
||||
this._logRecorderUrl = logRecorderUrl;
|
||||
this._domain = domain ?? this._domain;
|
||||
}
|
||||
|
||||
public log(timestamp: string, level: LoggingLevelType, category: string, message: string): void {
|
||||
const logMessage = {
|
||||
timestamp,
|
||||
domain: this._domain,
|
||||
level,
|
||||
category,
|
||||
message
|
||||
};
|
||||
this.queueMessage(logMessage);
|
||||
this.postLogMessage();
|
||||
}
|
||||
|
||||
private async postLogMessage(): Promise<void> {
|
||||
const logMessage = this._logMessageQueue.shift();
|
||||
|
||||
if (!logMessage || this._pendingPostLogMessagePromise !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof fetch === 'undefined') {
|
||||
console.error('Fetch API is not available in this environment');
|
||||
return;
|
||||
}
|
||||
|
||||
this._pendingPostLogMessagePromise = fetch(this._logRecorderUrl, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json'
|
||||
},
|
||||
mode: 'no-cors',
|
||||
method: 'POST',
|
||||
body: JSON.stringify(logMessage)
|
||||
}).then(() => (this._pendingPostLogMessagePromise = undefined));
|
||||
} catch (e) {
|
||||
console.error('Unable to send logs due to [%o]', e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private queueMessage(logMessage: ILogMessage): void {
|
||||
this._logMessageQueue.push(logMessage);
|
||||
}
|
||||
}
|
||||
12
src/appenders/AppenderFactory.ts
Normal file
12
src/appenders/AppenderFactory.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import {AppenderOptions} from './Appender';
|
||||
import Appender from './Appender';
|
||||
|
||||
export default class AppnederFactory {
|
||||
public static createRemoteAppender(remoteAppenderUrl: string, {domain}: AppenderOptions): Appender {
|
||||
return new Appender(remoteAppenderUrl, {domain});
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
throw new Error('AppenderFactory is a static class that may not be instantiated');
|
||||
}
|
||||
}
|
||||
6
src/appenders/LogMessage.ts
Normal file
6
src/appenders/LogMessage.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export default interface ILogMessage {
|
||||
timestamp: string;
|
||||
level: string;
|
||||
category: string;
|
||||
message: string;
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import type ILogger from './ILogger';
|
||||
import type IAppender from './appenders/IAppender';
|
||||
import AppenderFactory from './appenders/AppenderFactory';
|
||||
import LoggerFactory from './LoggerFactory';
|
||||
import LoggingLevelMapping from './level/LoggingLevelMapping';
|
||||
|
||||
export type {ILogger, IAppender};
|
||||
export {LoggerFactory, LoggingLevelMapping};
|
||||
export default {LoggerFactory, LoggingLevelMapping};
|
||||
export {AppenderFactory, LoggerFactory, LoggingLevelMapping};
|
||||
export default {AppenderFactory, LoggerFactory, LoggingLevelMapping};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
export enum LoggingLevel {
|
||||
Off = -1,
|
||||
Info = 10,
|
||||
Warn = 20,
|
||||
Error = 30,
|
||||
Debug = 40,
|
||||
Trace = 50,
|
||||
Silly = 60,
|
||||
All = 100
|
||||
Debug = 10,
|
||||
Trace = 20,
|
||||
Silly = 30,
|
||||
Info = 40,
|
||||
Warn = 50,
|
||||
Error = 60,
|
||||
All = 70
|
||||
}
|
||||
|
||||
export type LoggingLevelType = 'Off' | 'Info' | 'Warn' | 'Error' | 'Debug' | 'Trace' | 'Silly' | 'All';
|
||||
export type LoggingLevelType = 'Off' | 'Debug' | 'Trace' | 'Info' | 'Silly' | 'Warn' | 'Error' | 'All';
|
||||
|
||||
@@ -3,7 +3,7 @@ import Defaults from '../Defaults';
|
||||
import {LoggingLevel} from './LoggingLevel';
|
||||
|
||||
class Threshold {
|
||||
private _threshold: Subject<LoggingLevel> = new Subject(LoggingLevel.Debug);
|
||||
private _threshold: Subject<LoggingLevel> = new Subject(LoggingLevel.Info);
|
||||
|
||||
constructor(loggingLevel?: LoggingLevel) {
|
||||
this._threshold = new Subject(loggingLevel ?? Defaults.loggingLevel);
|
||||
|
||||
Reference in New Issue
Block a user