爲什麼不使用java.util.logging? - Why not use java.util.logging?

問題:

For the first time in my life I find myself in a position where I'm writing a Java API that will be open sourced.我有生以來第一次發現自己正在寫一個將開源的Java API。 Hopefully to be included in many other projects.希望將其包含在許多其他項目中。

For logging I (and indeed the people I work with) have always used JUL (java.util.logging) and never had any issues with it.對於日誌記錄,我(實際上是與我一起工作的人)一直使用JUL(java.util.logging),並且從未遇到過任何問題。 However now I need to understand in more detail what I should do for my API development.但是,現在我需要更詳細地瞭解我應該爲API開發做什麼。 I've done some research on this and with the information I've got I just get more confused.我對此進行了一些研究,並根據所獲得的信息感到更加困惑。 Hence this post.因此,這個職位。

Since I come from JUL I'm biased on that.由於我來自七月,所以我對此有偏見。 My knowledge of the rest is not that big.我對其餘的知識並不多。

From the research I've done I've come up with these reasons why people do not like JUL:從我所做的研究中,我得出了人們不喜歡JUL的這些原因:

  1. "I started developing in Java long before Sun released JUL and it was just easier for me to continue with logging-framework-X rather than to learn something new" . “我很早在Sun發佈JUL之前就開始用Java進行開發,對於我而言,繼續使用logging-framework-X而不是學習新知識只是一件容易的事。” Hmm.唔。 I'm not kidding, this is actually what people say.我不是在開玩笑,這實際上是人們所說的。 With this argument we could all be doing COBOL.有了這個論點,我們所有人都可能在做COBOL。 (however I can certainly relate to this being a lazy dude myself) (不過我當然可以認爲自己是個懶惰的傢伙)

  2. "I don't like the names of the logging levels in JUL" . “我不喜歡JUL中的日誌記錄級別的名稱” Ok, seriously, this is just not enough of a reason to introduce a new dependency.好的,很嚴重,這還不足以引入新的依賴關係。

  3. "I don't like the standard format of the output from JUL" . “我不喜歡JUL輸出的標準格式” Hmm.唔。 This is just configuration.這只是配置。 You do not even have to do anything code-wise.您甚至不必執行任何代碼明智的事情。 (true, back in old days you may have had to create your own Formatter class to get it right). (是的,在過去,您可能必須創建自己的Formatter類才能正確使用它)。

  4. "I use other libraries that also use logging-framework-X so I thought it easier just to use that one" . “我使用了其他也使用logging-framework-X的庫,因此我認爲僅使用該庫就更容易了” This is a circular argument, isn't ?這是一個循環的論證,不是嗎? Why does 'everybody' use logging-framework-X and not JUL?爲什麼“每個人”都使用logging-framework-X而不使用JUL?

  5. "Everybody else is using logging-framework-X" . “其他人都在使用logging-framework-X” This to me is just a special case of the above.對我來說,這只是上述情況的特例。 Majority is not always right.多數並不總是正確的。

So the real big question is why not JUL?因此,真正的大問題是爲什麼不選擇JUL? . What is it I have missed ?我錯過了什麼? The raison d'être for logging facades (SLF4J, JCL) is that multiple logging implementations have existed historically and the reason for that really goes back to the era before JUL as I see it.記錄正面(SLF4J,JCL)的理由是,歷史上已經存在多種記錄實現,其原因確實可以追溯到我看到的JUL之前的時代。 If JUL was perfect then logging facades wouldn't exist, or what?如果JUL是完美的,那麼將不存在伐木外觀,還是什麼? To make matters more confusing JUL is to some extent a facade itself, allowing Handlers, Formatters and even the LogManager to be swapped.讓事情變得更加混亂的是,JUL在某種程度上是一種外觀,它允許交換Handlers,Formatters甚至LogManager。

Rather than embracing multiple ways of doing the same thing (logging), shouldn't we question why they were necessary in the first place?而不是採用多種方法來做同一件事(記錄),我們是否應該首先質疑爲什麼必須這樣做? (and see if those reasons still exist) (並查看這些原因是否仍然存在)

