Neden java.util.logging kullanılmıyor?


351

Hayatımda ilk kez kendimi açık kaynaklı bir Java API yazdığım bir konumda buldum. Umarım diğer birçok projeye dahil edilir.

Günlüğe kaydetmek için ben (ve gerçekten birlikte çalıştığım insanlar) her zaman JUL (java.util.logging) kullandım ve bununla ilgili hiçbir sorun yaşamadım. Ancak şimdi API geliştirme için ne yapmam gerektiğini daha ayrıntılı olarak anlamalıyım. Bu konuda biraz araştırma yaptım ve elde ettiğim bilgilerle daha da kafam karıştı. Dolayısıyla bu yazı.

TEMMUZ'dan geldiğimden beri bu konuda önyargılıyım. Gerisi hakkındaki bilgim o kadar büyük değil.

Yaptığım araştırmadan, insanların JUL'u sevmemesinin nedenlerini ortaya çıkardım:

  1. "Ben Cum Tem yayımlanan çok önce Java geliştirmeye başladı ve bana günlük-çerçeve-X ile devam etmek yerine yeni bir şeyler öğrenmek için daha kolay oldu" . Hmm. Şaka yapmıyorum, aslında insanlar böyle söylüyor. Bu argümanla hepimiz COBOL yapabiliriz. (ancak ben kesinlikle bu tembel bir ahbap olmakla ilgili olabilir)

  2. Diyerek şöyle devam etti: "TEMMUZ'daki kayıt seviyelerinin adlarını sevmiyorum" . Tamam, cidden, bu yeni bir bağımlılık getirmek için yeterli bir neden değil.

  3. "TEMMUZ çıktısının standart biçimini sevmiyorum" . Hmm. Bu sadece yapılandırmadır. Kod-bilge bir şey yapmak zorunda bile değilsiniz. (doğru, eski günlerde, doğru olması için kendi Formatter sınıfınızı oluşturmanız gerekebilir).

  4. "Logging-framework-X kullanan diğer kütüphaneleri de kullanıyorum, bu yüzden bunu kullanmayı daha kolay düşündüm" . Bu dairesel bir argüman, değil mi? 'Herkes' neden JUL yerine logging-framework-X kullanıyor?

  5. "Herkes günlük kaydı-çerçeve-X kullanıyor" . Bu benim için yukarıdakilerin özel bir örneğidir. Çoğunluk her zaman doğru değildir.

Yani asıl büyük soru neden TEMMUZ olmasın? . Ne kaçırdım? Tomruk cepheleri (SLF4J, JCL) için varoluş nedeni, tarihsel olarak çok sayıda tomruklama uygulamasının mevcut olması ve bunun sebebinin gördüğüm gibi JUL'dan önceki döneme kadar gitmesidir. JUL mükemmel olsaydı, giriş cepheleri olmazdı, ya da ne? İşleri daha karmaşık hale getirmek için JUL, bir dereceye kadar bir cephenin kendisidir, bu da İşleyicilerin, Biçimlendiricilerin ve hatta LogManager'ın değiştirilmesine izin verir.

Aynı şeyi yapmanın (giriş) birden fazla yolunu benimsemek yerine, neden ilk başta gerekli olduklarını sorgulamalıyız? (ve bu nedenlerin hala var olup olmadığına bakın)

