2010-02-09 14 views
10

हम जानते हैं कि हम अपनी गुण/कॉन्फ़िगरेशन फ़ाइल के माध्यम से विशिष्ट स्थानों (कक्षा या जावा में पैकेज) पर लॉग को बंद करने के लिए log4j कॉन्फ़िगर कर सकते हैं। मेरे प्रश्नों का पालन किया जाता है:लॉग लॉग वास्तव में क्या करते हैं जब हम कुछ लॉग स्थानों को चालू या बंद करते हैं?

  1. वास्तव में उन झंडे के लिए log4j क्या कर रहा है?
  2. लॉग 4j में अभी भी लॉग स्टेटमेंट है, लेकिन उस ध्वज के कारण फ़ाइल या कंसोल पर लिखा नहीं जा रहा है? तो अभी भी प्रदर्शन प्रभाव है?
  3. यह सी ++ में #ifdef जैसा है जो संकलन समय पर प्रभावी होता है तो प्रदर्शन प्रभाव को सीमित कर सकता है?

धन्यवाद,

उत्तर

16

हाँ, लॉग बयान अभी भी निष्पादित किया जाएगा। यही कारण है कि यह पहली बार लॉग स्तर की जांच के लिए एक अच्छा पैटर्न है: जैसे

if (log.isInfoEnabled()) { 
    log.info("My big long info string: " + someMessage); 
} 

कुछ यह जानकारी String के लिए अंतरिक्ष पुनः दिए जब लॉग स्तर INFO बयान का समर्थन नहीं करता से रखने के लिए है।

यह कुछ भी नहीं है #ifdef - #ifdef एक संकलक निर्देश है, जबकि Log4J कॉन्फ़िगरेशन रनटाइम पर संसाधित होते हैं।

संपादित करें: मुझे अज्ञानता के कारण कमजोर होने से नफरत है, इसलिए यहां एक लेख मेरा जवाब का समर्थन कर रहा है।

http://surguy.net/articles/removing-log-messages.xml से

:

Log4J में, यदि आप डीबग स्तर पर संदेश लॉग इन करें, और केवल जानकारी स्तर के संदेशों लॉग इन करने की वर्तमान appender सेट किया गया है और इसके बाद के संस्करण है, तो संदेश नहीं होगा प्रदर्शित हों। प्रदर्शन विधि लॉग विधि को कॉल करने के लिए दंड न्यूनतम है - कुछ नैनोसेकंड। हालांकि, में विधि के तर्कों का मूल्यांकन करने में अधिक समय लग सकता है। उदाहरण के लिए:

logger.debug ("बड़ी वस्तु " + bigObject.toString());

largeObject.toString का मूल्यांकन() धीमा हो सकता है, और यह से पहले लकड़हारा करने के लिए कॉल का मूल्यांकन किया जाता है, तो लकड़हारा नहीं रोका जा सकता है कि यह मूल्यांकन किया जा रहा, भले ही यह उपयोग नहीं किया जाएगा।

संपादित 2: log4j मैनुअल ही (http://logging.apache.org/log4j/1.2/manual.html) से:

उपयोगकर्ता निम्न प्रदर्शन के मुद्दों के बारे में पता होना चाहिए।

  1. लॉगिंग बंद होने पर लॉगिंग प्रदर्शन। जब लॉगिंग पूरी तरह से या केवल स्तरों के सेट के लिए बंद हो जाती है, तो लॉग अनुरोध की लागत में एक विधि आमंत्रण और एक पूर्णांक तुलना होती है। 233 मेगाहट्र्ज पेंटियम II मशीन पर यह लागत आमतौर पर 5 से 50 नैनोसेकंद रेंज में होती है।

    हालांकि, विधि आमंत्रण में पैरामीटर निर्माण की "छिपी हुई" लागत शामिल है।

    उदाहरण के लिए, कुछ लकड़हारा बिल्ली के लिए, लेखन,

    logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); 
    

    , संदेश पैरामीटर, यानी निर्माण मैं और प्रवेश [i] एक स्ट्रिंग के लिए दोनों पूर्णांक परिवर्तित करने, और श्रृंखलाबद्ध मध्यवर्ती तार की लागत आती परवाह किए बिना क्या संदेश लॉग किया जाएगा या नहीं। पैरामीटर निर्माण की यह लागत काफी अधिक हो सकती है और यह शामिल पैरामीटर के आकार पर निर्भर करती है।

    if(logger.isDebugEnabled() { 
        logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); 
    } 
    

    यह पैरामीटर निर्माण की लागत नहीं देना होगा यदि डिबगिंग अक्षम किया गया है:

    पैरामीटर निर्माण लागत लिखने से बचने के लिए। दूसरी तरफ, अगर लॉगर डीबग-सक्षम है, तो यह मूल्यांकन करने की लागत से दोगुना होगा कि लॉगर सक्षम है या नहीं: एक बार डीबग में सक्षम और एक बार डीबग में। यह एक महत्वहीन ओवरहेड है क्योंकि लॉगर का मूल्यांकन वास्तव में लॉग इन करने में लगभग 1% लगता है।

