slf4j: biçimlendirilmiş mesaj, nesne dizisi, istisna nasıl günlüğe kaydedilir


275

Hem doldurulmuş bir iletiyi hem de kural dışı durumun yığın izlemesini günlüğe kaydetmek için doğru yaklaşım nedir?

logger.error(
    "\ncontext info one two three: {} {} {}\n",
    new Object[] {"1", "2", "3"},
    new Exception("something went wrong"));

Buna benzer bir çıktı üretmek istiyorum:

context info one two three: 1 2 3
java.lang.Exception: something went wrong
stacktrace 0
stacktrace 1
stacktrace ...

slf4j sürüm 1.6.1


3
Neden slf4j standart% s tarzı yerine kendi biçim dizesi sözdizimini kullandığını anlamıyorum. Can sıkıcı.
Keith Tyler

@KeithTyler Daha çok beğendim {}, lezzet meselesi ...
Betlista

@KeithTyler Bağımsız toString()değişkenlerin yöntemi pahalı olabilir. Bu sözdiziminde, yalnızca her nesneye bir başvuru iletilir ve toString()yöntem yalnızca belirli bir ileti gerçekten günlüğe kaydediliyorsa çağrılır. info()Günlük çağrısında atıfta bulunulan nesnelerde toString(), günlük düzeyi WARNveya daha yüksekse yöntem çağrılmaz . {}Sözdizimi bu olmadığını kullanıcılara bir hatırlatma String.format()benzeri operasyon, onlar bunların nesneleri yerine dize temsillerini geçmelidir yani.
user149408

Yanıtlar:


427

SLF4J 1.6.0'dan itibaren, birden çok parametrenin varlığında ve bir logging deyimindeki son argüman bir istisna ise, SLF4J kullanıcının son argümanın basit bir parametre değil istisna olarak ele alınmasını istediğini varsayar. Ayrıca ilgili SSS girişine de bakın .

Yani, yazma (SLF4J 1.7.x ve sonraki sürümlerinde)

 logger.error("one two three: {} {} {}", "a", "b", 
              "c", new Exception("something went wrong"));

veya yazma (SLF4J sürüm 1.6.x'te)

 logger.error("one two three: {} {} {}", new Object[] {"a", "b", 
              "c", new Exception("something went wrong")});

getirecek

one two three: a b c
java.lang.Exception: something went wrong
    at Example.main(Example.java:13)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at ...

Kesin çıktı, temel çerçevenin (örn. Logback, log4j, vb.) Ve temel çerçevenin nasıl yapılandırıldığına bağlı olacaktır. Ancak, son parametre bir istisna ise, altta yatan çerçeveden bağımsız olarak bu şekilde yorumlanacaktır.


4
Hangi temel kayıt çerçevesini kullanıyorsunuz? Yukarıdaki cevabımda belirtildiği gibi, son parametre bir istisna ise, temel çerçeveden bağımsız olarak bu şekilde yorumlanacaktır. (Logback, slf4j-log4j12, slf4j-jdk14 ve slf4j-basit ile test edilmiştir.)
Çeki

3
Maalesef, örneğinizde biçim dizesinde n = 3 yer tutucu ve nesne dizisinde n + 1 = 4 öğe kullandığınızı tanımadım. Biçim dizesinde n yer tutucuları ve ayrıca nesne dizisinde n öğeleri artı üçüncü parametre olarak bir istisna vardı. Beklentim, istisnanın yığın izlemesi ile basılmasıydı, ancak bu asla olmadı. Bu tasarlandığı gibi çalışıyor mu? Ayrıca, nesne öğesinde son öğe olan bir istisna dışında n yer tutucu ve n öğe varsa, herhangi bir stacktrace görmüyorum. Belki bir dizide n + 1 nesnesi olan n yer tutucusu biraz daha fazla vurgulanmalıdır.
Rowe

7
@Ceki'ye Javadocs'ta olmama konusunda zor zamanlar veriyordum ama Loggerjavadoc sınıfının en üstünde : slf4j.org/apidocs/org/slf4j/Logger.html
Adam Gent

1
İyileştirme talebi oluşturdum , isterseniz oy verebilirsiniz.
Betlista

8

@Ceki'nin cevabına ek olarak, logback kullanıyorsanız ve projenizde (genellikle logback.xml) bir yapılandırma dosyası kuruyorsanız, yığını izini çizmek için günlüğü tanımlayabilirsiniz.

<encoder>
    <pattern>%date |%-5level| [%thread] [%file:%line] - %msg%n%ex{full}</pattern> 
</encoder>

modeldeki% ex fark yaratan şeydir

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.