Created
October 22, 2021 04:25
-
-
Save krishnathota/b56014d1fc0d855e7d0e7b603f8980e1 to your computer and use it in GitHub Desktop.
Logger service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Logs to console, can be extended to localstorage, webapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { InjectionToken, ModuleWithProviders, NgModule } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { LoggerService } from './services/logger.service'; | |
// move these to new files to avoid circular dependency issues | |
const ENVIRONMENT = new InjectionToken<Environment>('environment'); | |
export interface Environment { | |
production: boolean; | |
} | |
@NgModule({ | |
imports: [CommonModule] | |
}) | |
export class LoggerModule { | |
public static forRoot(environment: Environment): ModuleWithProviders<LoggerModule> { | |
return { | |
ngModule: CommonModule, | |
providers: [ | |
{ | |
provide: ENVIRONMENT, | |
useValue: environment | |
}, | |
LoggerService | |
] | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Inject, Injectable } from '@angular/core'; | |
import { fromEvent } from 'rxjs'; | |
import { filter, map } from 'rxjs/operators'; | |
import { TsUtilService } from 'mes-components/src/lib/util'; | |
import { Entry } from '../models/entry'; | |
import { Level } from '../models/level.enum'; | |
import { ConsoleService } from './publishers/console.service'; | |
import { LocalStorageService } from './publishers/local-storage.service'; | |
import { WebApiService } from './publishers/web-api.service'; | |
import { ENVIRONMENT } from '../environment.injector'; | |
import { Environment } from '../models/environment'; | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class LoggerService { | |
constructor( | |
@Inject(ENVIRONMENT) private environment: Environment, | |
private console: ConsoleService, | |
private localStorage: LocalStorageService, | |
private webApi: WebApiService, | |
private tsUtil: TsUtilService | |
) { | |
this.fetchLevel(); | |
} | |
private LOG_LEVEL = 'loglevel'; | |
private WEB_API_LOG_LEVEL = 'webapiloglevel'; | |
private API_LOG_LEVEL = 'apiloglevel'; | |
private level: Level = Level.ERROR; | |
private apiLevel: Level = Level.OFF; | |
private logWithDate = false; | |
log(msg: string, ...params: any[]) { | |
this.writeToLog(msg, Level.LOG, params); | |
} | |
debug(msg: string, ...params: any[]) { | |
this.writeToLog(msg, Level.DEBUG, params); | |
} | |
info(msg: string, ...params: any[]) { | |
this.writeToLog(msg, Level.INFO, params); | |
} | |
warn(msg: string, ...params: any[]) { | |
this.writeToLog(msg, Level.WARN, params); | |
} | |
error(msg: string, ...params: any[]) { | |
this.writeToLog(msg, Level.ERROR, params); | |
} | |
private shouldLog = (level: Level, targetLevel?: Level) => { | |
if (!targetLevel) targetLevel = this.level; | |
return (level >= targetLevel && level !== Level.OFF) || targetLevel === Level.LOG; | |
}; | |
private writeToLog(message: string, level: Level, params: any[]) { | |
const entry: Entry = { | |
message, | |
level, | |
params, | |
timeStamp: this.logWithDate ? new Date() : undefined | |
}; | |
let loggers = []; | |
if (this.shouldLog(level, this.level)) { | |
loggers = [this.console, this.localStorage]; | |
} | |
if (this.shouldLog(level, this.apiLevel)) { | |
loggers.push(this.webApi); | |
} | |
loggers.forEach((_) => _.log(entry)); | |
} | |
private fetchLevel() { | |
this.level = this.environment.production ? Level.ERROR : Level.LOG; | |
this.apiLevel = this.environment.production ? Level.ERROR : Level.OFF; | |
Object.entries(sessionStorage).forEach(([key, value]) => { | |
if ( | |
key.toLowerCase() === this.LOG_LEVEL || | |
key.toLowerCase() === this.API_LOG_LEVEL || | |
key.toLowerCase() === this.WEB_API_LOG_LEVEL | |
) | |
this.setLevel({ key: key.toLowerCase(), value }); | |
}); | |
fromEvent<StorageEvent>(window, 'storage') | |
.pipe( | |
filter((event) => event.storageArea === sessionStorage), | |
filter( | |
(event) => | |
event.key.toLowerCase() === this.LOG_LEVEL || | |
event.key.toLowerCase() === this.API_LOG_LEVEL || | |
event.key.toLowerCase() === this.WEB_API_LOG_LEVEL | |
), | |
map((event: any) => ({ key: event.key, value: event.newValue })) | |
) | |
.subscribe(this.setLevel.bind(this)); | |
} | |
private setLevel(level: { key; value }) { | |
const _level = this.tsUtil.enumKeys(Level).find((_) => _ === level?.value?.toUpperCase()); | |
level.key === this.LOG_LEVEL ? (this.level = Level[_level]) : (this.apiLevel = Level[_level]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable } from '@angular/core'; | |
import { Entry } from '../../models/entry'; | |
import { Level } from '../../models/level.enum'; | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class ConsoleService { | |
private colors = { | |
[Level.LOG]: { background: 'DarkGrey', color: 'Black' }, | |
[Level.DEBUG]: { background: 'Grey', color: 'White' }, | |
[Level.INFO]: { background: 'DodgerBlue', color: 'White' }, | |
[Level.WARN]: { background: 'Orange', color: 'White' }, | |
[Level.ERROR]: { background: 'Red', color: 'White' } | |
}; | |
constructor() {} | |
log(entry: Entry) { | |
// Append app name if needed | |
const { message, level, params, timeStamp } = entry; | |
const logger = | |
level === Level.ERROR | |
? console.error | |
: level === Level.WARN | |
? console.warn | |
: level === Level.INFO | |
? console.info | |
: console.log; | |
logger( | |
`%c ${Level[level]} `, | |
`background: ${this.colors[level].background}; color: ${this.colors[level].color}`, | |
timeStamp ? `${timeStamp} ${message}` : message, | |
...params | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment