slf4j: स्वरूपित संदेश, ऑब्जेक्ट ऐरे, अपवाद को कैसे लॉग इन करें


275

आबादी वाले संदेश और अपवाद के ढेर का पता लगाने के लिए सही तरीका क्या है?

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

मैं इसके समान एक आउटपुट का उत्पादन करना चाहूंगा:

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

slf4j संस्करण 1.6.1


3
मुझे समझ में नहीं आता है कि मानक% s शैली के बजाय slf4j अपने स्वयं के प्रारूप स्ट्रिंग सिंटैक्स का उपयोग क्यों करता है। कष्टप्रद।
कीथ टायलर

@KeithTyler मुझे {}ज्यादा पसंद है , स्वाद की बात ...
बेटलिस्टा

@KeithTyler तर्कों की toString()विधि महंगी हो सकती है। इस सिंटैक्स के साथ, प्रत्येक ऑब्जेक्ट के लिए केवल एक संदर्भ दिया जाता है और toString()विधि को केवल तभी कहा जाता है जब विशेष संदेश वास्तव में लॉग इन हो रहा हो। info()लॉग कॉल में संदर्भित ऑब्जेक्ट में उनका toString()तरीका नहीं होगा, अगर लॉग स्तर WARNया उच्चतर है। {}वाक्य रचना है कि यह एक नहीं है उपयोगकर्ताओं के लिए एक चेतावनी है String.format(), की तरह आपरेशन यानी वे स्ट्रिंग अभ्यावेदन के बजाय वस्तुओं उसके पास करना चाहिए।
user149408

जवाबों:


427

SLF4J 1.6.0 के रूप में, कई मापदंडों की उपस्थिति में और यदि लॉगिंग स्टेटमेंट में अंतिम तर्क एक अपवाद है, तो SLF4J यह मान लेगा कि उपयोगकर्ता अंतिम तर्क को अपवाद के रूप में माना जाना चाहता है और साधारण पैरामीटर नहीं। प्रासंगिक FAQ प्रविष्टि भी देखें ।

इसलिए, लेखन (SLF4J संस्करण 1.7.x और बाद में)

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

या लेखन (SLF4J संस्करण 1.6.x में)

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

निकलेगा

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 ...

सटीक आउटपुट अंतर्निहित ढांचे (जैसे लॉगबैक, लॉग 4 जे, आदि) पर निर्भर करेगा और साथ ही अंतर्निहित रूपरेखा कैसे कॉन्फ़िगर की गई है। हालाँकि, यदि अंतिम पैरामीटर एक अपवाद है, तो इसकी व्याख्या अंतर्निहित रूपरेखा की परवाह किए बिना की जाएगी।


4
आप किस अंतर्निहित लॉगिंग ढांचे का उपयोग कर रहे हैं? जैसा कि ऊपर दिए गए मेरे उत्तर में बताया गया है, यदि अंतिम पैरामीटर एक अपवाद है तो इसकी व्याख्या अंतर्निहित रूपरेखा की परवाह किए बिना की जाएगी। (लॉगबैक, slf4j-log4j12, slf4j-jdk14 और slf4j-simple के साथ परीक्षण किया गया)
सेकी

3
क्षमा करें, मैंने नहीं पहचाना कि आपके उदाहरण में आपने n = 3 प्लेसहोल्डर्स का उपयोग प्रारूप स्ट्रिंग में और ऑब्जेक्ट सरणी में n + 1 = 4 तत्वों के लिए किया है। मैं प्रारूप स्ट्रिंग में n प्लेसहोल्डर था और ऑब्जेक्ट सरणी में n तत्व तीसरे प्लस के रूप में एक अपवाद भी था। मेरी उम्मीद थी कि अपवाद को स्टैक्ट्रेस के साथ मुद्रित किया जाएगा लेकिन ऐसा कभी नहीं हुआ। क्या यह डिज़ाइन के अनुसार काम करता है? इसके अलावा, यदि मेरे पास ऑब्जेक्ट एरे में एन प्लेसहोल्डर और एन एलिमेंट्स हैं तो आखिरी एलिमेंट होने के नाते मुझे कोई स्टैक्ट्रेस नहीं दिखता है। हो सकता है कि किसी सरणी में n + 1 ऑब्जेक्ट वाले n प्लेसहोल्डर्स पर थोड़ा अधिक जोर दिया जाए।
रोवे

7
मैं दे @Ceki एक कठिन समय के बारे में यह Javadocs में नहीं किया जा रहा है, लेकिन इसके लिए जा रहा था के शीर्ष पर Loggerजावाडोक वर्ग: slf4j.org/apidocs/org/slf4j/Logger.html
एडम Gent

1
मैंने सुधार अनुरोध बनाया , यदि आप इसे पसंद करते हैं तो आप इसके लिए वोट कर सकते हैं।
बेटलिस्टा

8

@Ceki के उत्तर के अतिरिक्त, यदि आप लॉगबैक का उपयोग कर रहे हैं और अपनी परियोजना में एक कॉन्फिग फाइल (आमतौर पर लॉगबैक.एक्सएमएल) का उपयोग कर रहे हैं, तो आप स्टैक ट्रेस का उपयोग करने के लिए लॉग का उपयोग करके परिभाषित कर सकते हैं।

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

पैटर्न में% पूर्व क्या अंतर बनाता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.