Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/line numbers #56

Merged
merged 2 commits into from
Apr 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-logger",
"version": "2.1.1",
"version": "2.2.0",
"scripts": {
"build": "gulp build",
"build:watch": "gulp",
Expand Down
8 changes: 8 additions & 0 deletions src/http-meta-data.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {NgxLoggerLevel} from './types/logger-lever.enum';

export class HttpMetaDataInterface {
level: NgxLoggerLevel;
timestamp: string;
fileName: string;
lineNumber: string;
}
9 changes: 6 additions & 3 deletions src/http.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {HttpMetaDataInterface} from './http-meta-data.interface';


@Injectable()
Expand All @@ -9,12 +10,14 @@ export class NGXLoggerHttpService {

}

logOnServer(url: string, message: string, additional: any[], timestamp: string, logLevel: string): Observable<any> {
logOnServer(url: string, message: string, additional: any[], metaData: HttpMetaDataInterface): Observable<any> {
const body = {
level: logLevel,
message: message,
additional: additional,
timestamp: timestamp
level: metaData.level,
timestamp: metaData.timestamp,
fileName: metaData.fileName,
lineNumber: metaData.lineNumber
};

const options = {
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import {NGXLoggerHttpService} from './http.service';
export * from './http.service';
export * from './http.service.mock';

export * from './utils/logger.utils';
export * from './types/logger-lever.enum';
export * from './http-meta-data.interface';

@NgModule({
imports: [
Expand Down
90 changes: 25 additions & 65 deletions src/logger.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {NGXLoggerHttpService} from './http.service';
import {NgxLoggerLevel} from './types/logger-lever.enum';
import {LoggerConfig} from './logger.config';
import {NGXLoggerConfigEngine} from './config.engine';
import {HttpMetaDataInterface} from './http-meta-data.interface';
import {NGXLoggerUtils} from './utils/logger.utils';

export const Levels = [
'TRACE',
Expand Down Expand Up @@ -60,79 +62,54 @@ export class NGXLogger {
this.configService.updateConfig(config);
}

private _logIE(level: NgxLoggerLevel, message: string, additional: any[], timestamp: string): void {
private _logIE(level: NgxLoggerLevel, metaString: string, message: string, additional: any[]): void {

// make sure additional isn't null or undefined so that ...additional doesn't error
additional = additional || [];

switch (level) {
case NgxLoggerLevel.WARN:
console.warn(`${timestamp} [${Levels[level]}] `, message, ...additional);
console.warn(`${metaString} `, message, ...additional);
break;
case NgxLoggerLevel.ERROR:
console.error(`${timestamp} [${Levels[level]}] `, message, ...additional);
console.error(`${metaString} `, message, ...additional);
break;
case NgxLoggerLevel.INFO:
console.info(`${timestamp} [${Levels[level]}] `, message, ...additional);
console.info(`${metaString} `, message, ...additional);
break;
default:
console.log(`${timestamp} [${Levels[level]}] `, message, ...additional);
console.log(`${metaString} `, message, ...additional);
}
}

private _prepareMessage(message) {
try {
if (message instanceof Error) {
message = message.stack;
} else if (typeof message !== 'string') {
message = JSON.stringify(message, null, 2);
}
} catch (e) {
// additional = [message, ...additional];
message = 'The provided "message" value could not be parsed with JSON.stringify().';
}

return message;
}

private _prepareAdditionalParameters(additional: any[]) {
if (additional === null || additional === undefined) {
return null;
}

return additional.map((next, idx) => {
try {
// We just want to make sure the JSON can be parsed, we do not want to actually change the type
if (typeof next === 'object') {
JSON.stringify(next)
}

return next;
}
catch (e) {
return `The additional[${idx}] value could not be parsed using JSON.stringify().`
}
});
}

private _log(level: NgxLoggerLevel, message, additional: any[] = [], logOnServer: boolean = true): void {
if (!message) {
return;
}

const logLevelString = Levels[level];

message = this._prepareMessage(message);
message = NGXLoggerUtils.prepareMessage(message);

// only use validated parameters for HTTP requests
const validatedAdditionalParameters = this._prepareAdditionalParameters(additional);
const validatedAdditionalParameters = NGXLoggerUtils.prepareAdditionalParameters(additional);

const timestamp = new Date().toISOString();
const config = this.configService.getConfig();

const callerDetails = NGXLoggerUtils.getCallerDetails();

if (logOnServer && config.serverLoggingUrl && level >= config.serverLogLevel) {

const metaData: HttpMetaDataInterface = {
level: level,
timestamp: timestamp,
fileName: callerDetails.fileName,
lineNumber: callerDetails.lineNumber,
};

// Allow logging on server even if client log level is off
this.httpService.logOnServer(config.serverLoggingUrl, message, validatedAdditionalParameters, timestamp, logLevelString).subscribe((res: any) => {
this.httpService.logOnServer(config.serverLoggingUrl, message, validatedAdditionalParameters, metaData).subscribe((res: any) => {
// I don't think we should do anything on success
},
(error: HttpErrorResponse) => {
Expand All @@ -147,32 +124,15 @@ export class NGXLogger {
return;
}

const metaString = NGXLoggerUtils.prepareMetaString(timestamp, logLevelString, callerDetails.fileName, callerDetails.lineNumber);

// Coloring doesn't work in IE
if (this._isIE) {
return this._logIE(level, message, additional, timestamp);
return this._logIE(level, metaString, message, additional);
}

const color = this._getColor(level);

console.log(`%c${timestamp} [${logLevelString}]`, `color:${color}`, message, ...(additional || []));
}
const color = NGXLoggerUtils.getColor(level);

private _getColor(level: NgxLoggerLevel): 'blue' | 'teal' | 'gray' | 'red' | undefined {
switch (level) {
case NgxLoggerLevel.TRACE:
return 'blue';
case NgxLoggerLevel.DEBUG:
return 'teal';
case NgxLoggerLevel.INFO:
case NgxLoggerLevel.LOG:
return 'gray';
case NgxLoggerLevel.WARN:
case NgxLoggerLevel.ERROR:
return 'red';
case NgxLoggerLevel.OFF:
default:
return;
}
console.log(`%c${metaString}`, `color:${color}`, message, ...(additional || []));
}

}
2 changes: 1 addition & 1 deletion src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-logger",
"version": "2.1.1",
"version": "2.2.0",
"repository": {
"type": "git",
"url": "https://github.com/dbfannin/ngx-logger"
Expand Down
85 changes: 85 additions & 0 deletions src/utils/logger.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {NgxLoggerLevel} from '../types/logger-lever.enum';

export class NGXLoggerUtils {

static prepareMetaString(timestamp: string, logLevel: string, fileName: string, lineNumber: string) {
return `${timestamp} ${logLevel} [${fileName}:${lineNumber}]`;
}

static getColor(level: NgxLoggerLevel): 'blue' | 'teal' | 'gray' | 'red' | undefined {
switch (level) {
case NgxLoggerLevel.TRACE:
return 'blue';
case NgxLoggerLevel.DEBUG:
return 'teal';
case NgxLoggerLevel.INFO:
case NgxLoggerLevel.LOG:
return 'gray';
case NgxLoggerLevel.WARN:
case NgxLoggerLevel.ERROR:
return 'red';
case NgxLoggerLevel.OFF:
default:
return;
}
}



/**
* This allows us to see who called the logger
* @return {string}
* @private
*/
static getCallerDetails(): {lineNumber: string, fileName: string} {
const err = (new Error(''));

// this should produce the line which NGX Logger was called
const callerLine = err.stack.split('\n')[4].split('/');

// returns the file:lineNumber
const fileLineNumber = callerLine[callerLine.length - 1].replace(/[)]/g, '').split(':');

return {
fileName: fileLineNumber[0],
lineNumber: fileLineNumber[1]
}
}

static prepareMessage(message) {
try {
if (message instanceof Error) {
message = message.stack;
} else if (typeof message !== 'string') {
message = JSON.stringify(message, null, 2);
}
} catch (e) {
// additional = [message, ...additional];
message = 'The provided "message" value could not be parsed with JSON.stringify().';
}

return message;
}

static prepareAdditionalParameters(additional: any[]) {
if (additional === null || additional === undefined) {
return null;
}

return additional.map((next, idx) => {
try {
// We just want to make sure the JSON can be parsed, we do not want to actually change the type
if (typeof next === 'object') {
JSON.stringify(next)
}

return next;
}
catch (e) {
return `The additional[${idx}] value could not be parsed using JSON.stringify().`
}
});
}


}