Ok, my research so far has led to a couple of things that I can see may be real issues with JUL:好的,到目前爲止,我的研究已經發現了幾件可能是JUL真正問題的事情:

  1. Performance .表現 Some say that performance in SLF4J is superior to the rest.有人說SLF4J的性能優於其他產品。 This seems to me to be a case of premature optimization.在我看來,這似乎是過早優化的一種情況。 If you need to log hundreds of megabytes per second then I'm not sure you are on the right path anyway.如果您需要每秒記錄數百兆字節,那麼我不確定您是否走在正確的道路上。 JUL has also evolved and the tests you did on Java 1.4 may no longer be true. JUL也已經發展,您在Java 1.4上進行的測試可能不再正確。 You can read about it here and this fix has made it into Java 7. Many also talk about the overhead of string concatenation in logging methods.您可以在此處閱讀有關此內容的信息,此修復程序已將其納入Java7。許多人還談到了日誌記錄方法中字符串連接的開銷。 However template based logging avoids this cost and it exist also in JUL.但是,基於模板的日誌記錄避免了這種開銷,並且它在JUL中也存在。 Personally I never really write template based logging.我個人從來沒有真正寫過基於模板的日誌記錄。 Too lazy for that.太懶了。 For example if I do this with JUL:例如,如果我使用JUL進行此操作:

    log.finest("Lookup request from username=" + username + ", valueX=" + valueX + ", valueY=" + valueY));

    my IDE will warn me and ask permission that it should change it to:我的IDE會警告我,並請求允許將其更改爲:

    log.log(Level.FINEST, "Lookup request from username={0}, valueX={1}, valueY={2}", new Object[]{username, valueX, valueY});

    .. which I will of course accept. ..我當然會接受。 Permission granted !許可授予 ! Thank you for your help.感謝您的幫助。

    So I don't actually write such statements myself, that is done by the IDE.因此,我實際上並不親自編寫此類語句,而是由IDE完成的。

    In conclusion on the issue of performance I haven't found anything that would suggest that JUL's performance is not ok compared to the competition.總之,在性能問題上,我沒有發現任何暗示JUL的性能與競爭對手相比不佳的信息。

  2. Configuration from classpath .從classpath配置 Out-of-the-box JUL cannot load a configuration file from the classpath.開箱即用的JUL無法從類路徑加載配置文件。 It is a few lines of code to make it do so.這樣做需要幾行代碼 I can see why this may be annoying but the solution is short and simple.我可以理解爲什麼這可能很煩人,但是解決方案又短又簡單。

  3. Availability of output handlers .輸出處理程序的可用性 JUL comes with 5 output handlers out-of-the-box: console, file stream, socket and memory. JUL帶有5個開箱即用的輸出處理程序:控制檯,文件流,套接字和內存。 These can be extended or new ones can be written.這些可以擴展,也可以編寫新的。 This may for example be writing to UNIX/Linux Syslog and Windows Event Log.例如,這可能正在寫入UNIX / Linux Syslog和Windows事件日誌。 I have personally never had this requirement nor have I seen it used but I can certainly relate to why it may be a useful feature.我個人從來沒有這個要求,也沒有看到它使用過,但是我可以肯定地解釋爲什麼它可能是一個有用的功能。 Logback comes with an appender for Syslog for example.例如,Logback附帶了Syslog的附加程序。 Still I would argue that我仍然會爭辯說

    1. 99.5% of the needs for output destinations are covered by what is in JUL out-of-the-box.開箱即用的JUL可以滿足99.5%的輸出目的地需求。
    2. Special needs could be catered for by custom handlers on top of JUL rather than on top of something else.定製處理程序可以在JUL之上而不是其他之上滿足特殊需求。 There's nothing to me that suggests that it takes more time to write a Syslog output handler for JUL than it does for another logging framework.在我看來,沒有什麼比爲其他日誌記錄框架花費更多的時間來爲JUL編寫Syslog輸出處理程序了。

I'm really concerned that there's something I've overlooked.我真的很擔心我忽略了某些事情。 The use of logging facades and logging implementations other than JUL is so widespread that I have to come to the conclusion that it's me who just doesn't understand.除了JUL之外,對日誌外觀和日誌實現的使用是如此廣泛,以至於我不得不得出結論,就是我自己不瞭解。 That wouldn't be the first time, I'm afraid.恐怕這不是第一次。 :-) :-)

So what should I do with my API?那麼我應該如何處理我的API? I want it to become successful.我希望它能夠成功。 I can of course just "go with the flow" and implement SLF4J (which seems the most popular these days) but for my own sake I still need to understand exactly what is wrong with the JUL of today that warrants all the fuzz?我當然可以“順其自然”並實現SLF4J(這是當今最流行的),但是出於我自己的考慮,我仍然需要確切地瞭解今天的JUL到底有什麼毛病? Will I sabotage myself by choosing JUL for my library ?我會爲我的圖書館選擇JUL來破壞自己嗎?

