From 2f059cccdf950e305d8f8caa59577802a52b462f Mon Sep 17 00:00:00 2001
From: bmtheo <31310846+bmtheo@users.noreply.github.com>
Date: Sat, 13 Feb 2021 16:45:17 +0100
Subject: [PATCH 1/2] avoids fail on complex structure when logging
fix #177 by removing the prepareMessage (JSON.stringify) call when logging
The prepareMessage call is still needed for server logging thus complex structure don't working with server logging
---
projects/demo/src/app/app.component.html | 2 +-
projects/demo/src/app/app.component.ts | 7 +++++++
projects/demo/src/app/app.module.ts | 3 ++-
.../app/log-config/log-config.component.html | 1 +
.../app/log-config/log-config.component.scss | 4 ++++
.../app/log-config/log-config.component.ts | 7 +++++++
.../logger-form/logger-form.component.html | 1 +
.../app/logger-form/logger-form.component.ts | 16 ++++++++++++---
src/lib/logger.service.spec.ts | 20 +++++++++++++++++++
src/lib/logger.service.ts | 2 +-
10 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/projects/demo/src/app/app.component.html b/projects/demo/src/app/app.component.html
index 0b81d29..d23b0de 100644
--- a/projects/demo/src/app/app.component.html
+++ b/projects/demo/src/app/app.component.html
@@ -2,5 +2,5 @@
Please open your console to see the output of the demo
-
+
diff --git a/projects/demo/src/app/app.component.ts b/projects/demo/src/app/app.component.ts
index 9dbd548..a36f571 100644
--- a/projects/demo/src/app/app.component.ts
+++ b/projects/demo/src/app/app.component.ts
@@ -19,6 +19,7 @@ export class AppComponent {
handleLogLevelChange(newLevel: NgxLoggerLevel) {
const updatedConfig = this.logger.getConfigSnapshot();
updatedConfig.level = newLevel;
+ updatedConfig.serverLogLevel = newLevel;
this.logger.updateConfig(updatedConfig);
}
@@ -57,4 +58,10 @@ export class AppComponent {
updatedConfig.disableFileDetails = disableFileDetails;
this.logger.updateConfig(updatedConfig);
}
+
+ serverLogging(enabled: boolean) {
+ const updatedConfig = this.logger.getConfigSnapshot();
+ updatedConfig.serverLoggingUrl = enabled ? '/dummyURL' : null;
+ this.logger.updateConfig(updatedConfig);
+ }
}
diff --git a/projects/demo/src/app/app.module.ts b/projects/demo/src/app/app.module.ts
index 1651f65..7398920 100644
--- a/projects/demo/src/app/app.module.ts
+++ b/projects/demo/src/app/app.module.ts
@@ -13,7 +13,7 @@ import {
MatSlideToggleModule,
MatTooltipModule,
} from '@angular/material';
-import { LoggerModule, NgxLoggerLevel } from 'ngx-logger';
+import { LoggerModule, NGXLogger, NgxLoggerLevel } from 'ngx-logger';
import { AppComponent } from './app.component';
import { LogConfigComponent } from './log-config/log-config.component';
@@ -29,6 +29,7 @@ import { HttpClientModule } from '@angular/common/http';
ReactiveFormsModule,
LoggerModule.forRoot({
level: NgxLoggerLevel.DEBUG,
+ serverLogLevel: NgxLoggerLevel.DEBUG,
}),
MatButtonModule,
MatCardModule,
diff --git a/projects/demo/src/app/log-config/log-config.component.html b/projects/demo/src/app/log-config/log-config.component.html
index 5fc43fb..1604f86 100644
--- a/projects/demo/src/app/log-config/log-config.component.html
+++ b/projects/demo/src/app/log-config/log-config.component.html
@@ -33,6 +33,7 @@ Logger Configuration
Disable file details
+ Server logging
diff --git a/projects/demo/src/app/log-config/log-config.component.scss b/projects/demo/src/app/log-config/log-config.component.scss
index bbf91f8..fdd41ac 100644
--- a/projects/demo/src/app/log-config/log-config.component.scss
+++ b/projects/demo/src/app/log-config/log-config.component.scss
@@ -10,3 +10,7 @@ button {
display: flex;
justify-content: center;
}
+
+.server-logging {
+ margin-left: 16px;
+}
\ No newline at end of file
diff --git a/projects/demo/src/app/log-config/log-config.component.ts b/projects/demo/src/app/log-config/log-config.component.ts
index 053a0c0..27cd391 100644
--- a/projects/demo/src/app/log-config/log-config.component.ts
+++ b/projects/demo/src/app/log-config/log-config.component.ts
@@ -20,6 +20,9 @@ export class LogConfigComponent {
@Output()
disableFileDetails: EventEmitter = new EventEmitter();
+ @Output()
+ serverLogging: EventEmitter = new EventEmitter();
+
/**
* Get the chip color based on the current logger level configuration
*/
@@ -56,4 +59,8 @@ export class LogConfigComponent {
disableFileDetailsChange(change: MatSlideToggleChange) {
this.disableFileDetails.emit(change.checked);
}
+
+ serverLoggingChange(change: MatSlideToggleChange) {
+ this.serverLogging.emit(change.checked);
+ }
}
diff --git a/projects/demo/src/app/logger-form/logger-form.component.html b/projects/demo/src/app/logger-form/logger-form.component.html
index 2fad3fd..331b6eb 100644
--- a/projects/demo/src/app/logger-form/logger-form.component.html
+++ b/projects/demo/src/app/logger-form/logger-form.component.html
@@ -15,6 +15,7 @@
+
diff --git a/projects/demo/src/app/logger-form/logger-form.component.ts b/projects/demo/src/app/logger-form/logger-form.component.ts
index 8f21521..a47d288 100644
--- a/projects/demo/src/app/logger-form/logger-form.component.ts
+++ b/projects/demo/src/app/logger-form/logger-form.component.ts
@@ -1,6 +1,6 @@
import {Component, OnInit, Output, EventEmitter} from '@angular/core';
-import {Validators, FormBuilder} from '@angular/forms';
-import {NgxLoggerLevel} from 'ngx-logger';
+import {Validators, FormBuilder, FormGroup} from '@angular/forms';
+import {NGXLogger, NgxLoggerLevel} from 'ngx-logger';
import {LogEvent} from '../models/log-event.model';
@@ -36,7 +36,10 @@ export class LoggerFormComponent implements OnInit {
{value: NgxLoggerLevel.ERROR, viewValue: 'Error'}
];
- constructor(private fb: FormBuilder) {
+ constructor(
+ private fb: FormBuilder,
+ private logger: NGXLogger
+ ) {
}
ngOnInit() {
@@ -48,4 +51,11 @@ export class LoggerFormComponent implements OnInit {
handleFormSubmission() {
this.logToConsole.emit(this.loggerForm.value);
}
+
+ logComplex() {
+ const complexStructure = new FormGroup({ sub: new FormGroup({}) });
+ this.logger.error('Test complex', complexStructure);
+ this.logger.error(complexStructure);
+ }
+
}
diff --git a/src/lib/logger.service.spec.ts b/src/lib/logger.service.spec.ts
index c2a7894..be91b9d 100644
--- a/src/lib/logger.service.spec.ts
+++ b/src/lib/logger.service.spec.ts
@@ -7,6 +7,7 @@ import {NGXMapperService} from './mapper.service';
import {NGXMapperServiceMock} from '../../testing/src/lib/mapper.service.mock';
import {LoggerConfig} from './logger.config';
import {NgxLoggerLevel} from './types/logger-level.enum';
+import { FormGroup } from '@angular/forms';
describe('NGXLogger', () => {
beforeEach(() => {
@@ -42,6 +43,25 @@ describe('NGXLogger', () => {
}
));
+ it('should handle complex circular structures', inject(
+ [NGXLogger],
+ (logger: NGXLogger) => {
+ // This structure is not "stringifyable" this make sure anything can be logged
+ // Before that we used JSON.stringify and it was not working
+ const complexStructure = new FormGroup({ sub: new FormGroup({}) });
+
+ spyOn(console, 'error');
+
+ logger.error('error', complexStructure);
+
+ expect(console.error).toHaveBeenCalledWith(jasmine.anything(), jasmine.anything(), jasmine.anything(), complexStructure);
+
+ logger.error(complexStructure);
+
+ expect(console.error).toHaveBeenCalledWith(jasmine.anything(), jasmine.anything(), complexStructure);
+ }
+ ));
+
describe('trace', () => {
it('should call _log with trace', inject(
[NGXLogger],
diff --git a/src/lib/logger.service.ts b/src/lib/logger.service.ts
index f7ba70b..f9c0dad 100644
--- a/src/lib/logger.service.ts
+++ b/src/lib/logger.service.ts
@@ -167,7 +167,6 @@ export class NGXLogger {
const logLevelString = Levels[level];
message = typeof message === 'function' ? message() : message;
- message = NGXLoggerUtils.prepareMessage(message);
// only use validated parameters for HTTP requests
const validatedAdditionalParameters = NGXLoggerUtils.prepareAdditionalParameters(additional);
@@ -192,6 +191,7 @@ export class NGXLogger {
}
if (isLog2Server) {
+ message = NGXLoggerUtils.prepareMessage(message);
// make sure the stack gets sent to the server
message = message instanceof Error ? message.stack : message;
logObject.message = message;
From 989a9107d0c3013f4ebd9994be8c6050414afe88 Mon Sep 17 00:00:00 2001
From: bmtheo <31310846+bmtheo@users.noreply.github.com>
Date: Sat, 13 Feb 2021 18:05:00 +0100
Subject: [PATCH 2/2] fix behavior when manipulating message
respect NGXLogInterface with string type for message
do the same processing it used to have for server logging without altering the data for console logging
---
src/lib/logger.service.ts | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/lib/logger.service.ts b/src/lib/logger.service.ts
index f9c0dad..1d444da 100644
--- a/src/lib/logger.service.ts
+++ b/src/lib/logger.service.ts
@@ -178,7 +178,10 @@ export class NGXLogger {
// const callerDetails = NGXLoggerUtils.getCallerDetails();
this.mapperService.getCallerDetails(config.enableSourceMaps).subscribe((callerDetails: LogPosition) => {
const logObject: NGXLogInterface = {
- message: message,
+ // prepareMessage is needed to match NGXLogInterface
+ // Even though I think message should be of type any (same as console.xxx signature)
+ // I'm not doing this right now as this would be a breaking change
+ message: NGXLoggerUtils.prepareMessage(message),
additional: validatedAdditionalParameters,
level: level,
timestamp: timestamp,
@@ -191,10 +194,9 @@ export class NGXLogger {
}
if (isLog2Server) {
- message = NGXLoggerUtils.prepareMessage(message);
- // make sure the stack gets sent to the server
- message = message instanceof Error ? message.stack : message;
- logObject.message = message;
+ // make sure the stack gets sent to the server (without altering the message for console logging)
+ logObject.message = message instanceof Error ? message.stack : message;
+ logObject.message = NGXLoggerUtils.prepareMessage(logObject.message);
const headers = this._customHttpHeaders || new HttpHeaders();
headers.set('Content-Type', 'application/json');