code-chunks/angular2-logger

Can file name be appended to the log message?

Opened this issue · 13 comments

Is there any way to include the Component name along with the string being logged? For example if I'm logging "Function getMusicData() called" inside a Component called Music. I would want my logged message to look like "MusicComponent : Function getMusicData() called".

One way to do this could be declaring a constant string, "MusicComponent : " and appending this, each time I log something. This would be very hectic where there are 100s of lines to be logged and 100s of files.

This is more of a feature request rather than a issue. I'm quite new to angular2-logger. If this feature already exists, I might have missed it. Can anyone point me to the usage, if it already exists?

Thanks in advance.

Hello @sudhashri , I've been working on this. Its planned for the Appenders and Support named loggers of the TODOs. It's a bit tricky in Typescript/JS so I want to make sure it's decent enough before delivering it. I can't promess you yet it will be as specific to the point of method names, but it will definitely be possible with Component's names.

As for the method name, I think you can already see this if you print it as an error which will make the console show the stacktrace of the callers, would this be a good alternative ?

@langley-agm Thanks for the update. I'm more interested in Component name than Method name. I can wait till released. As you said, I can already see the method name in stacktrace.

👍

Otherwise you don't know where the log is coming from...

Strangely, if I use console.~~debug()~~error()... I get the full call stack (and where the log is coming from)

image

But when using angular2-logger, no such thing ? why ?
image

Isn't that screenshot from a console.error and not a console.debug ?

Yes your are right my bad :p
But still no call stack if using this.logger.error('...')

image

@francisoud That's the stacktrace right there.

This is from the demo included in the distributable:

image

I am curious to know how can we config the log message with component name and time. Any help?
Thanks!!

@prabalakers At the moment that functionality hasn't been implemented so you cannot achieve it only by configuration.

However, Typescript allows extending classes, so you can extend it or create a wrapper of the actual logger if you favor composition over inheritance and extend its functionality.

@langley-agm #60 (comment) finally found time to test it against a clean new angular 2.0.0 project, works like expected :)
I have the source (file and line number of origin stacktrace in case of logger.error() )
My issue was surely related to something I must have left in my code during an angular 2.0.0.rc3 to 2.0.0.rc5 version, sorry for the trouble.

no problem, glad it worked out @francisoud

Could this be a feasible solution to the issue:

currently the logger works like this: (= no prefix)

export class AppComponent(){
    constructor( private _logger: Logger ){
        this._logger.error('This is a priority level 1 error message...');
    }
}

However, if it would be possible to provide an injectable Logger constructor, then we could write something like this.

export class AppComponent(){
    constructor( private Logger: Logger) {
        this._logger = new Logger(' I prefix every log message');
        this._logger.error('This is a priority level 1 error message...');
    }
}

This would solve the prefixing log message requested.

Any pros or cons on this?

Hi @HNeukermans,

Thanks for taking interest on this.

About the approach you propose:

If you inject the constructor so the user creates the object themselves then it would no longer be Dependency Injection, it would be the opposite and it would not be any different than importing the class and do this._logger = new Logger(' I prefix every log message'); without the need of the injection part constructor( private Logger: Logger).

It could be implemented with something similar to this:

1- Through a Factory:

`this._logger = LoggerFactory.getLogger('com.test.component');

Requires a refactor and a change in syntax of the people who are already using it.
`
2- Through reflection

Not sure if that's the correct word in JS but there is a way to find out the method name of the caller so we can use it as the prefix without the user having to specify it, problem with this approach is that it would only work if the user indeed calls it from the constructor (so it prefixes it with the name of the component) otherwise it will take the name of the function where the user is doing it from. Also, you can run into an issue of duplicated Component names.

3- Hybrid, a mix of the previous two.

Only name it with the caller name if the user doesn't specifies the prefix themselves and highly warn the user about the side effects if they don't.

I wonder if the second approach can be done using Dependency Injection, and have angular tell you who is it injecting it to and use an angular factory instead of singleton, but they were changing too much so I decided to postpone this research and I haven't had time lately to go back to it.

Hi @langley-agm,

Through a factory:
If you would agree on doing it this way, one way to not confront the user with breaking api changes is to develop the 'factory' way of working, parallell to current DI way, and mark the DI way as deprecated, so your api user can gradually phase out to to the new standard.

Through reflection:
I'm also not sure it this is possible using the current reflect metadata library. Reflection apis and features are still to limited for this, I guess..