分享

Logging, which framework to choose? Log4J, Commons Logging, LogBack, SLF4J? | Log4Mike

 小胡子的是也 2016-01-06

Log-ging is part of every appli-ca-tion we cre-ate and most of the time we do not use java’s own Java Util Log-ging frame-work. Most devel-op-ers and archi-tects use Jakarta Com-mons Log-ging (JCL) in com-bi-na-tion with Log4J. But what about SLF4J instead of JCL? Although more and more frame-works are using it, a lot of devel-op-ers and archi-tects stick to Jakarta Com-mons Log-ging with Log4J, why is that?

Ok, lets first go through the actual log-ging frame-works. After that we can decide which facade we are going to use.

Log4J

Log4J has become the defacto stan-dard imple-men-ta-tion for log-ging, since it started of as a frame-work for log-ging since Java did not include a log-ging facil-ity itself.

It seems every devel-oper knows it and most projects and appli-ca-tion servers use it. So prob-a-bly I do not need to tell you about the log-ging lev-els TRACE, DEBUG, INFO, WARN and ERROR. The fact that you con-fig-ure the lay-out of the mes-sages con-tain-ing date and time, thread, class and method infor-ma-tion. The avail-abil-ity of file, data-base and e-mail appen-ders is also widely known and used. In short, this is the log-ging framework.

How-ever, Log4J is not actively main-tained any-more. It is widely spread and sta-ble accord-ing to the v1.2 web-site. Log4J was the pio-neer frame-work that intro-duced con-fig-urable log-ging. Intro-duc-tion of the log-ging level, the log-ger and the appen-ders, it’s all the guys that devel-oped Log4J who came up with that. But now it is stuck in its imple-men-ta-tion and no-one seems to be will-ing to cre-ate a new and improved v2.0.

Java Util Logging (JUL)

Java intro-duced its own log-ging frame-work to make log-ging more con-fig-urable then the pre-vi-ous usage of  System.out.println(), System.err.println() and e.printStackTrace() usage. How-ever instead of per-fect-ing the all-ready intro-duced Log4J frame-work, it intro-duced a sim-i-lar but not fin-ished API.

Java Util Log-ging is not very devel-oper  friendly. It con-tains just a very basic way of log-ging, a method called log where you always have to indi-cate the level. And those lev-els are not very clear for usage (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST).

So basi-cally, I would not choose this as my log-ging framework.

LogBack

Log-Back is kind of what should have been Log4J 2.0. It picks up where Log4J stopped. The cre-ator of Log4J also started the Log-Back project to cre-ate a new and improved version.

LogBack’s inter-nals are refac-tored to be faster, have a smaller mem-ory foot-print is bet-ter tested and has good doc-u-men-ta-tion. All improve-ments that we wel-come. Log-Back also imple-ments the SLF4J API natively and can eas-ily be used as a dropin replace-ment for Log4J (at least that is what they say, I will def-i-nitely need to try that).

Log-Back has some other cool new fea-tures, like the Siftin-gAp-pen-der, which is able to sep-a-rate your log-files on for instance a user ses-sion. It is also pos-si-ble to change the loglevel only for a cer-tain user, so you can trou-bleshoot a pro-duc-tion prob-lem with-out the log-file eat-ing up your lim-ited diskspace!

I/O failover is bet-ter, when-ever a file server fails tem-porar-ily, you do not need to restart your appli-ca-tion to start log-ging again.

The con-fig-u-ra-tion file is auto-mat-i-cally reloaded upon mod-i-fi-ca-tion, a nice fea-ture for appli-ca-tion servers and JEE appli-ca-tions. Another nice addon is the logback-access mod-ule for appli-ca-tion servers. This addon adds the abil-ity to see HTTP-access log-ging to your application.

There is also the logviewer Lilith, com-pa-ra-ble to Chain-saw for Log4J, but it can han-dle large log-files much better.

When log-ging it is a best prac-tice to check the level (when using com-mons log-ging and/or Log4J) using code sim-i-lar to this:

if( logger.isDebugEnabled() ) {
  logger.debug( "User with account " +
    user.getAccount() + " failed authentication; " +
    "supplied crypted password " + user.crypt(password) +
    " does not match." );
}

Within Log-Back it would be much sim-pler, more read-able and cleaner. The pre-vi-ous exam-ple would look like this:

logger.debug( "User with account {} failed authentication; " +
    "supplied crypted password {} does not match.",
    user.getAccount(), user.crypt(password) );

While writ-ing down all these fea-tures, I won-der why we are all still using Log4J. I will need to look into this frame-work soon!

Logging implementation choice

Basi-cally, Log4J is the defacto stan-dard and the default choice. I defi-nately want to take a look at Log-Back, but for now I would still go for the ‘safe’ choice Log4J.

Look-ing into the facade frame-works Jakarta Com-mons Log-ging and SLF4J, what should we use here?