Testing performance測試性能

(section added by nolan600 on 07-JUL-2012) (部分由nolan600在2012年7月7日添加)

There's a reference below from Ceki about SLF4J's parametrization being 10 times or more faster than JUL's.以下來自Ceki的參考資料表明SLF4J的參數化速度比JUL的速度快10倍或更多。 So I've started doing some simple tests.所以我已經開始做一些簡單的測試。 At first glance the claim is certainly correct.乍一看,這一主張當然是正確的。 Here are the preliminary results (but read on!):這是初步結果(但請繼續閱讀!):

  • Execution time SLF4J, backend Logback: 1515執行時間SLF4J,後端登錄:1515
  • Execution time SLF4J, backend JUL: 12938執行時間SLF4J,後端JUL:12938
  • Execution time JUL: 16911執行時間JUL:16911

The numbers above are msecs so less is better.上面的數字是毫秒,所以越少越好。 So 10 times performance difference is by first actually pretty close.所以實際上十倍的性能差異實際上是非常接近的。 My initial reaction: That is a lot !我最初的反應:很多!

Here is the core of the test.這是測試的核心。 As can be seen an integer and a string is construted in a loop which is then used in the log statement:可以看出,整數和字符串在循環中構造,然後在log語句中使用該循環:

    for (int i = 0; i < noOfExecutions; i++) {
        for (char x=32; x<88; x++) {
            String someString = Character.toString(x);
            // here we log 
        }
    }

(I wanted the log statement to have both a primitive data type (in this case an int) and a more complex data type (in this case a String). Not sure it matters but there you have it.) (我希望log語句同時具有原始數據類型(在這種情況下爲int)和更復雜的數據類型(在這種情況下爲String)。不確定是否重要,但是有。)

The log statement for SLF4J: SLF4J的日誌語句:

logger.info("Logging {} and {} ", i, someString);

The log statement for JUL: JUL的日誌語句:

logger.log(Level.INFO, "Logging {0} and {1}", new Object[]{i, someString});

The JVM was 'warmed up' with the same test executed once before the actual measurement was done.在完成實際測量之前,對JVM進行了“熱身”,並執行了一次相同的測試。 Java 1.7.03 was used on Windows 7. Latest versions of SLF4J (v1.6.6) and Logback (v1.0.6) was used. Windows 7使用Java 1.7.03。使用了最新版本的SLF4J(v1.6.6)和Logback(v1.0.6)。 Stdout and stderr was redirected to null device. Stdout和stderr被重定向到空設備。

However, careful now, it turns out JUL is spending most of its time in getSourceClassName() because JUL by default prints the source class name in the output, while Logback doesn't.但是,現在要小心,事實證明JUL大部分時間都花在getSourceClassName()因爲默認情況下,JUL在輸出中輸出源類名稱,而Logback則不輸出。 So we are comparing apples and oranges.因此,我們正在比較蘋果和橙子。 I have to do the test again and configure the logging implementations in a similar manner so that they actually output the same stuff.我必須再次進行測試,並以類似的方式配置日誌記錄實現,以便它們實際上輸出相同的內容。 I do however suspect that SLF4J+Logback will still come out on top but far from the initial numbers as given above.但是,我確實懷疑SLF4J + Logback仍將排在首位,但與上面給出的初始數字相去甚遠。 Stay tuned.敬請關注。

Btw: The test was first time I've actually worked with SLF4J or Logback.順便說一句:該測試是我第一次真正使用SLF4J或Logback。 A pleasant experience.令人愉快的經歷。 JUL is certainly a lot less welcoming when you are starting out.剛開始時,JUL當然不受歡迎。

Testing performance (part 2)測試性能(第2部分)

(section added by nolan600 on 08-JUL-2012) (部分由nolan600在2012年7月8日添加)

As it turns out it doesn't really matter for performance how you configure your pattern in JUL, ie whether or not it includes the source name or not.事實證明,在JUL中如何配置模式(即,是否包含源名稱)對於性能而言並不重要。 I tried with a very simple pattern:我嘗試了一個非常簡單的模式:

java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"

and that did not change the above timings at all.而這完全沒有改變上述時間。 My profiler revealed that the logger still spent a lot of time in calls to getSourceClassName() even if this was not part of my pattern.我的探查器顯示,即使這不是我的模式的一部分,記錄器仍然花費大量時間來調用getSourceClassName() The pattern doesn't matter.模式無關緊要。

