Level.FINE लॉगिंग संदेश क्यों नहीं दिखा रहे हैं?


110

के लिए Javadocsjava.util.logging.Level राज्य:


अवरोही क्रम में स्तर हैं:

  • SEVERE (उच्चतम मूल्य)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST (न्यूनतम मूल्य)

स्रोत

import java.util.logging.*;

class LoggingLevelsBlunder {

    public static void main(String[] args) {
        Logger logger = Logger.getAnonymousLogger();
        logger.setLevel(Level.FINER);
        System.out.println("Logging level is: " + logger.getLevel());
        for (int ii=0; ii<3; ii++) {
            logger.log(Level.FINE, ii + " " + (ii*ii));
            logger.log(Level.INFO, ii + " " + (ii*ii));
        }
    }
}

उत्पादन

Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .

समस्या का विवरण

मेरा उदाहरण इसके लिए सेट Levelहै FINER, इसलिए मैं प्रत्येक लूप के लिए 2 संदेश देखने की उम्मीद कर रहा था। इसके बजाय मुझे प्रत्येक लूप के लिए एक संदेश दिखाई देता है (संदेश Level.FINEगायब हैं)।

सवाल

FINE(, FINERया FINEST) आउटपुट को देखने के लिए क्या बदलने की आवश्यकता है ?

अद्यतन (समाधान)

विनीत रेनॉल्ड्स के जवाब के लिए धन्यवाद , यह संस्करण मेरी उम्मीद के अनुसार काम करता है। यह 3 x INFOसंदेश, और 3 x FINEसंदेश प्रदर्शित करता है ।

import java.util.logging.*;

class LoggingLevelsBlunder {

    public static void main(String[] args) {
        Logger logger = Logger.getAnonymousLogger();
        // LOG this level to the log
        logger.setLevel(Level.FINER);

        ConsoleHandler handler = new ConsoleHandler();
        // PUBLISH this level
        handler.setLevel(Level.FINER);
        logger.addHandler(handler);

        System.out.println("Logging level is: " + logger.getLevel());
        for (int ii=0; ii<3; ii++) {
            logger.log(Level.FINE, ii + " " + (ii*ii));
            logger.log(Level.INFO, ii + " " + (ii*ii));
        }
    }
}

10
मुझे लगता है कि आपके पास INFO और उससे ऊपर के कंसोल पर दो बार छपे हुए संदेश होंगे: पहला अनाम लकड़हारे के द्वारा, फिर उसके अभिभावक द्वारा, वैश्विक लकड़हारा जिसके पास एक कंसोलहैंडलर भी है, जो डिफ़ॉल्ट रूप से INFO को सेट करता है। वैश्विक लकड़हारा को अक्षम करने के लिए, आपको कोड की इस पंक्ति को जोड़ने की आवश्यकता है: logger.setUseParentHandlers (झूठी);
मिनट

मैं केवल पुलों के बारे में टिप्पणी की पुष्टि करना चाहता हूं। जब तक आप उपयोग नहीं करेंगे तब तक आपको दो आउटपुट मिलेंगे।
xpagesbeast

जवाबों:


124

लोग केवल संदेश लॉग करते हैं, अर्थात वे लॉग रिकॉर्ड (या लॉगिंग अनुरोध) बनाते हैं। वे गंतव्यों को संदेश प्रकाशित नहीं करते हैं, जो हैंडलर द्वारा ध्यान रखा जाता है। एक लकड़हारे के स्तर को निर्धारित करना, केवल उस स्तर या उससे अधिक मिलान वाले लॉग रिकॉर्ड बनाने का कारण बनता है ।

आप एक का उपयोग कर रहे हो सकता है ConsoleHandler(मैं यह नहीं जान सकता कि आपका आउटपुट System.err या फ़ाइल कहाँ है, लेकिन मुझे लगता है कि यह पूर्व है), जो स्तर के लॉग रिकॉर्ड को प्रकाशित करने में चूक करता है Level.INFO। आपको Level.FINERवांछित परिणाम के लिए, स्तर और उच्च के लॉग रिकॉर्ड प्रकाशित करने के लिए, इस हैंडलर को कॉन्फ़िगर करना होगा ।

मैं अंतर्निहित डिजाइन को समझने के लिए जावा लॉगिंग ओवरव्यू गाइड पढ़ने की सलाह दूंगा । गाइड एक लकड़हारे और एक हैंडलर की अवधारणा के बीच अंतर को कवर करता है।

हैंडलर स्तर का संपादन

1. कॉन्फ़िगरेशन फ़ाइल का उपयोग करना

Java.util.log गुण फ़ाइल (डिफ़ॉल्ट रूप से, यह logging.propertiesफ़ाइल है JRE_HOME/lib) कंसोलहैंडलर के डिफ़ॉल्ट स्तर को बदलने के लिए संशोधित की जा सकती है:

java.util.logging.ConsoleHandler.level = FINER

2. रनटाइम पर हैंडलर बनाना

