import type {LoggingLevel, LoggingLevelType} from '../LoggingLevel'; import type {IAppender} from './IAppender'; import type ILogMessage from './LogMessage'; export default class TechnikerMeAppender implements IAppender { private readonly _logRecorderUrl: string = 'https://logserver.techniker.me/api/logs'; // @ts-ignore private readonly _domain: string = typeof globalThis !== 'undefined' ? (globalThis.location?.hostname ?? '') : ''; private readonly _logMessageQueue: ILogMessage[] = []; private _pendingPostLogMessagePromise: Promise | undefined = undefined; 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 { 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); } }