UNPKG

core-native

Version:

A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.

138 lines (116 loc) 4.8 kB
import {loggerContext} from "./platform/loggerContext"; import {app} from "./app"; import {APIException, Exception, NetworkConnectionException, ReactLifecycleException, RuntimeException} from "./Exception"; interface Log { date: Date; result: "OK" | "WARN" | "ERROR"; context: {[key: string]: string}; // To store indexed data (for Elastic Search) info: {[key: string]: string}; // To store text data (no index) elapsedTime: number; action?: string; errorCode?: string; } /** * If eventLogger config is provided in non-DEV environment * All collected logs will automatically sent to {serverURL} every {sendingFrequency} second * * The request will be PUT to the server in the following format * {events: Log[]} */ export interface LoggerConfig { serverURL: string; sendingFrequency: number; maskedKeywords?: RegExp[]; } export interface Logger { addContext(context: {[key: string]: string | (() => string)}): void; /** * Add a log item, whose result is OK */ info(action: string, info?: {[key: string]: string}): () => void; /** * Add a log item, whose result is WARN * @errorCode: Naming in upper-case and underscore, e.g: SOME_DATA */ warn(errorCode: string, action?: string, info?: {[key: string]: string}): () => void; /** * Add a log item, whose result is ERROR * @errorCode: Naming in upper-case and underscore, e.g: SOME_DATA */ error(errorCode: string, action?: string, info?: {[key: string]: string}): () => void; /** * This function can auto convert to ERROR/WARN level with exception information, according to type */ exception(exception: Exception): () => void; } export class LoggerImpl implements Logger { private environmentContext: {[key: string]: string | (() => string)} = {}; private logQueue: Log[] = []; constructor() { this.environmentContext = loggerContext; } addContext(context: {[key: string]: string | (() => string)}): void { this.environmentContext = {...this.environmentContext, ...context}; } info(action: string, info?: {[key: string]: string}): () => void { return this.appendLog("OK", action, undefined, info); } warn(errorCode: string, action?: string, info?: {[key: string]: string}): () => void { return this.appendLog("WARN", action, errorCode, info); } error(errorCode: string, action?: string, info?: {[key: string]: string}): () => void { return this.appendLog("ERROR", action, errorCode, info); } exception(exception: Exception): () => void { if (exception instanceof NetworkConnectionException) { return this.appendLog("WARN", undefined, "NETWORK_FAILURE", {errorMessage: exception.message}); } else { const info: {[key: string]: string} = {errorMessage: exception.message}; let errorCode: string = "ERROR"; if (exception instanceof APIException) { errorCode = `API_ERROR:${exception.statusCode}`; info.requestURL = exception.requestURL; if (exception.errorCode) { info.errorCode = exception.errorCode; } if (exception.errorId) { info.errorId = exception.errorId; } } else if (exception instanceof ReactLifecycleException) { errorCode = "LIFECYCLE_ERROR"; info.stackTrace = exception.componentStack; info.appState = JSON.stringify(app.store.getState().app); } else if (exception instanceof RuntimeException) { errorCode = "JS_ERROR"; info.stackTrace = JSON.stringify(exception.errorObject); info.appState = JSON.stringify(app.store.getState().app); } return this.appendLog("ERROR", undefined, errorCode, info); } } collect(): Log[] { return this.logQueue; } empty(): void { this.logQueue = []; } private appendLog(result: "OK" | "WARN" | "ERROR", action?: string, errorCode?: string, info?: {[key: string]: string}): () => void { const completeContext = {}; Object.entries(this.environmentContext).map(([key, value]) => { completeContext[key] = typeof value === "string" ? value : value(); }); const event: Log = { date: new Date(), result, action, errorCode, info: info || {}, context: completeContext, elapsedTime: 0, }; this.logQueue.push(event); return () => { event.elapsedTime = new Date().getTime() - event.date.getTime(); }; } }