Jakarta Commons Logging (JCL)

Jakarta Com-mons Log-ging cre-ates an API that hides the real log-ging frame-work. Since there are a lot of log-ging frame-works (Avalon LogKit, Log4J, JUL), Com-mons Log-ging tried to cre-ate an API so devel-op-ers could switch log-ging frame-work with-out recom-pil-ing the code.

It is widely spread. Frame-works like Spring also use it, although other frame-works like Hiber-nate have changed to SLF4J recently.

Com-mons Log-ging is not actively main-tained any-more, but is sta-ble. One very big down-side often encoun-tered is class loader issues in appli-ca-tion servers.

SLF4J

SLF4J is not a log-ging imple-me-na-tion, like Jakarta Com-mons Log-ging, it is just a facade to pro-vide log-ging func-tion-al-ity in an appli-ca-tion with-out to much has-sle with dependencies.

How-ever, SLF4J is a cleaner depen-dency and more effi-cient at run-time than commons-logging. One of the rea-sons is SLF4J uses compile-time bind-ings instead of run-time dis-cov-ery of the other log-ging frame-works it inte-grates. That means that you can-not switch log-ging imple-men-ta-tions at run-time (and who would want that?). You con-fig-ure which of the com-mon log-ging frame-works you want to use explicitely.

Another dif-fer-ence with Com-mons Log-gins is that it does not only pro-vide bind-ings to many com-mon log-ging frame-works, includ-ing JCL, it also does the reverse. SLF4J includes bridges between other log-ging frame-works and itself. OK, but what does that mean, well if you want to use SLF4J with for instance Spring which uses the commons-logging frame-work, you will need to replace the commons-logging depen-dency with the SLF4J-JCL bridge. Once you have done that then log-ging calls from within Spring will be trans-lated into log-ging calls to the SLF4J API, so if other libraries in your appli-ca-tion use that API, then you have a sin-gle place to con-fig-ure and man-age logging.

When bridg-ing from Spring to SLF4J, you could choose Log4J as the bind-ing, which would result in 4 depen-den-cies (and off course the exlu-sion of the commons-logging depen-dency of Spring): the bridge, theSLF4J API, the bind-ing to Log4J, and the Log4J imple-men-ta-tion itself. There-fore most peo-ple using SLF4J choose Log-Back instead of Log4J. That requires only the bridge jcl-over-slf4j and log-back (and exclude slf4j-api from depen-den-cies that include that!).

Conclusion

Dur-ing my research for this arti-cle I encoun-tered the Log-Back log-ging frame-work. I had heard of it, but just like any archi-tect, I used what I already knew. But hav-ing looked into it, I think it is defi-nately worth a shot to see what hap-pens when I encor-po-rate it into my appli-ca-tions. Will it work in appli-ca-tion servers like IBM Web-sphere and JBoss? Or does it only work on devel-op-ment con-tain-ers like Tom-cat and Jetty? How much con-flicts do I need to solve with Maven since a lot of depen-den-cies will use JCL and assume it is there? For now, I will leave it at that and assume we are still using good old Log4J as the imple-men-ta-tion frame-work and focus on the choice between Com-mons Log-ging and SLF4J.

Jakarta Com-mons Log-ging is widely spread, used by the very pop-u-lar Spring Frame-work and in recent release of appli-ca-tion servers it is shipped with the appli-ca-tion server. So the easy choice would be Jakarta Com-mons Logging.

Depend-ing on the time pres-sure and team com-po-si-tion I would prob-a-bly choose JCL first. Maybe it is the anx-i-ety for the unknown and unused, but in my expe-ri-ence the pos-si-ble deploy-ment issues could be a killer for a project when using ‘new’ tech-nol-ogy like SLF4J and LogBack.

When time is not as impor-tant, but per-for-mance is, I would defi-nately try to use SLF4J with Log-Back. Another rea-son to use SLF4J with Log-Back would be when there are cer-tain require-ments that can be met with the improved appenders.

Advan-tages SLF4J

  • No bloated code since we do not need the if(logger.isDebugEnabled()) line any-more to pre-vent sting con-cate-na-tion. (Note that other expen-sive calls made in the log state-ment might force us to put the if state-ment back!)
  • Para-me-ter-ized log-ging, eas-ily markup your log-ging mes-sage and pass the arguments.

Disadvantages SLF4J

  • Class-load-ing prob-lems when appli-ca-tion servers still use Log4J and ship com-mons log-ging and Log4J libraries in their own server lib direc-tory. Use reverse class load-ing (IBM calles it ‘par-ent last’) to let your appli-ca-tion deter-mine the log-ging framework.
  • Some maven plu-g-ins use commons-logging which then cause conflicts.
  • Need two libraries as depen-dency, one for bridg-ing to slf4j and one for the actual implementation.

No related posts.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多