इसकी अनुशंसा नहीं की जाती है, क्योंकि इसके परिणामस्वरूप वैश्विक कॉन्फ़िगरेशन को पछाड़ना होगा। अपने पूरे कोड के आधार पर इसका उपयोग करने से संभवतः अप्रभावी लॉगर कॉन्फ़िगरेशन हो जाएगा।

Handler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.FINER);
Logger.getAnonymousLogger().addHandler(consoleHandler);

2
धन्यवाद। यही चाल चली। मुझे अब एहसास हुआ कि मैं शुरू में इतना उलझन में क्यों था। मैंने पहले लॉगिंग स्तरों के साथ काम किया था, लेकिन उस समय मेरे कार्यान्वयन ने प्रत्येक लॉग किए गए संदेश को एक सूची में गिरा दिया, जिसे किसी भी संबंध में प्रदर्शित नहीं किया गया था Handler
एंड्रयू थॉम्पसन

3
आपका स्वागत है। और हाँ, डिजाइन आपको मिलता है, अगर कोई लकड़हारा लिख ​​रहा है जो बस एक फ़ाइल, कंसोल आदि में तार डंप करता है
विनीत रेनॉल्ड्स

7
और ग्लोबल जेआरई लाइब्रेरी में लॉगिंग.प्रोपर्टी को बदलना प्रबंधनीय है?
जेम्स एंडरसन

2
कृपया ध्यान दें, लकड़हारा का स्तर हैंडलर के स्तर की तुलना में कम प्रतिबंधक होना चाहिए। लॉगिंग से पहले जावा लकड़हारा और हैंडलर के बीच अधिकतम स्तर की जांच करता है। इसलिए यदि आप केवल हैंडलर सेट करें। सेटवेल (Level.FINER); आप कुछ भी नहीं देखेंगे क्योंकि डिफ़ॉल्ट लकड़हारा स्तर Level.INFO है। आपको इसे FINER, FINEST या ALL में सेट करना होगा। Logger.setLevel (Level.ALL) कहें;
जेफ़_एलीफ़सन

मुझे लगता है कि यह समस्या को एक-लाइनर के रूप में हल करेगा, यहां तक ​​कि जब आप एक डिफ़ॉल्ट वातावरण में अनाम और नामित लॉगर का उपयोग करते हैं:Logger.getGlobal().getParent().getHandlers()[0].setLevel(Level.FINER);
मार्क जेरोनिमस

27

क्यों

java.util.log में एक रूट लकड़हारा होता है जो कि चूक करता है Level.INFOऔर एक ConsoleHandler इससे जुड़ा होता है जो भी चूक करता है Level.INFOFINEसे कम है INFO, इसलिए ठीक संदेश डिफ़ॉल्ट रूप से प्रदर्शित नहीं होते हैं।


समाधान 1

अपने पूरे आवेदन के लिए एक लकड़हारा बनाएँ, जैसे आपके पैकेज के नाम या उपयोग से Logger.getGlobal(), और अपने स्वयं के कंसोल को इसमें हुक करें। फिर या तो रूट लॉगर को बंद करने के लिए कहें (उच्च स्तर के संदेशों के डुप्लिकेट आउटपुट से बचने के लिए), या अपने लकड़हारे से पूछें कि लॉग को रूट नहीं करना है।

public static final Logger applog = Logger.getGlobal();
...

// Create and set handler
Handler systemOut = new ConsoleHandler();
systemOut.setLevel( Level.ALL );
applog.addHandler( systemOut );
applog.setLevel( Level.ALL );

// Prevent logs from processed by default Console handler.
applog.setUseParentHandlers( false ); // Solution 1
Logger.getLogger("").setLevel( Level.OFF ); // Solution 2

समाधान २

वैकल्पिक रूप से, आप रूट लॉगर के बार को कम कर सकते हैं।

आप उन्हें कोड द्वारा सेट कर सकते हैं:

Logger rootLog = Logger.getLogger("");
rootLog.setLevel( Level.FINE );
rootLog.getHandlers()[0].setLevel( Level.FINE ); // Default console handler

या लॉगिंग कॉन्फ़िगरेशन फ़ाइल के साथ, यदि आप इसका उपयोग कर रहे हैं :

.level = FINE
java.util.logging.ConsoleHandler.level = FINE

वैश्विक स्तर को कम करके, आप कोर पुस्तकालयों से संदेश देखना शुरू कर सकते हैं, जैसे कि कुछ स्विंग या JavaFX घटकों से। इस मामले में आप एक निर्धारित कर सकते हैं फ़िल्टर अपने कार्यक्रम से नहीं गए संदेशों को फिल्टर करने की जड़ लकड़हारा पर।


applog.setUseParentHandlers (गलत) ये कोड मेरी मदद करते हैं, बहुत बहुत धन्यवाद।
एओलफ़न

4

मेरा जावा काम क्यों नहीं कर रहा है

