UNPKG

amos-ionic-logging

Version:
206 lines (181 loc) 5.95 kB
import * as log4javascript from "log4javascript"; import { LocalStorageAppenderConfiguration } from "./local-storage-appender.configuration"; import { LogLevelConverter } from "./log-level.converter"; import { LogLevel } from "./log-level.model"; import { LogMessage } from "./log-message.model"; /** * An appender which stores the log messages in the browser's local storage. * * The messages are saved JSON-serialized. * You have to configure which key is used for storing the messages. * * A typical configuration could be: * * ```json * { * "localStorageKey": "myLogs", * "maxMessages": 500, * "threshold": "INFO" * } * ``` */ export class LocalStorageAppender extends log4javascript.Appender { private static maxMessagesDefault = 250; private static thresholdDefault = "WARN"; private maxMessages: number; private localStorageKey: string; private logMessages: LogMessage[]; /** * Creates a new instance of the appender. * * @param configuration configuration for the appender. */ constructor(configuration: LocalStorageAppenderConfiguration) { super(); if (!configuration) { throw new Error("configuration must be not empty"); } if (!configuration.localStorageKey || configuration.localStorageKey === "") { throw new Error("localStorageKey must be not empty"); } this.localStorageKey = configuration.localStorageKey; // read existing logMessages this.logMessages = LocalStorageAppender.loadLogMessages(this.localStorageKey); // process remaining configuration this.configure({ localStorageKey: configuration.localStorageKey, maxMessages: configuration.maxMessages || LocalStorageAppender.maxMessagesDefault, threshold: configuration.threshold || LocalStorageAppender.thresholdDefault, }); } /** * Load log messages from local storage which are stored there under the given key. * * @param localStorageKey local storage key * @return stored messages */ public static loadLogMessages(localStorageKey: string): LogMessage[] { let logMessages: LogMessage[]; if (!localStorageKey || localStorage.getItem(localStorageKey) === null) { logMessages = []; } else { logMessages = JSON.parse(localStorage.getItem(localStorageKey)); for (const logMessage of logMessages) { // timestamps are serialized as strings logMessage.timeStamp = new Date(logMessage.timeStamp); } } return logMessages; } /** * Remove log messages from local storage which are stored there under the given key. * * @param localStorageKey local storage key */ public static removeLogMessages(localStorageKey: string): void { localStorage.removeItem(localStorageKey); } /** * Configures the logging depending on the given configuration. * * Only the defined properties get overwritten. * The localStorageKey cannot be modified. * * @param configuration configuration data. */ public configure(configuration: LocalStorageAppenderConfiguration): void { if (configuration) { if (configuration.localStorageKey && configuration.localStorageKey !== this.localStorageKey) { throw new Error("localStorageKey must not be changed"); } if (configuration.maxMessages) { this.setMaxMessages(configuration.maxMessages); } if (configuration.threshold) { const convertedThreshold = LogLevelConverter.levelToLog4Javascript( LogLevelConverter.levelFromString(configuration.threshold)); this.setThreshold(convertedThreshold); } } } /** * Appender-specific method to append a log message. * * @param loggingEvent event to be appended. */ public append(loggingEvent: log4javascript.LoggingEvent): void { // if logMessages is already full, remove oldest element while (this.logMessages.length >= this.maxMessages) { this.logMessages.shift(); } // add event to logMessages const message: LogMessage = { level: LogLevel[LogLevelConverter.levelFromLog4Javascript(loggingEvent.level)], logger: typeof loggingEvent.logger !== "undefined" ? loggingEvent.logger.name : undefined, message: loggingEvent.messages.slice(1), methodName: loggingEvent.messages[0], timeStamp: loggingEvent.timeStamp, }; this.logMessages.push(message); // write values to localStorage localStorage.setItem(this.localStorageKey, JSON.stringify(this.logMessages)); } /** * Gets the appender's name. * Mainly for unit testing purposes. * * @return appender's name */ public toString(): string { return "Ionic.Logging.LocalStorageAppender"; } /** * Get the key which is used to store the messages in the local storage. */ public getLocalStorageKey(): string { return this.localStorageKey; } /** * Get the maximum number of messages which will be stored in local storage. */ public getMaxMessages(): number { return this.maxMessages; } /** * Set the maximum number of messages which will be stored in local storage. * * If the appender stores currently more messages than the new value allows, the oldest messages get removed. * * @param value new maximum number */ public setMaxMessages(value: number): void { if (this.maxMessages !== value) { this.maxMessages = value; if (this.logMessages.length > this.maxMessages) { // there are too much logMessages for the new value, therefore remove oldest messages while (this.logMessages.length > this.maxMessages) { this.logMessages.shift(); } // write values to localStorage localStorage.setItem(this.localStorageKey, JSON.stringify(this.logMessages)); } } } /** * Gets all messages stored in local storage. * Mainly for unit testing purposes. * * @return stored messages */ public getLogMessages(): LogMessage[] { return this.logMessages; } /** * Removes all messages from local storage. * Mainly for unit testing purposes. */ public clearLog(): void { this.logMessages = []; localStorage.removeItem(this.localStorageKey); } }