dbfannin / ngx-logger

Angular logger
MIT License
428 stars 110 forks source link

How to update default config in production environment at run time #109

Closed ctaleck closed 4 years ago

ctaleck commented 5 years ago

Related issue #7 answers how to change the logging config at compile-time (using environment), but I wish to know how to change the global config at run-time.

The logger.updateConfig(config) method only changes them for the current instance.

I am trying to perform this update in an APP_INITIALIZER of the Angular bootstrap, but it grabs a new copy of the config provided in forRoot(config). I wondering if the service could have another way to update the default config which is always provided to the service when initialized:

    // each instance of the logger should have their own config engine
    this.configService = new NgxLoggerConfigEngine(loggerConfig);
dbfannin commented 5 years ago

@ctaleck, I'm trying to make sure I'm understanding your use case.

Does that sum it up?

ctaleck commented 5 years ago

@dbfannin A bit of clarification on each point:

It seems that every time I invoke the logger service, I get a new set of config settings which was provided by the forRoot(config), and then the updateConfig(config) can be used to override that. However, I want to override the forRoot(config) settings at run time so that every new instance uses the new run time settings.

To give some context on the user story for this, I would like to be able to change the logging level for each new environment for continuous deployment without re-compiling. Only the app settings file would need to change. I hope this helps.

dbfannin commented 5 years ago

@ctaleck, Thanks for the clarification. I definitely see the benefit of doing the runtime configuration using an APP_INITIALIZER. I'm not sure of the urgency of this, because it has not been requested by anyone else. If you would like to take a stab at it, I'd be happy to look at a PR. If it doesn't introduce breaking changes, and all the changes look good, I'll be happy to get that change in for you.

If it does introduce breaking changes, I think we would need to get more backing from the community before we introduced this change.

Thanks!

bradoyler commented 5 years ago

So one workaround might be to read the logLevel from localStorage and then you can update the value in the browser console at runtime. This is how the nodejs debug module works.

example app.module.ts

....
const localLogLevel = localStorage.getItem('logLevel');
const defaultLogLevel = NgxLoggerLevel.INFO;
const logLevel = localLogLevel ? NgxLoggerLevel[localLogLevel] || defaultLogLevel : defaultLogLevel;
....
imports: [
  LoggerModule.forRoot({ level: logLevel })
]
ctaleck commented 5 years ago

How would you get the initial settings into localStorage before the Angular app initializes?

bradoyler commented 5 years ago

@ctaleck I don't do that. I just use localStorage.setItem() to override the existing defaultLogLevel at runtime.

tomanovy commented 4 years ago

I found this solution, it's working (only not on Stackblitz, don't know why it's not able to http.get those json files): https://stackoverflow.com/questions/54668780/how-to-configure-logger-level-for-ngx-logger-in-global-config-file/#answer-55048067 but I cannot figure out how to set it up with APP_Initializer...I'm stuck in this situation: https://ngx-logger-config.stackblitz.io... Could you guys help me?

bmtheo commented 4 years ago

@dbfannin this would also be useful in our app

The user story is a bit different : We need to change the logLevel at runtime (by default in PROD mode it's set to ERROR) but if we need to investigate on an issue, we'd like to modify that logLevel to DEBUG or TRACE for example.

So the updateConfig should update all "living" instances of NGXLogger AND the future instances.

Are you open to PR for this ? and if so I was thinking of doing something like this :

export class NGXLogger implements OnDestroy {
  private static readonly _sharedConfig: Subject<LoggerConfig> = new Subject<LoggerConfig>();
  /** Returns an observable when the sharedConfig is changed */
  public sharedConfigChanged(): Observable<LoggerConfig> {
    return NGXLogger._sharedConfig.asObservable();
  }

  /** Updates the config for all the instances of NGXLogger */
  public updateSharedConfig(config: LoggerConfig) {
    NGXLogger._sharedConfig.next(config);
  }

...

  // each instance of the logger should have their own config engine
  this.config = new NGXLoggerConfigEngine(loggerConfig, this.sharedConfigChanged());
qortex commented 4 years ago

Duplicate of #184

Closing this issue, which will be tracked in #184