एक जार फ़ाइल प्रदान करता है जो आपकी अपेक्षा के अनुरूप काम न करने के कारण आपको लॉग आउट करने में मदद करेगा। यह आपको एक पूर्ण डंप देता है कि लॉगर और हैंडलर्स को क्या स्थापित किया गया है और लॉगिंग पदानुक्रम में किस स्तर पर और किस स्तर पर सेट किया गया है।


यह एक टिप्पणी है, एक जवाब नहीं है।
hfontanez

4

क्यों

जैसा @Sheepy द्वारा उल्लेख किया गया है, इसका कारण यह नहीं है कि java.util.logging.Loggerएक रूट लकड़हारा है जो कि चूक करता है Level.INFO, और ConsoleHandlerउस मूल लकड़हारा से जुड़ा हुआ भी चूक करता है Level.INFO। इसलिए, देखने के लिए FINE(, FINERया FINEST) उत्पादन, आप रूट लकड़हारा का डिफ़ॉल्ट मान निर्धारित करने की आवश्यकता है और इसके ConsoleHandlerलिए Level.FINEके रूप में इस प्रकार है:

Logger.getLogger("").setLevel(Level.FINE);
Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);


आपके अपडेट की समस्या (समाधान)

जैसा कि @mins द्वारा उल्लेख किया गया है, आपके पास कंसोल के INFOऊपर और ऊपर दो बार छपे हुए संदेश होंगे : पहले अनाम लकड़हारे द्वारा, फिर उसके अभिभावक द्वारा, मूल लकड़हारा जिसके पास डिफ़ॉल्ट रूप ConsoleHandlerसे एक सेट भी है INFO। रूट लकड़हारा को निष्क्रिय करने के लिए, आपको कोड की इस पंक्ति को जोड़ना होगा:logger.setUseParentHandlers(false);

लॉग को रोकने के अन्य तरीके हैं जो @Sheepy द्वारा उल्लिखित रूट लॉगर के डिफ़ॉल्ट कंसोल हैंडलर द्वारा संसाधित किए जा रहे हैं, जैसे:

Logger.getLogger("").getHandlers()[0].setLevel( Level.OFF );

लेकिन Logger.getLogger("").setLevel( Level.OFF );काम नहीं करेगा क्योंकि यह केवल संदेश को मूल लकड़हारे को सीधे ब्लॉक करता है, न कि संदेश बाल लकड़हारे से आता है। यह बताने के लिए कि कैसे Logger Hierarchyकाम करता है, मैं निम्नलिखित चित्र बनाता हूं:

यहां छवि विवरण दर्ज करें

public void setLevel(Level newLevel)लॉग स्तर निर्दिष्ट करें कि कौन सा संदेश स्तर इस लकड़हारे द्वारा लॉग किया जाएगा। इस मान से कम वाले संदेश स्तर को छोड़ दिया जाएगा। स्तर मान Level.OFF का उपयोग लॉगिंग को बंद करने के लिए किया जा सकता है। यदि नया स्तर शून्य है, तो इसका मतलब है कि यह नोड विशिष्ट (गैर-शून्य) स्तर मूल्य के साथ अपने निकटतम पूर्वज से अपने स्तर को प्राप्त करना चाहिए।


0

मुझे मेरी वास्तविक समस्या का पता चला और किसी भी उत्तर में इसका उल्लेख नहीं किया गया था: मेरे कुछ यूनिट-परीक्षण लॉगिंग इनिशियलाइज़ेशन कोड को एक ही टेस्ट सूट के भीतर कई बार चलाने का कारण बन रहे थे, जो बाद के परीक्षणों पर लॉगिंग को गड़बड़ कर रहा था।


0

अन्य प्रकारों की कोशिश की, यह उचित हो सकता है

    Logger logger = Logger.getLogger(MyClass.class.getName());        
    Level level = Level.ALL;
    for(Handler h : java.util.logging.Logger.getLogger("").getHandlers())    
        h.setLevel(level);
    logger.setLevel(level);
// this must be shown
    logger.fine("fine");
    logger.info("info");

0

यह समाधान मेरे लिए बेहतर है, परिवर्तन के लिए स्थिरता और डिजाइन के बारे में:

  1. जार फ़ाइल में शामिल करने के लिए संसाधन प्रोजेक्ट फ़ोल्डर में एम्बेड करने वाली लॉगिंग प्रॉपर्टी फ़ाइल बनाएँ:

    # Logging
    handlers = java.util.logging.ConsoleHandler
    .level = ALL
    
    # Console Logging
    java.util.logging.ConsoleHandler.level = ALL
  2. कोड से संपत्ति फ़ाइल लोड करें:

    public static java.net.URL retrieveURLOfJarResource(String resourceName) {
       return Thread.currentThread().getContextClassLoader().getResource(resourceName);
    }
    
    public synchronized void initializeLogger() {
       try (InputStream is = retrieveURLOfJarResource("logging.properties").openStream()) {
          LogManager.getLogManager().readConfiguration(is);
       } catch (IOException e) {
          // ...
       }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.