• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to get rid of boilerplate for logger

 
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A few days ago, while I was chasing a bug in the code using the log files, I was tripped by one particular message in the log file. The message suggested that it came from a particular class. I went to that class but couldn't find that message. Then I looked for it in the class I suspected it should have come from and found it there.

The reason for wrong class name in the log file was very simple. The message was generated by a statement such as logger.info("message"); But the wrong class name was passed while creating of the logger itself. i.e.

static Logger logger = Logger.getLogger(SomeOtherClass.class.getName());

This was probably a copy paste error. Someone copied the code from another class and forgot to change the name of the logger.

I see this pattern of creating the logger object everywhere and was wondering if there is better way to get access to a logger that would generate the right message?


 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Use an instance variable instead of a static variable. Then your boilerplate looks like this:


 
Paul Anilprem
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:Use an instance variable instead of a static variable. Then your boilerplate looks like this:




This won't work because getClass() is an instance method and logger has to be static because it will be used in static methods of the class as well.

Besides, I am looking to get rid of this line entirely if possible. If I have to add this line in every class that I write, I am thinking, there's got to be a better way to do this.
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I believe this is the sort of "cross-cutting concern" that AOP (Aspect-Oriented Programming) is meant to deal with.
 
Paul Anilprem
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Bear Bibeault wrote:I believe this is the sort of "cross-cutting concern" that AOP (Aspect-Oriented Programming) is meant to deal with.



Yes, I think that is a good idea. But that will only print start and end messages before and after the method call. But usually, we use a logger to print info and debug messages that will aid in debugging issues. So I guess, we do need some method call that is as handy as System.out.print(), yet, doesn't require writing any repetitive boilerplate code.

One solution that I saw was to call a static utility method Logger.log("message") and in that method generate stack trace to get the actual class and method name and append it to the message. I think that is exactly what I would want (usage wise) except that it is too expensive to generate stack trace every time you want to log a message.
 
Paul Anilprem
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I just realized how the aspect approach might be as helpful. The start of method message can tell you about the class the subsequent message are coming from.
But if there are some classes that are not covered by the aspect then that may cause confusion. If you have a global aspect that applies to each and every method, I am not sure how that will impact performance.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm sure it's far too late for me to say this, but it isn't a requirement of log4j that you use the class name for the name of the logger. That's only useful if you're going to configure log4j so that logs from different classes are written to different appenders -- maybe you are doing that, or maybe not. People just tend to use the class name there because the log4j documentation did that (to demonstrate how multiple loggers work and so on) but it isn't necessary.
 
Paul Anilprem
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:I'm sure it's far too late for me to say this, but it isn't a requirement of log4j that you use the class name for the name of the logger. That's only useful if you're going to configure log4j so that logs from different classes are written to different appenders -- maybe you are doing that, or maybe not. People just tend to use the class name there because the log4j documentation did that (to demonstrate how multiple loggers work and so on) but it isn't necessary.


May be I am missing something in the log4j API, but can you tell me how can you append the source of the message (i.e. the class name) if you don't create the logger with the name?

thank you,
Paul.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Anilprem wrote:May be I am missing something in the log4j API, but can you tell me how can you append the source of the message (i.e. the class name) if you don't create the logger with the name?



Well, do you want to output the class name or the logger name? As I said, they don't have to be the same. The documentation of PatternLayout (here) just says that you can use %C to get the name of the class which issued the logging request. It doesn't say anything about the logger name having to be the same as the class name.

I've always used specific logger names in my code for the appenders to key off of.
 
Paul Anilprem
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Paul Anilprem wrote:May be I am missing something in the log4j API, but can you tell me how can you append the source of the message (i.e. the class name) if you don't create the logger with the name?



Well, do you want to output the class name or the logger name? As I said, they don't have to be the same. The documentation of PatternLayout (here) just says that you can use %C to get the name of the class which issued the logging request. It doesn't say anything about the logger name having to be the same as the class name.

I've always used specific logger names in my code for the appenders to key off of.


Thanks but I think %C is as slow as trying to get the class name from the stack trace, that is why people tend to use the class name as the logger name.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, people use the class name as the logger name because they haven't ever seen any other method of assigning logger names. That's my opinion anyway. And your other comment is just premature optimization. That's not only my opinion but that of a lot of other people.
 
Paul Anilprem
Enthuware Software Support
Posts: 4803
52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:No, people use the class name as the logger name because they haven't ever seen any other method of assigning logger names. That's my opinion anyway. And your other comment is just premature optimization. That's not only my opinion but that of a lot of other people.



Description of %C from the link you mentioned:


WARNING Generating the caller class information is slow. Thus, use should be avoided unless execution speed is not an issue.


 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When I have logging enabled, it's because I'm debugging. It doesn't matter how slow it is.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Anilprem wrote:Description of %C from the link you mentioned:


WARNING Generating the caller class information is slow. Thus, use should be avoided unless execution speed is not an issue.




That was written approximately 10 years ago. Things written that long ago about Java performance are basically meaningless today.
 
reply
    Bookmark Topic Watch Topic
  • New Topic