Tamam, şu ana kadar yaptığım araştırma , TEMMUZ ile ilgili gerçek sorunlar olabileceğini görebildiğim birkaç şeye yol açtı :

  1. Performans . Bazıları SLF4J'deki performansın diğerlerinden daha üstün olduğunu söylüyor. Bu bana erken optimizasyon örneği gibi geliyor. Saniyede yüzlerce megabayt kaydetmeniz gerekiyorsa, yine de doğru yolda olduğunuzdan emin değilim. JUL da gelişti ve Java 1.4'te yaptığınız testler artık doğru olmayabilir. Burada bunu okuyabilirsiniz ve bu düzeltme Java 7'ye dönüştürmüştür. Birçoğu, günlükleme yöntemlerinde dize birleştirme yükü hakkında da konuşur. Ancak, şablon tabanlı günlük kaydı bu maliyeti önler ve Temmuz ayında da mevcuttur. Şahsen ben asla şablon tabanlı log yazmam. Bunun için çok tembel. Örneğin, bunu TEMMUZ ile yaparsam:

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

    IDE'm beni uyaracak ve izin vermesi için izin isteyecek:

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

    .. tabi ki kabul edeceğim. İzin verildi ! Yardımın için teşekkürler.

    Yani aslında bu tür ifadeleri kendim yazmıyorum, bu IDE tarafından yapılır.

    Performans konusunda sonuç olarak, JUL'un performansının rekabete kıyasla iyi olmadığını gösteren hiçbir şey bulamadım.

  2. Sınıfyolundan yapılandırma . Kullanıma hazır JUL, sınıf yolundan bir yapılandırma dosyası yükleyemiyor. Bunu yapmak için birkaç satır kod var . Bunun neden sinir bozucu olabileceğini görebiliyorum ama çözüm kısa ve basit.

  3. Çıktı işleyicilerin kullanılabilirliği . JUL, kutudan çıkar çıkmaz 5 çıkış işleyicisi ile birlikte gelir: konsol, dosya akışı, soket ve bellek. Bunlar genişletilebilir veya yenileri yazılabilir. Bu, örneğin UNIX / Linux Syslog ve Windows Olay Günlüğüne yazıyor olabilir. Şahsen bu gereksinimi hiç yaşamadım ya da kullanıldığını görmedim ama neden yararlı bir özellik olabileceğini kesinlikle anlatabilirim. Logback, örneğin Syslog için bir ek ile birlikte gelir. Hala tartışırım

    1. Çıktı destinasyonlarına yönelik ihtiyaçların% 99,5'i, TEMMUZ'da hazır olanlar tarafından karşılanmaktadır.
    2. Özel ihtiyaçlar, başka bir şey yerine JUL'un üstünde özel işleyiciler tarafından karşılanabilir. Benim için JUL için bir Syslog çıktı işleyicisi yazmanın başka bir günlük çerçevesi için olduğundan daha fazla zaman aldığını gösteren hiçbir şey yok.

Göz ardı ettiğim bir şey olduğundan gerçekten endişeliyim. Log cephelerinin kullanımı ve JUL dışındaki log uygulamalarının o kadar yaygın olduğu sonucuna varmamalıyım ki, sadece anlamayan benim. İlk defa olmaz, korkarım. :-)

Peki API'm ile ne yapmalıyım? Başarılı olmasını istiyorum. Tabii ki sadece "akış ile gitmek" ve SLF4J (bu günlerde en popüler gibi görünüyor) uygulamak olabilir ama kendi iyiliğim için hala hala tüm bulanıklığı garanti JUL bugün tam olarak ne olduğunu anlamak gerekir? Kütüphanem için TEMMUZ seçerek kendimi sabote edecek miyim?

Test performansı

(bölüm 07-TEMMUZ 2012 tarihinde nolan600 tarafından eklendi)

Aşağıda Ceki'den SLF4J'in parametrelendirmesinin JUL'dan 10 kat veya daha hızlı olduğuna dair bir referans var. Bu yüzden bazı basit testler yapmaya başladım. İlk bakışta iddia kesinlikle doğrudur. İşte ön sonuçlar (ancak okumaya devam edin!):

  • Yürütme süresi SLF4J, arka uç
  • Yürütme süresi SLF4J, arka uç TEMMUZ: 12938
  • Yürütme zamanı TEMMUZ: 16911

Yukarıdaki sayılar msec'tir, dolayısıyla daha azı daha iyidir. Yani 10 kat performans farkı ilk bakışta oldukça yakın. İlk tepkim: Bu çok fazla!

İşte testin çekirdeği. Görülebileceği gibi bir tamsayı ve bir dize, daha sonra log deyiminde kullanılan bir döngüde oluşturulmuştur:

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