I'm therefore concluding on the issue of performance that at least for the tested template based log statement there seems to be roughly a factor of 10 in real performance difference between JUL (slow) and SLF4J+Logback (quick).因此,我在性能問題上得出結論,至少對於經過測試的基於模板的日誌語句,JUL(慢)和SLF4J + Logback(快速)之間的實際性能差異似乎大約是10倍。 Just like Ceki said.就像切基說的那樣。

I can also see another thing namely that SLF4J's getLogger() call is a lot more expensive than JUL's ditto.我還可以看到另一件事,那就是SLF4J的getLogger()調用比JUL的同上更加昂貴。 (95 ms vs 0.3 ms if my profiler is accurate). (95毫秒vs. 0.3毫秒(如果我的探查器準確的話))。 This makes sense.這是有道理的。 SLF4J has to do some time on the binding of the underlying logging implementation. SLF4J必須在底層日誌記錄實現的綁定上花費一些時間。 This doesn't scare me.這不會嚇到我。 These calls should be somewhat rare in the lifetime of an application.在應用程序的生命週期中,這些調用應該很少見。 The fastness should be in the actual log calls.牢度應在實際的日誌調用中。

Final conclusion定論

(section added by nolan600 on 08-JUL-2012) (部分由nolan600在2012年7月8日添加)

Thank you for all your answers.感謝您的所有答覆。 Contrary to what I initially thought I've ended up deciding to use SLF4J for my API.與我最初的想法相反,我最終決定對我的API使用SLF4J。 This is based on a number of things and your input:這基於許多因素和您的輸入:

  1. It gives flexibility to choose log implementation at deployment time.它提供了在部署時選擇日誌實現的靈活性。

  2. Issues with lack of flexibility of JUL's configuration when run inside an application server.在應用服務器中運行時,JUL的配置缺乏靈活性的問題。

  3. SLF4J is certainly a lot faster as detailed above in particular if you couple it with Logback. SLF4J肯定比上面詳述的要快得多,特別是如果將其與Logback結合使用。 Even if this was just a rough test I have reason to believe that a lot more effort has gone into optimization on SLF4J+Logback than on JUL.即使這只是一個粗略的測試,我也有理由相信,在SLF4J + Logback上進行的優化比在JUL上進行了更多的努力。

  4. Documentation.文檔。 The documentation for SLF4J is simply a lot more comprehensive and precise. SLF4J的文檔更加全面和精確。

  5. Pattern flexibility.模式靈活性。 As I did the tests I set out to have JUL mimic the default pattern from Logback.在進行測試時,我開始讓JUL模仿Logback的默認模式。 This pattern includes the name of the thread.此模式包括線程的名稱。 It turns out JUL cannot do this out of the box.事實證明,JUL無法開箱即用。 Ok, I haven't missed it until now, but I don't think it is a thing that should be missing from a log framework.好的,直到現在我都沒有錯過它,但是我認爲日誌框架不應該缺少它。 Period!時期!

  6. Most (or many) Java projects today use Maven so adding a dependency is not that big a thing especially if that dependency is rather stable, ie doesn't constantly change its API.如今,大多數(或許多)Java項目都使用Maven,因此添加依賴項並不是一件大事,尤其是如果該依賴項相當穩定(即不會不斷更改其API)的話。 This seems to be true for SLF4J.對於SLF4J似乎確實如此。 Also the SLF4J jar and friends are small in size. SLF4J罐子和朋友的尺寸也很小。

So the strange thing that happened was that I actually got quite upset with JUL after having worked a bit with SLF4J.所以發生的一件奇怪的事情是,我在與SLF4J一起工作之後實際上對JUL感到不高興。 I still regret that it has to be this way with JUL.我仍然感到遺憾的是,JUL必須採取這種方式。 JUL is far from perfect but kind of does the job. JUL遠非完美,但可以勝任。 Just not quite well enough.只是不夠好。 The same can be said about Properties as an example but we do not think about abstracting that so people can plug in their own configuration library and what have you.Properties爲例也可以這樣說,但是我們不考慮抽象化,因此人們可以插入自己的配置庫以及您所擁有的。 I think the reason is that Properties comes in just above the bar while the opposite is true for JUL of today ... and in the past it came in at zero because it didn't exist.我認爲原因是, Properties在排行榜的正上方,而對於今天的7月,情況恰恰相反……過去,由於不存在,所以排在零位。


解決方案:

參考一: https://stackoom.com/question/lf2h
參考二: Why not use java.util.logging?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章