UNPKG

@ng-log/log4a

Version:

A powerful and customizable logging library for Angular application.

362 lines (352 loc) 20 kB
import * as i1 from '@angular/common/http'; import { HttpHeaders } from '@angular/common/http'; import * as i0 from '@angular/core'; import { Injectable, Component, NgModule } from '@angular/core'; import { catchError, throwError } from 'rxjs'; import { of } from 'rxjs/internal/observable/of'; class AbstractLogger { } class ConsoleAppender extends AbstractLogger { log(entry) { entry.buildLogString(); return of(true); } clear() { console.clear(); return of(true); } } class LocalStorageAppender extends AbstractLogger { constructor() { super(); this.location = 'logging'; } log(entry) { let ret = false; let values; try { const location = localStorage.getItem(this.location) ?? ''; values = JSON.parse(location) || []; values.push(entry); localStorage.setItem(this.location, JSON.stringify(values)); ret = true; } catch (e) { console.error(e); } return of(ret); } clear() { localStorage.removeItem(this.location); return of(true); } } class WebApiAppender extends AbstractLogger { constructor(http) { super(); this.http = http; this.location = 'api/logging'; } log(entry) { // let headers = new Headers({ 'Content-Type': 'Content-Type' }); const options = new HttpHeaders().set('Content-Type', 'application/json'); this.http .post(this.location, entry, { headers: options }).pipe(catchError((error, caught) => { console.error('There was an error!', error); // after handling error, return a new observable // that doesn't emit any values and completes return of(); })); return of(true); } clear() { // TODO: Call Web API to clear all values return of(true); } handleErrors(error) { const errors = []; let msg = ''; msg = 'Status: ' + error.status; msg += ' - Status Text: ' + error.statusText; if (error.json()) { msg += ' - Exception Message: ' + error.json().exceptionMessage; } errors.push(msg); console.error('An error occurred', errors); return throwError(errors); } } class AppenderService { constructor(http) { this.http = http; this.appenders = []; console.log('AppenderService Initiated'); } loadConfig(logConfig) { let appender = {}; for (const pub of logConfig.filter(p => p.enable)) { switch (pub.appenderName.toLowerCase()) { case 'console': appender = new ConsoleAppender(); break; case 'localstorage': appender = new LocalStorageAppender(); break; case 'serverapi': appender = new WebApiAppender(this.http); break; } // Set location of logging appender.location = pub.location; // Add publisher to array this.appenders.push(appender); } } loadRuntimeConfig() { let appender = {}; console.log(this.getQueryParams('logger-option')); switch (this.getQueryParams('logger-option')) { case 'console': appender = new ConsoleAppender(); break; case 'localstorage': appender = new LocalStorageAppender(); break; case 'serverapi': appender = new WebApiAppender(this.http); break; } this.appenders.push(appender); } getQueryParams(param) { const href = location.href; const reg = new RegExp('[?&]' + param + '=([^&#]*)', 'i'); const string = reg.exec(href); return string ? string[1] : ''; } } /** @nocollapse */ AppenderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AppenderService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ AppenderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AppenderService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AppenderService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } }); const PUBLISHERS_FILE = 'assets/logging-config.json'; class Log4a { constructor(appenderService, http) { this.appenderService = appenderService; this.http = http; // tslint:disable-next-line: no-use-before-declare this.level = LogLevel.All; this.logWithDate = true; this.abstractAppenders = appenderService.appenders; } async loadConfigs() { const loggerOption = this.appenderService.getQueryParams('logger-option'); if (loggerOption !== '') { this.appenderService.loadRuntimeConfig(); } else { this.http .get(PUBLISHERS_FILE).subscribe((res) => { this.appenderService.loadConfig(res); }); } } debug(msg, ...optionalParams) { // tslint:disable-next-line: no-use-before-declare this.writeToLog(msg, LogLevel.Debug, optionalParams); } info(msg, ...optionalParams) { // tslint:disable-next-line: no-use-before-declare this.writeToLog(msg, LogLevel.Info, optionalParams); } warn(msg, ...optionalParams) { // tslint:disable-next-line: no-use-before-declare this.writeToLog(msg, LogLevel.Warn, optionalParams); } error(msg, ...optionalParams) { // tslint:disable-next-line: no-use-before-declare this.writeToLog(msg, LogLevel.Error, optionalParams); } fatal(msg, ...optionalParams) { // tslint:disable-next-line: no-use-before-declare this.writeToLog(msg, LogLevel.Fatal, optionalParams); } log(msg, ...optionalParams) { // tslint:disable-next-line: no-use-before-declare this.writeToLog(msg, LogLevel.All, optionalParams); } clear() { for (const logger of this.abstractAppenders) { logger.clear().subscribe((response) => console.log(response)); } } shouldLog(level) { let ret = false; if ( // tslint:disable-next-line: no-use-before-declare (level >= this.level && level !== LogLevel.Off) || // tslint:disable-next-line: no-use-before-declare this.level === LogLevel.All) { ret = true; } return ret; } writeToLog(msg, level, params) { if (this.shouldLog(level)) { // Declare variables // tslint:disable-next-line: no-use-before-declare const entry = new LogEntry(); // Build Log Entry entry.message = msg; entry.level = level; entry.extraInfo = params; entry.logWithDate = this.logWithDate; for (const logger of this.abstractAppenders) { logger.log(entry); // .subscribe(response => console.log(response)); } } } } /** @nocollapse */ Log4a.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Log4a, deps: [{ token: AppenderService }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ Log4a.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Log4a }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Log4a, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: AppenderService }, { type: i1.HttpClient }]; } }); var LogLevel; (function (LogLevel) { LogLevel[LogLevel["All"] = 0] = "All"; LogLevel[LogLevel["Debug"] = 1] = "Debug"; LogLevel[LogLevel["Info"] = 2] = "Info"; LogLevel[LogLevel["Warn"] = 3] = "Warn"; LogLevel[LogLevel["Error"] = 4] = "Error"; LogLevel[LogLevel["Fatal"] = 5] = "Fatal"; LogLevel[LogLevel["Off"] = 6] = "Off"; })(LogLevel || (LogLevel = {})); class LogEntry { constructor() { // Public Properties this.entryDate = new Date(); this.message = ''; this.level = LogLevel.Debug; this.extraInfo = []; this.logWithDate = true; } // ************** // Public Methods // ************** buildLogString() { let value = ''; if (this.logWithDate) { value = new Date() + ''; } // value += "Type: " + LogLevel[this.level]; value += ' - Message: ' + this.message; if (this.extraInfo.length) { value += ' - Extra Info: ' + this.formatParams(this.extraInfo); } switch (LogLevel[this.level]) { case 'Debug': // tslint:disable-next-line: no-console console.debug('%c Type: [' + LogLevel[this.level] + ']%c' + value, ' border-bottom-color: blue; background: blue; color: white; display: block; font-weight: bold;', 'background: white;border-bottom: 1px solid blue; font-weight: 900;color:blue'); break; case 'Info': // tslint:disable-next-line: no-console console.info('%c Type: [' + LogLevel[this.level] + ']%c' + value, ' border-bottom-color: blue; background: blue; color: white; display: block; font-weight: bold;', 'background: white;border-bottom:1px solid blue; font-weight: 900;color:blue'); break; case 'Warn': console.warn('%c Type: [' + LogLevel[this.level] + ']%c' + value, ' border-bottom-color: black; background: orange; color: white; display: block; font-weight: bold;', 'background: white;border-bottom: 1px solid orange; font-weight: 900; '); break; case 'Error': console.error('%c Type: [' + LogLevel[this.level] + ']%c' + value, ' border-bottom-color: white; background: red; color: white; display: block; font-weight: bold;', 'background: ;border-bottom: 1px solid red; font-weight: 900; color:red'); break; case 'Fatal': console.error('%c Type: [' + LogLevel[this.level] + ']%c' + value, ' border-bottom-color: white; background: red; color: white; display: block; font-weight: bold;', 'background: ;border-bottom: 1px solid red; font-weight: 900; color:red'); break; case 'All': // tslint:disable-next-line: no-console console.info('%c Type: [' + LogLevel[this.level] + ']%c' + value, ' border-bottom-color: blue; background: blue; color: white; display: block; font-weight: bold;', 'background: white;border-bottom: 1px solid blue; font-weight: 900;color:blue'); break; } // return value; } // *************** // Private Methods // *************** formatParams(params) { let ret = params.join(','); // Is there at least one object in the array? if (params.some(p => typeof p === 'object')) { ret = ''; // Build comma-delimited string for (const item of params) { ret += JSON.stringify(item) + ','; } } return ret; } } class LogConfigComponent { constructor(logger) { this.logger = logger; this.isChecked = true; } ngOnInit() { } enableLog() { this.isChecked = !this.isChecked; this.logger.level = this.isChecked ? LogLevel.All : LogLevel.Off; } enableDate() { this.logger.logWithDate = !this.logger.logWithDate; } setLogLevel(level) { switch (level) { case 'Debug': this.logger.level = (this.logger.level === LogLevel.Off) ? LogLevel.Off : LogLevel.Debug; break; case 'Info': this.logger.level = (this.logger.level === LogLevel.Off) ? LogLevel.Off : LogLevel.Info; break; case 'Warn': this.logger.level = (this.logger.level === LogLevel.Off) ? LogLevel.Off : LogLevel.Warn; break; case 'Error': this.logger.level = (this.logger.level === LogLevel.Off) ? LogLevel.Off : LogLevel.Error; break; default: this.logger.level = (this.logger.level === LogLevel.Off) ? LogLevel.Off : LogLevel.All; break; } } logmsg() { this.logger.debug('test'); } } /** @nocollapse */ LogConfigComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LogConfigComponent, deps: [{ token: Log4a }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ LogConfigComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: LogConfigComponent, selector: "log-config", ngImport: i0, template: "<form (ngSubmit) = \"false\">\n <h1>Enable/Disable Log :</h1>\n <label class=\"switch\">\n\n <input type=\"checkbox\" [checked]='isChecked' (click) = \"enableLog()\">\n <span class=\"slider round\" ></span>\n </label>\n\n <!-- Rounded switch -->\n <h1>Enable Date :</h1>\n <label class=\"switch\">\n\n <input type=\"checkbox\" checked (click) = \"enableDate()\">\n <span class=\"slider round\"></span>\n </label>\n\n\n<br>\n<br>\n<br>\n<fieldset >\n <legend>Log Level :</legend>\n\n <div>\n <input type=\"radio\" id=\"debug\" name=\"log\" value=\"Debug\" checked (change) = \"setLogLevel('Debug')\"/>\n <label for=\"debug\">Debug</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"info\" name=\"log\" value=\"Info\" (change) = \"setLogLevel('Info')\"/>\n <label for=\"info\">Info</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"warn\" name=\"log\" value=\"warn\" (change) = \"setLogLevel('Warn')\"/>\n <label for=\"warn\">Warn</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"error\" name=\"log\" value=\"Error\" (change) = \"setLogLevel('Error')\"/>\n <label for=\"error\">Error</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"all\" name=\"log\" value=\"All\" (change) = \"setLogLevel('All')\"/>\n <label for=\"all\">All</label>\n </div>\n</fieldset>\n\n\n<br>\n\n<input type=\"button\" (click) = \"logger.debug('test')\" value=\"Debug Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.info('test')\" value=\"Info Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.warn('test')\" value=\"Warn Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.error('test')\" value=\"Error Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.log('test')\" value=\"All Test\"/><br><br>\n\n\n\n", styles: [".switch{position:relative;display:inline-block;width:60px;height:34px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s}.slider:before{position:absolute;content:\"\";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#2196f3}input:focus+.slider{box-shadow:0 0 1px #2196f3}input:checked+.slider:before{transform:translate(26px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.btn{border:none;background-color:inherit;padding:14px 28px;font-size:16px;cursor:pointer;display:inline-block}.btn:hover{background:#eee}.success{color:green}.info{color:#1e90ff}.warning{color:orange}.danger{color:red}.default{color:#000}\n"] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LogConfigComponent, decorators: [{ type: Component, args: [{ selector: 'log-config', template: "<form (ngSubmit) = \"false\">\n <h1>Enable/Disable Log :</h1>\n <label class=\"switch\">\n\n <input type=\"checkbox\" [checked]='isChecked' (click) = \"enableLog()\">\n <span class=\"slider round\" ></span>\n </label>\n\n <!-- Rounded switch -->\n <h1>Enable Date :</h1>\n <label class=\"switch\">\n\n <input type=\"checkbox\" checked (click) = \"enableDate()\">\n <span class=\"slider round\"></span>\n </label>\n\n\n<br>\n<br>\n<br>\n<fieldset >\n <legend>Log Level :</legend>\n\n <div>\n <input type=\"radio\" id=\"debug\" name=\"log\" value=\"Debug\" checked (change) = \"setLogLevel('Debug')\"/>\n <label for=\"debug\">Debug</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"info\" name=\"log\" value=\"Info\" (change) = \"setLogLevel('Info')\"/>\n <label for=\"info\">Info</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"warn\" name=\"log\" value=\"warn\" (change) = \"setLogLevel('Warn')\"/>\n <label for=\"warn\">Warn</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"error\" name=\"log\" value=\"Error\" (change) = \"setLogLevel('Error')\"/>\n <label for=\"error\">Error</label>\n </div>\n\n <div>\n <input type=\"radio\" id=\"all\" name=\"log\" value=\"All\" (change) = \"setLogLevel('All')\"/>\n <label for=\"all\">All</label>\n </div>\n</fieldset>\n\n\n<br>\n\n<input type=\"button\" (click) = \"logger.debug('test')\" value=\"Debug Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.info('test')\" value=\"Info Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.warn('test')\" value=\"Warn Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.error('test')\" value=\"Error Test\"/><br><br>\n<input type=\"button\" (click) = \"logger.log('test')\" value=\"All Test\"/><br><br>\n\n\n\n", styles: [".switch{position:relative;display:inline-block;width:60px;height:34px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s}.slider:before{position:absolute;content:\"\";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#2196f3}input:focus+.slider{box-shadow:0 0 1px #2196f3}input:checked+.slider:before{transform:translate(26px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.btn{border:none;background-color:inherit;padding:14px 28px;font-size:16px;cursor:pointer;display:inline-block}.btn:hover{background:#eee}.success{color:green}.info{color:#1e90ff}.warning{color:orange}.danger{color:red}.default{color:#000}\n"] }] }], ctorParameters: function () { return [{ type: Log4a }]; } }); class Log4aModule { } /** @nocollapse */ Log4aModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Log4aModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); /** @nocollapse */ Log4aModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: Log4aModule, declarations: [LogConfigComponent], exports: [LogConfigComponent] }); /** @nocollapse */ Log4aModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Log4aModule }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Log4aModule, decorators: [{ type: NgModule, args: [{ declarations: [LogConfigComponent], imports: [], exports: [LogConfigComponent] }] }] }); /* * Public API Surface of log4a */ /** * Generated bundle index. Do not edit. */ export { AppenderService, ConsoleAppender, LocalStorageAppender, Log4a, Log4aModule, LogConfigComponent, LogEntry, LogLevel, WebApiAppender }; //# sourceMappingURL=ng-log-log4a.mjs.map