+2

असल में यदि आपके बयान में सभी बयान कथन को लपेटना अच्छा नहीं है। लॉगिंग जितना संभव हो उतना छोटा काम होना चाहिए, यही कारण है कि आपके पास लॉगिंग फ्रेमवर्क है। इसके अलावा यदि लॉग स्टेटमेंट (गलती से) का दुष्प्रभाव है तो आप रिलीज से अलग डीबग कर देंगे। केवल तभी जब आप इसे दस लाख बार करते हैं तो आपको if जोड़ना चाहिए। यह भी संभव है कि वीएम ने पहले से ही इस कोड को अनुकूलित किया है जिसका उपयोग कभी नहीं किया जाता है। (बीटीडब्ल्यू, जिस टिप्पणी का मूल्यांकन किया गया है वह निश्चित रूप से सही है) – Thirler

+1

क्षमा करें, आप पूरी तरह से अनौपचारिक हैं। वीएम संभवतया इसे अनुकूलित नहीं कर सकता है, क्योंकि कथन प्रत्येक बार निष्पादित किया जाता है। प्रदर्शन प्रदर्शन के लिए आपको "दस लाख" लॉग स्टेटमेंट की आवश्यकता नहीं है, आपको बस एक लॉग इन स्टेटमेंट की आवश्यकता है जो लूप में है। और "लॉगिंग जितना संभव हो उतना कम काम होना चाहिए" इस संदर्भ में एक अर्थहीन बयान है - विशेष रूप से ओपी विशेष रूप से प्रदर्शन के बारे में पूछ रहा है। – danben

+0

मैं कुछ मामलों में डैनबेन से सहमत हूं। यदि आप पंक्तियों में 10 लाइनों को बड़ी तारों (या जटिल toString()) के साथ लॉग इन करना चाहते हैं, तो उन्हें एक अच्छा विचार है, तो इसे लपेटना। मुझे नहीं लगता कि डाउनवोट योग्य था। – karoberts

1
  1. log4j लॉग बयान पर कार्रवाई, और देखने के लिए अगर विशेष लकड़हारा विशेष प्रवेश स्तर पर सक्षम की जाँच करेगा। यदि ऐसा नहीं है, तो कथन लॉग नहीं किया जाएगा।

  2. ये चेक डिस्क (या कंसोल) के वास्तविक लेखन की तुलना में काफी कम महंगे हैं, लेकिन उनके पास अभी भी प्रभाव है।

  3. नहीं, जावा #ifdef जैसी कोई अवधारणा (बॉक्स से बाहर वैसे भी उसमें डेवलपर जावा प्रीकंपाइलर कर रहे हैं,)

5

मैं परीक्षण करने के लिए एक सरल बेंचमार्क भाग गया है।

for (int j = 0; j < 5; j++) { 
     long t1 = System.nanoTime()/1000000; 
     int iterations = 1000000; 
     for (int i = 0; i < iterations; i++) { 
      int test = i % 10; 
      log.debug("Test " + i + " has value " + test); 
     } 
     long t2 = System.nanoTime()/1000000; 
     log.info("elapsed time: " + (t2 - t1)); 

     long t3 = System.nanoTime()/1000000; 
     for (int i = 0; i < iterations; i++) { 
      int test = i % 10; 
      if (log.isDebugEnabled()) { 
       log.debug("Test " + i + " has value " + test); 
      } 
     } 
     long t4 = System.nanoTime()/1000000; 
     log.info("elapsed time 2: " + (t4 - t3)); 
    } 

elapsed time: 539 
elapsed time 2: 17 
elapsed time: 450 
elapsed time 2: 18 
elapsed time: 454 
elapsed time 2: 19 
elapsed time: 454 
elapsed time 2: 17 
elapsed time: 450 
elapsed time 2: 19 

1.6.0_18 के साथ, जो मुझे आश्चर्यचकित करता था क्योंकि मैंने सोचा था कि इनलाइनिंग ने इसे रोक दिया होगा। शायद बचने के विश्लेषण के साथ जावा 7 होगा।

हालांकि मैं अभी भी अगर किसी भी खंड में डीबग कथन लपेट नहीं लेता, तब तक आधे माइक्रोसॉन्ड के आदेश में समय सुधार महत्वपूर्ण नहीं होता है!

संबंधित मुद्दे