(Günlük deyiminin hem ilkel bir veri türüne (bu durumda int) hem de daha karmaşık bir veri türüne (bu durumda bir String) sahip olmasını istedim.

SLF4J için günlük ifadesi:

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

TEMMUZ için günlük ifadesi:

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

JVM, gerçek ölçüm yapılmadan önce bir kez yapılan aynı testle 'ısıtıldı'. Windows 7'de Java 1.7.03 kullanıldı. SLF4J'nin (v1.6.6) ve Logback'in (v1.0.6) son sürümleri kullanıldı. Stdout ve stderr boş cihaza yönlendirildi.

Ancak, şimdi dikkatli olun, JUL zamanının çoğunu harcıyor, getSourceClassName()çünkü JUL varsayılan olarak çıktıdaki kaynak sınıfı adını yazdırıyor, ancak Logback yapmıyor. Bu yüzden elma ve portakalları karşılaştırıyoruz. Sınamayı yeniden yapmam ve günlük uygulamalarını benzer şekilde yapılandırmam gerekiyor, böylece aynı şeyleri çıktılar. Bununla birlikte, SLF4J + Logback'in hala üstte çıkacağını, ancak yukarıda verilen ilk sayılardan uzak olacağını sanıyorum. Bizi izlemeye devam edin.

Btw: Test aslında SLF4J veya Logback ile ilk kez çalıştım. Hoş bir deneyim. TEMMUZ, başlarken kesinlikle çok daha az hoş.

Test performansı (bölüm 2)

(bölüm 08 Temmuz-2012 tarihinde nolan600 tarafından eklendi)

Anlaşıldığı üzere, deseninizi TEMMUZ'da nasıl yapılandırdığınız, yani kaynak adını içerip içermediği önemli değildir. Çok basit bir desenle denedim:

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

ve bu yukarıdaki zamanlamaları hiç değiştirmedi. Profil oluşturucum, bu benim modelimin bir getSourceClassName()parçası olmasa bile , kaydedicinin çağrılara hala çok zaman harcadığını açıkladı . Desen önemli değil.

Bu nedenle, en azından test edilen şablon tabanlı günlük ifadesi için kabaca JUL (yavaş) ve SLF4J + Logback (hızlı) arasındaki gerçek performans farkında 10 faktörü olduğu sonucuna varıyorum. Tıpkı Ceki'nin dediği gibi.

SLF4J'in getLogger()çağrısının JUL'un ditto'sundan çok daha pahalı olduğu başka bir şey de görebiliyorum . (Profilerim doğruysa 95 ms vs 0.3 ms). Bu mantıklı. SLF4J, temeldeki kayıt uygulamasının bağlanması için biraz zaman ayırmalıdır. Bu beni korkutmuyor. Bu çağrılar bir uygulamanın kullanım ömrü boyunca biraz nadir olmalıdır. Haslık gerçek günlük çağrılarında olmalıdır.

Final sonucu

(bölüm 08 Temmuz-2012 tarihinde nolan600 tarafından eklendi)

Tüm cevaplarınız için teşekkür ederim. Başlangıçta benim API için SLF4J kullanmaya karar verdim düşündüm aksine. Bu, bazı şeylere ve girdilerinize dayanmaktadır:

  1. Dağıtım zamanında günlük uygulamasını seçme esnekliği sağlar.

  2. Bir uygulama sunucusunda çalıştırıldığında, JUL'un yapılandırmasında esneklik eksikliği olan sorunlar.

  3. SLF4J, özellikle Logback ile birleştirirseniz, yukarıda ayrıntılı olarak açıklandığı gibi çok daha hızlıdır. Bu sadece kaba bir test olsa bile, SLF4J + Logback üzerinde Temmuz ayına göre optimizasyona çok daha fazla çaba harcandığına inanmak için nedenim var.

  4. Belgeler. SLF4J belgeleri çok daha kapsamlı ve hassastır.

  5. Desen esnekliği. Testleri yaparken JUL uygulamasının Logback'in varsayılan şablonunu taklit etmesini sağladım. Bu desen, iş parçacığının adını içerir. JUL bunu kutunun dışında yapamaz. Tamam, şimdiye kadar kaçırmadım, ama bir günlük çerçevesinden eksik olması gereken bir şey olduğunu düşünmüyorum. Dönem!

  6. Günümüzde çoğu (veya birçok) Java projesi Maven'i kullanıyor, bu nedenle bir bağımlılık eklemek, özellikle bu bağımlılık oldukça kararlıysa, yani sürekli olarak API'sını değiştirmezse, büyük bir şey değildir. Bu SLF4J için geçerli gibi görünüyor. Ayrıca SLF4J kavanozu ve arkadaşları küçük boyutludur.

Yani, garip olan şey, SLF4J ile biraz çalıştıktan sonra aslında JUL ile oldukça üzüldüm. Yine de TEMMUZ ile böyle olması gerektiğine üzülüyorum. JUL mükemmel olmaktan uzaktır, ancak bir tür iş yapar. Yeterince iyi değil. Aynı şey Propertiesörnek olarak da söylenebilir , ancak insanların kendi yapılandırma kitaplıklarını ve neleriniz olduğunu takabilmeleri için soyutlamayı düşünmüyoruz. Sanırım bunun sebebi Propertiesçubuğun hemen üstündeyken, bunun tam tersi bugünün TEMMUZ için geçerli ... ve geçmişte sıfır geldi çünkü mevcut değildi.


8
Bu iyi sunulan soru ilginç olduğu için bir kapanış istemeyeceğim, ancak SSS'yi okursanız sınırda: fikirlere dayanmayan kesin bir benzersiz cevap bulmak zor olacak.
Denys Séguret

Kaçırmış olabileceğiniz şey, birçok çerçeve yazarının JUL'u kullanmaya çalışmaktan vazgeçmiş olmasıdır ve bu nedenle vanilya java yapmazsanız bunu kullanmak genellikle daha zordur.
Denys Séguret

3
Jul'dan önce gelen popüler günlükleme çerçevelerine atıfta bulunurken "logging-framework-X" jenerik terimini kullanmak yanıltıcıdır. Bu durumda "log4j" kullanmalısınız. SLF4J ve logback gibi diğer popüler çerçeveler, jul yayınlandıktan sonra çok iyi geldi.
Ceki

1
@Acuariano. Netty projesi, sınıf yolunda hangi günlükleme çerçevesinin kullanılabilir olduğunu test etmek için Reflection'ı kullanıyor. Kaynak için buraya bakınız . Bkz InternalLoggerFactory.java.
peterh

1
@xenoterracide daha da önemli olan Java 9 için bir güncelleme olacak java.lang.System.Logger, ki bu arayüz yakalandığı ve bu arayüzün bir uygulamasını sağladığı sürece, istediğiniz gerçek günlük çerçevesine yönlendirilebilen bir arayüz. Modülerleştirmeyle birlikte java.util.logging, farklı bir çerçeveyi tercih ederseniz paketlenmiş JRE içermeyen bir uygulamayı bile dağıtabilirsiniz .
Holger

Yanıtlar:


207

Feragatname : Log4j, SLF4J ve logback projelerinin kurucusuyum.

SLF4J'yi tercih etmenin nesnel nedenleri vardır. Birincisi, SLF4J, son kullanıcının özgürlüğün altında yatan kayıt çerçevesini seçmesine izin verir . Buna ek olarak, daha savurgan kullanıcılar , arkasından düşerek log4j'nin ötesinde yetenekler sunan geri dönüşü tercih etme eğilimindedir . Feature-wise jul bazı kullanıcılar için yeterli olabilir, ancak diğerleri için yeterli değildir. Özetle, günlük kaydı sizin için önemliyse, SLF4J'yi logback ile birlikte temel uygulama olarak kullanmak istersiniz. Günlük kaydı önemsizse, jul iyidir.

Ancak, bir oss geliştiricisi olarak, sadece kendi değil, kullanıcılarınızın tercihlerini de dikkate almanız gerekir. Çünkü sen SLF4J benimsemek gerektiğini izler Eğer SLF4J iyi tarihine daha ama eminiz şu anda en Java geliştiricileri (2012 Temmuz) kendi günlük API olarak SLF4J tercih ettiklerinden. Nihayetinde popüler düşünceyi önemsememeye karar verirseniz, aşağıdaki gerçekleri göz önünde bulundurun:

  1. jul'i tercih edenler bunu yaparlar çünkü jul JDK ile birlikte gelir. Bildiğim kadarıyla jul lehine başka nesnel argümanlar yok
  2. jul için kendi tercihiniz tam da budur, bir tercih .

Bu nedenle, görünüşte cesur olsa da, kamuoyunun üzerinde "sert gerçekler" tutmak bu durumda mantıklı bir yanlıştır.

Hala ikna olmamışsa , JB Nizet ek ve güçlü bir argüman öne sürer :

Son kullanıcı kendi kodunu veya log4j veya logback kullanan başka bir kütüphane için bu özelleştirmeyi zaten yapmış olabilir. jul genişletilebilir, ancak logback'i genişletmek zorunda olan jul, log4j ve Tanrı sadece diğer günlük çerçevesini bilir çünkü dört farklı günlük çerçevesi kullanan dört kütüphane kullanır. SLF4J kullanarak, seçtiğiniz günlük çerçevelerini yapılandırmasına izin verirsiniz, seçtiğiniz çerçeveyi değil. Tipik bir projenin sadece sizin değil, sayısız kütüphane kullandığını unutmayın .

Herhangi bir nedenle SLF4J API'sinden nefret ederseniz ve onu kullanmak işinizin eğlencesini kaptırırsa, o zaman elbette jul için gidin Sonuçta, jul'i SLF4J'e yönlendirmek için araçlar var .

Bu arada, jul parametrelendirmesi, fark edilebilir bir fark yaratan SLF4J'lerden en az 10 kat daha yavaştır.


2
@Ceki feragatnameniz üzerinde biraz ayrıntı vermek isteyebilirsiniz, bu yüzden log4j, slf4j ve logback projelerinde mevcut rolünüzden bahseder. Nedeni doğal olarak önyargınızı açıklamaktır.
Thorbjørn Ravn Andersen

2
Çoğu Java geliştiricisinin günlük API'sı olarak SLF4J'yi tercih ettiği iddiası için bazı destek var mı?
Olivier Cailloux

3
Görevimin özü, farklı geliştiricilerin anlaşmazlığın ötesinde görünen farklı tercihlere sahip olmasıdır. Evet?
Ceki

1
dürüst olmak gerekirse, Java 11 (veya sonuçta ne olursa olsun) 2018 kriterlerini ve zaman uyumsuz modda log4j2'ye karşı görmek isterim.
2018'de xenoterracide

5
Buradayım, SLF4J kullanıyorum ve hala diğer kütüphanelerin kullandığı diğer tüm günlük çerçeveleri ile uğraşmak zorundayım. SLF4J kullanımı heterojen kütük problemini çözmez, sadece daha da kötüleştirir. xkcd.com/927
Charlie

34
  1. java.util.loggingJava 1.4'te tanıtıldı. Bundan önce günlüğe kaydetmenin kullanımları vardı, bu yüzden başka birçok günlükleme API'sı var. Java 1.4'ten önce yoğun olarak kullanılan ve bu nedenle 1.4 yayınlandığında sadece 0'a düşmeyen harika bir pazar payına sahip olan API'lar.

  2. TEMMUZ bu kadar iyi başlamadı, bahsettiğiniz şeylerin çoğu 1.4'te çok daha kötü ve sadece 1.5'te daha iyi oldu (ve 6'da da sanırım, ama çok emin değilim).

  3. JUL, aynı JVM'de farklı yapılandırmalara sahip birden çok uygulama için uygun değildir (etkileşimde bulunmaması gereken birden çok web uygulamasını düşünün). Tomcat'in çalışabilmesi için bazı halkalardan atlaması gerekiyor (doğru anladıysam JUL'u etkili bir şekilde yeniden uygulamak).

  4. Kütüphanelerinizin hangi kayıt çerçevesini kullandığını her zaman etkileyemezsiniz. Bu nedenle (aslında diğer kütüphanelerin üstünde çok ince bir API katmanı olan) SLF4J kullanmak, tüm logging dünyasının biraz tutarlı bir resmini korumaya yardımcı olur (böylece aynı sistemde hala kütük günlüğü tutmaya devam ederken alttaki günlükleme çerçevesine karar verebilirsiniz).

  5. Kütüphaneler kolayca değiştirilemez. Bir kütüphanenin daha önceki bir sürümü logging-library-X kullanmak için kullanıldıysa, bu kütüphane açıkça süper olsa bile, log-library-Y'ye (örneğin JUL) kolayca geçemez: bu kütüphanenin herhangi bir kullanıcısının öğrenmesi gerekir yeni günlük kaydı çerçevesi ve (en azından) günlük kaydını yeniden yapılandırın. Bu büyük bir hayır-hayır, özellikle de çoğu insana belirgin bir kazanç getirmediğinde.

JUL olduğunu düşündüğüm her şeyi söyledikten sonra, bu günlerde diğer günlük çerçeveleri için en azından geçerli bir alternatif.


1
Teşekkürler Joachim, gönderinizi takdir ediyorum. (1) ve (2) bana sadece tarih. Uzun zaman önce. Sizin (4) bunun bir sonucudur ve sonra döngüsel bir argüman olarak adlandırdığım şeye dönüşür. Ancak (3) gerçekten ilginç. Belki birşeyin peşindesiniz? Ancak bu sadece günün sonunda çok az insan olan uygulama kapları inşa edenleri etkileyecektir. Ya da ne?
peterh

3
Peki, kimin tarihi görmezden geldiği onu tekrarlamaya mahkumdur ;-) Tarih yazılım geliştirmeyle çok ilgilidir. İnsanlar çok hızlı hareket etmiyor ve mevcut üçüncü taraf kitaplıklarını standart API'lerle değiştirmek yalnızca standart API'ler en azından üçüncü taraf kitaplıkları kadar iyi çalışıyorsa iyi çalışır . Ve başlangıçta olmadılar (ve bazı durumlarda tartışmasız hala).
Joachim Sauer

Joachim, bahsettiğiniz "tartışmasız hala bazı durumlarda yok" ile ilgileniyorum. Etin olması gerekiyordu. Mevcut kodunuzdaki bir kayıt defteri kitaplığının değiştirilmesi oldukça önemlidir ve bu günlerde otomatikleştirilebilir. SLF4J'de benim açımdan bunu kanıtlayan bir araç var. Bu yüzden 2002'de log4j ile yazılmış büyük bir kütüphanenin otomatik bir araçla birkaç dakika içinde TEMMUZ'a dönüştürülebileceğini düşünürdüm. (Birinin var olup olmadığını bilmiyorum). Öyleyse neden olmadı?
peterh

3
@ nolan6000: Bu cümle ile ilgili ayrıntılara girecek ayrıntılar hakkında yeterince bilgim yok ve bu gerçekten bahsettiğim nokta değil. JUL şimdi üçüncü taraf çerçevelerle eşit olsa bile, atalet ve mevcut altyapı geçiş yapmamak için hala güçlü bir neden. Örneğin, kütüphane X, Sürüm 1.1'de slf4j kullandıysa, 1.2'de (hatta 2.0'da) JUL'a geçmek birçok kullanıcı için büyük bir sorun olacaktır (eski sistemi doğru bir şekilde yapılandırmış olan ve bunu belirgin bir kazanç elde etmek için tekrar yapmak zorunda kalacak) .
Joachim Sauer

bile @ nolan6000 sen tarihin umurumda değil, kütüphaneleri uygulamalarınızda kullanmak kesinlikle yok. Sizden farklı bir günlük çerçevesi kullandığı için bir kütüphaneyi atmak zorunda değilsiniz.
Thorbjørn Ravn Andersen

29

IMHO, slf4j gibi bir günlük cephesi kullanmanın ana avantajı, kütüphanenin son kullanıcısının, seçiminizi son kullanıcıya vermek yerine, hangi somut günlük uygulaması uygulamasını seçmesine izin vermenizdir.

Belki de Log4j veya LogBack'e (özel formatlayıcılar, appenders, vb.) Zaman ve para yatırdı ve jul yapılandırmak yerine Log4j veya LogBack kullanmaya devam etmeyi tercih ediyor. Sorun değil: slf4j buna izin verir. Log4j'i jul üzerinde kullanmak akıllıca bir seçim mi? Belki, belki değil. Ama umrunda değil. Son kullanıcının neyi tercih ettiğini seçmesine izin verin.


Teşekkürler JB. Benim sorum, JUL'u ona zorlayarak gerçekten çok fazla kütüphane kullanıcısına / uygulayıcısına empoze edersem? Örneğin, JUL'un standart çıktı işleyicilerinden memnun değilse, gördüğüm gibi onları dağıtım sırasında kendi başına değiştirebilir. JUL'u deli gömleği olarak görmüyorum. Bana öyle geliyor ki, diğerleri kadar esnek ve genişletilebilir.
peterh

12
Son kullanıcı bu özelleştirmeyi kendi kodu veya log4j veya LogBack kullanan başka bir kütüphane için zaten yapmış olabilir. jul genişletilebilir, ancak LogBack, jul, log4j ve Tanrı'yı ​​genişletmek zorunda olan sadece 4 farklı günlük çerçevesi kullanan 4 kütüphane kullandığından hangi diğer günlük çerçevesini bilir. Slf4j kullanarak, istediği günlük çerçevelerini yapılandırmasına izin verirsiniz. seçtiğiniz kişi değil. Tipik projelerin sadece sizin değil, sayısız kütüphane kullandığını unutmayın.
JB Nizet

6

Şüphelendiğim gibi, JUL'u kullanmaya başladım çünkü hemen başlamak en kolay olanıydı. Ancak yıllar içinde, biraz daha fazla zaman geçirmeyi diliyorum.

Şimdi asıl sorun, birçok uygulamada kullanılan ve hepsi de JUL kullanan önemli miktarda 'kütüphane' koduna sahip olmamız. Bu araçları bir web hizmeti türü uygulamasında kullandığımda, günlük kaydı kaybolur veya öngörülemeyen veya garip bir yere gider.

Bizim çözümümüz kütüphane koduna kütüphane kütük çağrılarının değişmediği, ancak mevcut kütük mekanizmasına dinamik olarak yönlendirildiği anlamına gelen bir cephe eklemekti. Bir POJO aracına dahil edildiğinde TEMMUZ'a yönlendirilirler, ancak bir web uygulaması olarak dağıtıldıklarında LogBack'e yönlendirilirler.

Şüphesiz, kütüphane kodunun parametreli günlüğe kaydetme kullanmaması, ancak bu artık gerektiği zaman ve sonra uyarlanabilir.

Cepheyi inşa etmek için slf4j kullandık.


1
Slf4j dağıtımında "redirect java.util.logging to slf4j" paketini kullanmamanızın herhangi bir nedeni var mı?
Thorbjørn Ravn Andersen

2
Yaptık, ama çok az değer verdik çünkü slf4j'ye geçmenin birincil yararı verimli parametreli günlük kaydıdır. Bunu en başından kullansaydık şimdi yapacak bir işimiz olmazdı.
OldCurmudgeon

1
Bu slf4j düşük asılı meyve olduğunu kabul ediyorum.
Thorbjørn Ravn Andersen

3

Bir SSD, Java 1.8, Win64 çıktı slback4-1.7.21 üzerinden logback-1.1.7 karşı jul koştu

jul 48449 ms koştu, 1M döngü için 27185 ms oturum açın.

Yine de, biraz daha hızlı ve biraz daha güzel API, 3 kütüphane ve 800K için bana değer değil.

package log;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LogJUL
{
    final static Logger logger = Logger.getLogger(LogJUL.class.getSimpleName());

    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            Object[] o = { lc };

            logger.log(Level.INFO,"Epoch time {0}", o);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }
}

ve

package log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogSLF
{
    static Logger logger = LoggerFactory.getLogger(LogSLF.class);


    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            logger.info("Epoch time {}", lc);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }

}

3
Benzeri gibi karşılaştırmıyorsunuz. Neden açık bir şekilde jul için bir dizi oluşturuyorsunuz? Sanırım slf4j bir argüman aşırı yüklü olmadığı için logger.info(). Böylece, slf4j'nin arayüzündeki bir eksikliği telafi etmek için kasıtlı bir şekilde performans sergiliyorsunuz. Bunun yerine her iki yöntemi de deyimsel olarak kodlandıkları şekilde kodlamanız gerekir.
Klitos Kyriacou

2
Yanlış anladın. Ek bir 800K kullanmanız gerekmez. Fikir birliği çok ince SLF4J api kullanmaya değer çünkü o (ya da belki bir gün kodunuzu yeniden kullanan diğerleri!) JUL, Logback, Log4j vb arasında serbestçe geçiş yapabilirsiniz. SLF4J sadece ~ 28K. JUL köprüsü SLF4J (slf4j-jdk ... kavanoz) sadece ~ 9K.
riskop
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.