SLF4J: Now you can do logging in Java... oh wait!

Discussions

News: SLF4J: Now you can do logging in Java... oh wait!

  1. Dion Almaer has posted "SLF4J: Now you can do logging in Java... oh wait!," mentioning Tapestry's retreat from commons-logging and migration to SLF4J, Ceki Gulcu's next-generation logging proxy. It's humorous in its way: when will SLF4J's successor show up?
    Howard is saying so long, commons-logging, hello SLF4J. I had to giggle a little bit here. When commons-logging came along to abstract your logger which abstracts your println (I know.... you CAN write an appender that sends you SMS messages and launches rockets) I thought "wow". Only the J2EE community would architect twelve levels of abstraction to handle a filtered logging system. After years of use we realise that the last level of abstraction doesn't do anything for you... but instead of just ignoring it, we have a new one!
    The non-Apache follow on to commons-logging is SLF4J. It does things right: Logger, not Log. Better yet, Logger is an interface (it's a class in Log4J) which makes my EasyMock-addled brain quite happy. Finally, SLF4J takes a very simple, very sane approach: you combine the API JAR with one of several implementation JARs. That's it ... no class loader magic, no dynamic binding. This is an ideal solution for those same 99.99999% of applications out there.
    Maybe someone could write an abstraction layer on top of commoons-logging and SLF4J.... you know, so you could switch between then without changing the interface.
    The scary thing is that ... gosh, I recall working around commons-logging's use in WebSphere not long ago, and JBoss' use of fairly common libraries can cause issues - all things that can be worked around, but one wonders sometimes that if the workarounds (the logging library proxies) need workarounds (classloader magic), maybe there should be an easier way... Like, perhaps, just using java.util.logging itself, since every VM since 1.4 has it?

    Threaded Messages (37)

  2. java.util.logging[ Go to top ]

    We continue to make this hard. I have just started saying no to all these loggers and use java.util.logging. It works just fine for me.
  3. Re: java.util.logging[ Go to top ]

    We continue to make this hard. I have just started saying no to all these loggers and use java.util.logging. It works just fine for me.
    +1. I'd like to see JBoss projects move to java.util.logging as well, but its hard due to backward compatibility reasons. -- Bill Burke JBoss, a division of Red hat http://bill.burkecentral.com
  4. Re: java.util.logging[ Go to top ]

    +1 again... I understand the need that Log4J fulfilled, back before java.util.logging - but they both do the same thing and these days I'd rather not have to drag along libraries that really aren't needed. Then there's the fact that it's in the JVM and you don't have to worry about different ClassLoaders stomping on files.
  5. Re: java.util.logging[ Go to top ]

    +1 - Have not seen a sensible reason to use anything else since 1.4
  6. JDK 1.4 logging is flawed[ Go to top ]

    - I disagree completely. JDK 1.4 logging: terrible. Poorly designed. Very confusing. Look at how Tomcat had to extend this system with non-standard JULI extensions to make it usable. Try and write a standard config file to do something simple like log different namespaces to different files (nearly impossible). log4j: Simple, well designed, easy to use, feature complete, but unfortunately it's a third party lib and not part of the JDK. I would much prefer to use the standard JDK option, but in this case, that option is simply terrible. In hindsight, I wish they did JDK 1.4 logging correctly and we could all use the same library without all this complexity and confusion. However, that didn't happen.
  7. Re: JDK 1.4 logging is flawed[ Go to top ]

    I wouldn't go quite that far, but I *do* think java.util.logging threw out some extraordinarily important concepts from log4j. First and foremost, log4j uses log(Object), not log(String). This does 2 important things. First, it allows you to convert your object to a String only if/when you're actually going to log it as such. Yes, I know you can add an additional if-enabled check on the logger first, prior to the conversion, but this should not be required when passing just a single object. Second, it prevents you from communicating anything more structured or meaningful than a string to custom appenders, renderers, filters, etc. This is a huge gap in j.u.l. We have specialized classes that hold key/value pairs and formatting options that can do elaborate message formatting when a string is needed or can simply be used by a custom appender to write each pair's value to a database column corresponding to the key. This sort of thing is simply not possible with j.u.l due to this fundamental design flaw. log4j is incredibly powerful, yet simple and easy to use, and has numerous great extensions. Unfortunately, it seems to be floundering as of late. The synchronization therein is too course and can become a real bottleneck in cases. This is a recognized issue, but there is a lack of strong leadership and/or consensus on how to address such critical issues while breaking as little existing log4j code as possible. Meanwhile, Ceki Gulcu's goes off and creates yet another logging framework with zero compatibility. I don't get it.
  8. Re: JDK 1.4 logging is flawed[ Go to top ]

    log4j is incredibly powerful, yet simple and easy to use, and has numerous great extensions. Unfortunately, it seems to be foundering as of late. The synchronization therein is too coarse and can become a real bottleneck in cases. This is a recognized issue, but there is a lack of strong leadership and/or consensus on how to address such critical issues while breaking as little existing log4j code as possible.
    One could argue that by creating java.util.logging, Sun took some of the wind out of Jog4J's sails.
  9. Re: JDK 1.4 logging is flawed[ Go to top ]

    First and foremost, log4j uses log(Object), not log(String). This does 2 important things.

    First, it allows you to convert your object to a String only if/when you're actually going to log it as such. Yes, I know you can add an additional if-enabled check on the logger first, prior to the conversion, but this should not be required when passing just a single object.

    Second, it prevents you from communicating anything more structured or meaningful than a string to custom appenders, renderers, filters, etc. This is a huge gap in j.u.l.
    Nope. You're just looking at the simple API of Logger, but that's not the heart of the system. The heart of the system is LogRecord, which is basically a String and a Object Array and some miscellaneous properties. You can pump anything you want in to the logging system and the Formatters can do whatever they like with that information. It's trivial to add a wrapper over j.u.l to give your app the sugar it wants to work with. In fact, today, it's pretty much required since j.u.l came out with JDK 1.4 before varargs. I have a wrapper that does just this: log.debug("Debug message {0}, {1}, {2}", arg1, arg2, arg3); Notable is a) j.u.l doesn't HAVE a "debug" level, b) this uses varargs, and c) no nasty Obj->String conversions happen if "debug" is disabled, so no IF wrappings here, I pay the price of the method hit, but that's it. I happen to run it through MessageFormatter myself rather than relying on a j.u.l.Formatter to do it, but I could have easily just populated a LogRecord and written a Formatter for it. Now, log4j DOES have some nice extra Handlers and what not, there's a lot of value add there, and it's more readily configured than the stock j.u.l configuration file. But the core of j.u.l is sound, flexible, and easy to use.
  10. Hurrah for smarter programmers![ Go to top ]

    I have a wrapper that does just this:

    log.debug("Debug message {0}, {1}, {2}", arg1, arg2, arg3);

    Notable is a) j.u.l doesn't HAVE a "debug" level, b) this uses varargs, and c) no nasty Obj->String conversions happen if "debug" is disabled, so no IF wrappings here, I pay the price of the method hit, but that's it. I happen to run it through MessageFormatter myself rather than relying on a j.u.l.Formatter to do it, but I could have easily just populated a LogRecord and written a Formatter for it.
    I like your approach A LOT, but stuck with commons-logging (aka clogging in Hani-speak).
  11. Re: Hurrah for smarter programmers![ Go to top ]

    I had been a very happy customer with common-logging for years until dealing with WebSphere. I have been using SLF4j since Websphere 5, it served me fairly well. java.util.logging is just plain dumb implementation. It is not good enough to convince me not to use third party logging yet, especially we are moving very slow on migrating to newer version WebSphere 6.1.
  12. I have a wrapper that does just this:

    log.debug("Debug message {0}, {1}, {2}", arg1, arg2, arg3);

    Completely agree. I think that one of the problems is that many frameworks haven't been able to bite the bullet and drop support for Java 1.4 and below. With varargs and enums you can do some very nice stuff. You can define an Enum for you message keys public enum ErrorMessageKey { FILE_NOT_FOUND( “Cannot find file {0}”), ... In your logging mechanism pass the enum and varargs public void info(ErrorMessageKey msg, Object… arg); Then using the logging mechanism is type safe, concise, and most importantly, very readable logger.info(ErrorMessageKey.CANNOT_READ_FILE, “file.txt”); I've gone in to more detail here http://www.theserverlabs.com/blog/?p=8 Paul Parsons CTO The Server Labs http://www.theserverlabs.com
  13. Re: JDK 1.4 logging is flawed[ Go to top ]

    First and foremost, log4j uses log(Object), not log(String). This does 2 important things.

    First, it allows you to convert your object to a String only if/when you're actually going to log it as such. Yes, I know you can add an additional if-enabled check on the logger first, prior to the conversion, but this should not be required when passing just a single object.

    Second, it prevents you from communicating anything more structured or meaningful than a string to custom appenders, renderers, filters, etc. This is a huge gap in j.u.l.


    Nope.

    You're just looking at the simple API of Logger, but that's not the heart of the system.

    The heart of the system is LogRecord, which is basically a String and a Object Array and some miscellaneous properties.

    You can pump anything you want in to the logging system and the Formatters can do whatever they like with that information.

    It's trivial to add a wrapper over j.u.l to give your app the sugar it wants to work with. In fact, today, it's pretty much required since j.u.l came out with JDK 1.4 before varargs.

    I have a wrapper that does just this:

    log.debug("Debug message {0}, {1}, {2}", arg1, arg2, arg3);

    Notable is a) j.u.l doesn't HAVE a "debug" level, b) this uses varargs, and c) no nasty Obj->String conversions happen if "debug" is disabled, so no IF wrappings here, I pay the price of the method hit, but that's it. I happen to run it through MessageFormatter myself rather than relying on a j.u.l.Formatter to do it, but I could have easily just populated a LogRecord and written a Formatter for it.

    Now, log4j DOES have some nice extra Handlers and what not, there's a lot of value add there, and it's more readily configured than the stock j.u.l configuration file. But the core of j.u.l is sound, flexible, and easy to use.
    Okay, so there's a way to do what I want -- cool. That said, having to pass a string *and* additional stuff as var args to get this isn't really an improvement!
  14. I understand everyone's apprehension about making a simple things like logging complicated. But, being able to have email's sent, errors saved in a RDBMS for statistics queries are very nice capabilities to have. I don't see anything in java.util.logging to help with that, and setting up logback takes about 15 - 30 mintues and you have nicely formatted log messages with great context hints like IP addresses and tomcat contexts for a particular client. IMO slf4j provides a nice api that lets you switch logging frameworks if you wanted, say if you were using logback and wanted the ability to use chainsaw in the future (chainsaw uses log4j xml logging format). (http://logging.apache.org/log4j/docs/chainsaw.html) Food for thought, Kevin Schmidt
  15. Re: java.util.logging[ Go to top ]

    -1 I say just use the de-facto standard java logger, log4j, and be done with it. Commons logging was never a good idea and was never needed, and the JCP folks should have just incorporated Log4J into Java wholesale instead of spinning a watered down version of it.
  16. I really don't like j.u.l[ Go to top ]

    I've had to j.u.l a time or two and it has always been painful. Want to change the log location? Change this file in $JAVA_HOME. Don't want to do that? Write this custom FileHandler (?) class. Of course, maybe I just don't know it well enough and all the above is complete nonsense, but I've never had the type of experience with it that makes me want to stick with it and find out. To be honest, I don't see why a facade is even needed. Just use log4j like a good boy -- assuming you can figure out off their AWFUL documentation -- and be done with it. :P
  17. java.util.logging sucks but not quite badly enough to justify dragging in a 3rd party library.
  18. Yea, j.u.l is hardly perfect. We added our own layer on top of it. And it's config file is nowhere near as flexible as log4j. But, we haven't cared enough to create a better configuration loader. I do need to tweak the commons-logging code. We have some packages that use commons-logging, and when you tie them in to using j.u.l, it turns out it converts DEBUG in to INFO, which is a bit "too high" for my tastes. Someday I'll tweak that as well. But, j.u.l has one advantage. It may be the Loweset Common Denominator of logging, but it IS the LCD of logging. And the more that (inevitably) routes through it, the easier it is to get one stop shopping configuration. I would like to see j.u.l better adopted, even by 3rd party libs (where commons-logging prevails), and then have the 3rd parties tweak the j.u.l configuration for value add, as j.u.l is pretty much an open book as far as implementation and pluggability is concerned, and it IS "everywhere" and "free". So, rather than adding extra channels and formatters and loaders and what not to 3rd Party Logging, write some modules to add or config j.u.l for that. Finally, for us, Glassfish uses j.u.l, so by us using j.u.l we get "free" value add from the container, including being able to tweak logging levels from the CLI or GUI on the "for free". We had to write that functionality for our last app that ran log4j. That helped tip it for us too.
  19. java.util.logging sucks but not quite badly enough to justify dragging in a 3rd party library.
    Yes because dragging in a 3rd party library is *SO* difficult.
  20. java.util.logging sucks but not quite badly enough to justify dragging in a 3rd party library.


    Yes because dragging in a 3rd party library is *SO* difficult.
    Especially one that's less than 100K once it's Pack200 compressed (which is how any recent remote client would get it and who cares about a jar of log4j.jar's size on the server). Now if you're in the Java ME space, *then* I understand.
  21. java.util.logging should never have been created. It's a real shame that Sun caught NIH syndrome and did that.
  22. I hate all of the standard loggers. Years ago, before open source took off we wrote our own logger and it had all sorts of features missing from the de facto standard loggers of today. Ones that come to mind. 1. Transactional awareness. You could configure different logging thresholds that came into play depending on whether a transaction committed or was rolled back. This allowed you to get around the problem of a production system running too slow with debug on, just turn on debug for transactions that are rolling back. I'm not aware of anything like this in log4j, jdk logger, etc. 2. Additional classifications beyond info/debug/warning/error, etc. These where a mask of attributes which I think where things like DATABASE NETWORK APPLICATION SECURITY APPSERVER etc. This allowed you to classify logging, so you could say, turn SECURITY logging to debug, while leaving the rest of the app at info or warn. I realize that it is only a convention to use a class's name to qualify the logging namespace, but it is really a bad one. A single class could log info relevant to a few of the above channels and unless you heavily deviate from the standard convention this isn't easy. btw, I'm not endorsing home brewed loggers its just that there doesn't seem to be all that much innovation going on here.
  23. Additional classifications beyond info/debug/warning/error, etc.

    These where a mask of attributes which I think where things like
    DATABASE
    NETWORK
    APPLICATION
    SECURITY
    APPSERVER
    etc.

    This allowed you to classify logging, so you could say, turn SECURITY logging to debug, while leaving the rest of the app at info or warn.
    Yea, but you can do that now with the logging namespaces. The logger name is a orthogonal to the logging level. You don't HAVE to use the Class name as your logger name, that's just common practice. You could also extend the loggers to add meta data to the logger name. The shipped loggers may not do that, but they (at least j.u.l can) be extended to transparently add that functionality (transparent to the logging client that is, the code with "log.debug(...)" in it). About the only thing really hard coded in to j.u.l is the levels themselves. The values are pretty well set, but you can render them however you want.
  24. Yea, but you can do that now with the logging namespaces. The logger name is a orthogonal to the logging level. You don't HAVE to use the Class name as your logger name, that's just common practice. You could also extend the loggers to add meta data to the logger name. The shipped loggers may not do that, but they (at least j.u.l can) be extended to transparently add that functionality (transparent to the logging client that is, the code with "log.debug(...)" in it).

    About the only thing really hard coded in to j.u.l is the levels themselves. The values are pretty well set, but you can render them however you want.
    Right, I think I clearly mentioned this in my post. I think the point is when there's a well known convention and you deviate from it, it's a constant battle to communicate and get everyone to follow it. So I'd rather have this as a first class feature, not some home grown inner platform.
  25. Transactional awareness => Dynamic Runtime/Request Diagnostics Image Dumps For contextual dumps in the event of errors, exceptions or aborted operations it would be much better to use a runtime diagnostics API and not a logger that could export on demand images of global, thread and stack diagnostic frames that included important runtime object state (not simple flattened string). Here are some related blog entries on my approach to NOT logging. JXInsight Diagnostics Open API http://blog.jinspired.com/?p=35 Introducing JXInsight Diagnostics http://blog.jinspired.com/?p=34 Component State in Diagnostics Global Frame http://blog.jinspired.com/?p=44 (Dynamic) Diagnostics Tags http://blog.jinspired.com/?p=52 JXInsight 5.5 and AspectJ - Sample Application http://blog.jinspired.com/?p=132 It would be great to see a similar API standardized and added to the Java runtime. We are finishing up work on Annotations for declarative marking of diagnostics frames (methods) and diagnostics variables (fields, parameters) which would simplify things even further both for the developer and problem management end user. regards, William Louth JXInsight Product Architect CTO, JINSPIRED "Java performance monitoring and problem management for Java EE, SOA, and Grid Computing" http://www.jinspired.com
  26. I hate all of the standard loggers.

    Years ago, before open source took off we wrote our own logger and it had all sorts of features missing from the de facto standard loggers of today. Ones that come to mind.

    1. Transactional awareness. You could configure different logging thresholds that came into play depending on whether a transaction committed or was rolled back.

    This allowed you to get around the problem of a production system running too slow with debug on, just turn on debug for transactions that are rolling back. I'm not aware of anything like this in log4j, jdk logger, etc.
    I'm not aware of any standard representation of a transaction across all Java applications and libraries. I don't know how you would expect Log4J to support this 'out-of-the-box'. I don't see any reason why you couldn't implement this as an extension to Log4J.
    2. Additional classifications beyond info/debug/warning/error, etc.

    These where a mask of attributes which I think where things like
    DATABASE
    NETWORK
    APPLICATION
    SECURITY
    APPSERVER
    etc.

    This allowed you to classify logging, so you could say, turn SECURITY logging to debug, while leaving the rest of the app at info or warn.

    I realize that it is only a convention to use a class's name to qualify the logging namespace, but it is really a bad one. A single class could log info relevant to a few of the above channels and unless you heavily deviate from the standard convention this isn't easy.
    I kind of wonder why one class would need to log about the network and the database but I won't question that here. There may be an easy way to do this with the existing configuration tools but I don't know of any. You could accomplish this by using a custom appender and by creating separate loggers for each type you want to separate. You don't need to stray from the conventions at all. For example if you have a class com.foo.Bar you could create two loggers: Logger DATABASE = Logger.getLogger(com.foo.Bar + '.' + "DATABASE"); // helper class would be a nice touch Logger NETWORK = Logger.getLogger(com.foo.Bar + '.' + "NETWORK"); With the above you not only get what you are looking for but you still can turn on all debugging for com.foo.Bar in a standard configuration with one line. The custom appender would allow you to turn on all loggers that end with DATABASE, or some subset of classes DATABASE loggers, for example. I've used this technique to create separate loggers for each instance of a class.
    btw, I'm not endorsing home brewed loggers its just that there doesn't seem to be all that much innovation going on here.
    Log4J is really quite extensible. You can still roll your own and not have to reinvent what has been implemented already in Log4J. And if what you come up with is good enough, you could contribute and allow others to gain from what you have done.
  27. I'm not aware of any standard representation of a transaction across all Java applications and libraries.
    We just tied in in as a transaction resource and let JTA handle it.
    You don't need to stray from the conventions at all. For example if you have a class com.foo.Bar you could create two loggers:

    Logger DATABASE = Logger.getLogger(com.foo.Bar + '.' + "DATABASE"); // helper class would be a nice touch
    Logger NETWORK = Logger.getLogger(com.foo.Bar + '.' + "NETWORK");


    With the above you not only get what you are looking for but you still can turn on all debugging for com.foo.Bar in a standard configuration with one line.

    The custom appender would allow you to turn on all loggers that end with DATABASE, or some subset of classes DATABASE loggers, for example.

    I've used this technique to create separate loggers for each instance of a class.

    Sure, this would cover most cases. I guess where I felt the loss of ability was say if a SQL statement was be used to authenticate someone I might want to do something like logger.debug(SECURITY | DATABASE, sql ); This way the statement would show up if I turned up debugging on either security or database. That's why I referred to it as a mask. With your approach I'd have to have duplicate debug statements to send them to different loggers. But that's the difference between first class support and theoretical support. I'm sure I could come up with some approach to get similar stuff, my point was more I'd like to see these as first class concepts.
  28. I'm not aware of any standard representation of a transaction across all Java applications and libraries.


    We just tied in in as a transaction resource and let JTA handle it.
    Wouldn't this then be something that JTA should address? I feel like I'm missing something.
    Sure, this would cover most cases. I guess where I felt the loss of ability was say if a SQL statement was be used to authenticate someone I might want to do something like

    logger.debug(SECURITY | DATABASE, sql );

    This way the statement would show up if I turned up debugging on either security or database. That's why I referred to it as a mask.

    With your approach I'd have to have duplicate debug statements to send them to different loggers. But that's the difference between first class support and theoretical support. I'm sure I could come up with some approach to get similar stuff, my point was more I'd like to see these as first class concepts.
    I think these are great ideas, I just don't see why you couldn't implement them on top of Log4J. You said you were able to do this in a hand-rolled logger, or at least some of these things. Is there something about how Log4J is designed that prevents you from doing this? I used to come up with ideas and ask why no one had implemented them. I finally decided that I would start doing so. I haven't changed the world but I do see people downloading my open source library. As another poster mentioned above, Log4J could use some improvements. On your idea of the mask, I would prefer something like: logger.debug("my message", database, security); Where database and security are objects implementing a specific interface. These would go at the end only so that varargs could be used.
  29. I think these are great ideas, I just don't see why you couldn't implement them on top of Log4J.
    I've actually thought several times of defining a wrapper over log4j with these sorts of features, more of an extension since so much of log4j works and works well. Mostly it would be standardizing how the class based name spacing could be extended to include these masks similar to what you described. Then I could post my new logger on TSS for all the world to see. But I'd be afraid people would takeover the thread to talk about their ideas on logging and how silly it was I tried to innovate in this space. :-p Speaking of which, did anyone look at the logger this post is about and could they summarize the innovative features? The only ones I got from the original post is that it uses interfaces and calls it Logger instead of Log. Other than possibly getting James Watson to practice TDD I don't see this as a compelling innovation.
  30. Then I could post my new logger on TSS for all the world to see.

    But I'd be afraid people would takeover the thread to talk about their ideas on logging and how silly it was I tried to innovate in this space.
    I'm not sure that this is the place to try and disseminate code. It's more of a place to advertise it. If you seriously wanted to add it to Log4J, the Log4J project and community would be where you would do that. You could also host it yourself as an extension or put it on SourceForge or wherever you want. As far as people thinking you are silly for try to innovate, who cares? Unless you act like you are king s*** of f*** mountain, most people won't give you a hard time for trying. People might say 'so and so' already did that. And even if people think your idea is not good, so what? One of my physics profs once told me, "have the courage or your convictions."
    Speaking of which, did anyone look at the logger this post is about and could they summarize the innovative features? The only ones I got from the original post is that it uses interfaces and calls it Logger instead of Log.
    Personally I think the whole problem it is trying to solve is an imaginary/theoretical one. I don't see much value in building an abstraction over the logging framework. I'd like to see one person explain how doing this has been worth it.
    Other than possibly getting James Watson to practice TDD I don't see this as a compelling innovation.
    I don't really see the connection to TDD.
  31. I don't see much value in building an abstraction over the logging framework. I'd like to see one person explain how doing this has been worth it.
    Application sugar, portability, and itch scratching, Like my "log.debug" above, or the "log.debug(SECURITY | DATABASE, ...)", those are both abstractions (or can be) on top of the core logging system. Those are the primary reasons, and there's certainly value. Commons-logging is really designed for library authors, it just seems redundant that all these libraries come with both commons-logging and log4j. SL4J is simply Yet Another portability layer, combined with Yet Another Logger. My argument is simply the j.u.l is a utilitarian, but feature complete logger that is easily extensible. I think there's value in folks writing better back ends for it (Handlers, Filters, LogManagers) as well as front ends for it (like my log.debug, or layering on the SECURITY | DATABASE style selectors). But the core framework is there and capable, and as long as your code is fundamentally using LogRecords and Loggers from LogManagers, which is all the stock j.u.l code does, and which is not an arduous requirement, then your code will work. So, j.u.l could easily be the "commons-logging" of Java.
  32. I don't see much value in building an abstraction over the logging framework. I'd like to see one person explain how doing this has been worth it.


    Application sugar, portability, and itch scratching,

    Like my "log.debug" above, or the "log.debug(SECURITY | DATABASE, ...)", those are both abstractions (or can be) on top of the core logging system.

    Those are the primary reasons, and there's certainly value.
    Sorry, I wasn't clear. I see the value in a custom abstraction to implement special logic. What I don't see much value in is using a logging framework that is built merely to allow you to choose between other logging frameworks.
    Commons-logging is really designed for library authors, it just seems redundant that all these libraries come with both commons-logging and log4j.
    Good point about library authors. I guess I can see where that's useful.
    SL4J is simply Yet Another portability layer, combined with Yet Another Logger.

    My argument is simply the j.u.l is a utilitarian, but feature complete logger that is easily extensible. I think there's value in folks writing better back ends for it (Handlers, Filters, LogManagers) as well as front ends for it (like my log.debug, or layering on the SECURITY | DATABASE style selectors). But the core framework is there and capable, and as long as your code is fundamentally using LogRecords and Loggers from LogManagers, which is all the stock j.u.l code does, and which is not an arduous requirement, then your code will work.

    So, j.u.l could easily be the "commons-logging" of Java.
    I don't have any particular problem with j.u.l but it's just not as capable as Log4J AFAICT. I doesn't make a lot of sense to me that Log4J, the defacto logging standard at the time j.u.l was created wasn't used as the basis for j.u.l.
  33. Naive Implementation[ Go to top ]

    public class LoggingMask { private static final String maskIdentifier = ":MASK:"; protected static boolean prependerOrAppender = true; /* false is appender */ protected HashMap masks = new HashMap(); public void LoggingMask() {} public void LoggingMask(boolean prependerOrAppender) { this.prependerOrAppender = prependerOrAppender; } public void LoggingMask(HashMap masks) { for (Iterator i = masks.keySet().iterator(); i.hasNext(); ) { Object key = i.next(); Object value = masks.get(key); this.mask.add(key, value); } public void setPrepender(boolean onOrOff) { this.prependerOrAppender = onOrOff; } public void setAppender(boolean onOrOff) { this.prependerOrAppender = onOrOff; } public String addMask(Object) { if (this.prependerOrAppender == true) { ... aw, nuts, I'm bored. You get the general idea. What I'm getting at is just add the string "DATABASE or SECURITY" into your debug message and grep for the damn word and then view your logger results. I'm going to go override default string behavior in Ruby to do this and an SMS implementation as we as a "fortune" log level where random quips are added to the log file.
  34. SLFJ+LogBack[ Go to top ]

    1. LogBack is the library Gulcu replaced Log4j with -- not SLFJ. SLFJ is just a wrapper. 2. I think you all should actually look into what SLFJ combined with the LogBack implementation provides you before being so trite with your "why not just use j.u.l?" overly simplistic answers. 3. There are actually people using j.u.l? yikes, you have no taste whatsoever in good software. You're probably also the type of people who use Eclipse because it's just good enough, right?
  35. Log4J was there well before j.u.l, it is well engineered, well documented, well accepted and supported by the community, used in a vast number of projects and it has no known deficiencies. j.u.l has been a bad and disappointing surprise for a huge number of us. j.u.l is just a carbon-copy of log4j and like every carbon-copy the quality is lower. j.u.l output is too much verbose and because it prints in two lines (by default), you never know if line n pertains to line n-1 or line n+1 => unreadable. J.u.l default output is System.err; under eclipse this is printed in red in the console: a very aggressive color and this makes it hard to distinguish exception stacktrace that also prints in System.err. The addition of j.u.l into the jdk is like the Microsoft practices that consist of including all kind of [bad] products into the core just to cut out competition. I’m not saying that they [sun] had that intention at the time, just that the net effect is the same: years ago this debate would never have taken place, because log4j completely fulfilled the needs and there was no need for j.u.l. IMHO, j.u.l should never have seen the light [of sun], Sun should have worked with the creator of Log4J, the Apache people and the community to give birth and incorporate into the core an API (vs an implementation) for which Log4j would have been a reference implementation. This would have given us something resembling slf4j years ago. IMHO again, j.u.l, because it is entangled in the core, will never evolve (or very slowly), while log4j and now logback will continue to provides more and more features, conveniences and performances, etc. Today, with SLF4J and Logback, the very own existence of j.u.l is questionable again. Zartc
  36. Log4J was there well before j.u.l, it is well engineered, well documented, well accepted and supported by the community, used in a vast number of projects and it has no known deficiencies.
    I just listed a couple of deficiencies. I'd agree it's well bedded and I'm not aware of any bugs. On a whole I don't mind it, but your glowing review seems a little over the top. If I'm asked I'd just shrug and say it's not as good as loggers I've used in the past, but since I'm not in the business of writing loggers it's good enough.
  37. java.util.loggin == log4j--[ Go to top ]

    The travesty of j.u.l was that there were opportunities to do things IN THE LANGUAGE to help logging. Traditionally I need to do things like: if (log.debugon()) log.debug("sdfljl" + vara + "sdfjlkasd"); In order to bypass the expensive string concatenation, that if statement is necessary to do the check. It would have been nice for Sun to provide some features that would alleviate things like this, and maybe make it easier to toggle the display of log statements for code readability. Or they could have provided features that you have to use aspectJ for (at least practically), such as automatic logging of method calls, param values, etc. No, instead they gave us log4j--
  38. 10 tips on logging in java[ Go to top ]

    This is just a great post indeed quite useful logging tips in java. In my opinion using correct logging level for different message is most important thing to learn and logging has important performance impact (ever found process running in DEBUG mode in production ) and has to be handled efficiently. I have also blogged my tips as 10 tips on logging in Java  , let me know how do you find it.