2010-10-01 18 views
81

क्या लॉगर को स्थिर घोषित किया जाना चाहिए या नहीं?क्या लॉगर निजी स्थिर होना चाहिए या

 
    protected Log log = new Log4JLogger(aClass.class); 

या

 
    private static Log log = new Log4JLogger(aClass.class); 

कौन सा प्रयोग किया जाना चाहिए: आमतौर पर मैं एक लकड़हारा के लिए घोषणा के दो प्रकार देखा है? दोनों के प्रो और कॉन क्या हैं?

protected Log log = new Log4JLogger(getClass()); 

हालांकि इसके नुकसान जाहिर है वह यह है कि:

+1

लॉगिंग एक क्रॉस-काटने की चिंता है। पहलुओं का प्रयोग करें और सवाल मंथन है। –

+2

'स्थिर 'प्रति वर्ग एक संदर्भ है। गैर स्थैतिक ** प्रति उदाहरण एक संदर्भ ** (+ प्रारंभिकरण) है। तो कुछ मामलों में, यदि आपके पास कई उदाहरण हैं तो उत्तरार्द्ध एक महत्वपूर्ण स्मृति प्रभाव पर आता है। एक * लगातार * ऑब्जेक्ट में गैर स्थैतिक का कभी भी उपयोग न करें। मैं हमेशा स्थिर संस्करण का उपयोग करता हूं। (जो * अपरकेज्ड * 'LOG' होना चाहिए) –

+0

यदि आप [jcabi-log] (http://www.jcabi.com/jcabi-log/) का उपयोग करते हैं, तो आप इस वैरिएबल से छुटकारा पा सकते हैं, एक स्थिर रैपर slf4j – yegor256

उत्तर

83

गैर स्थिर प्रपत्र का लाभ यह है कि आप चिंता है कि सही classname उपयोग किया जाएगा के बिना इस प्रकार की तरह एक (सार) आधार वर्ग में यह घोषणा कर सकते हैं है कक्षा के हर उदाहरण के लिए एक नया नया लॉगर उदाहरण बनाया जाएगा। यह महंगा नहीं हो सकता है, लेकिन यह एक महत्वपूर्ण ओवरहेड जोड़ता है। यदि आप इससे बचना चाहते हैं, तो आप इसके बजाय static फॉर्म का उपयोग करना चाहेंगे। लेकिन इसका नुकसान बदले में है कि आपको इसे प्रत्येक वर्ग में घोषित करना होगा और प्रत्येक वर्ग में देखभाल करना होगा कि दाएं वर्गनाम का उपयोग लॉगर के निर्माण के दौरान किया जाता है क्योंकि getClass() स्थिर संदर्भ में उपयोग नहीं किया जा सकता है। हालांकि, औसत आईडीई में आप इसके लिए एक स्वत: पूर्ण टेम्पलेट बना सकते हैं। जैसे logger + ctrl+space

दूसरी ओर, यदि आप एक कारखाना है जो बदले में पहले से ही instantiated वालों को संचित कर सकता है, तो गैर स्थिर फ़ॉर्म का उपयोग करके कि ज्यादा भूमि के ऊपर नहीं जोड़ेगा द्वारा लकड़हारा प्राप्त करते हैं। उदाहरण के लिए Log4j इस उद्देश्य के लिए LogManager है। नियंत्रण से

protected Log log = LogManager.getLogger(getClass()); 
+5

अमूर्त वर्ग में 'अमूर्त लॉग getLogger(); 'घोषित करें। इस विधि को लागू करें, विशेष उदाहरण के लिए स्थैतिक लॉगर लौटाएं। 'निजी अंतिम स्थैतिक लॉग LOG = LogManager.getLogger (Clazz.class) जोड़ें; 'अपने आईडीई क्लास टेम्पलेट में। –

+2

slf4j के लिए: 'संरक्षित लॉगर लॉग = LoggerFactory.getLogger (getClass()); ' –

+0

@BalusC GetLass विधि को getClass() से गुजरने में समस्या यह है कि यह वर्तमान उदाहरण की कक्षा देता है। आम तौर पर यह वांछित है कि लॉगिंग कक्षा के साथ जुड़ा हुआ है जहां कोड है। उदाहरण के लिए यदि लॉगिंग कोड कक्षा अभिभावक में है तो हम चाहते हैं कि लॉगिंग को अभिभावक से जोड़ा जाए, भले ही निष्पादन उदाहरण है और कक्षा के बच्चे का उदाहरण जो माता-पिता का उप-वर्ग है। GetClass() के साथ यह बच्चे से जुड़ा होगा, गलत – inor

2

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

+2

यूनिट परीक्षण जो लॉगिंग की जांच कर रहे हैं, वे बेकार और अविश्वसनीय रूप से भंगुर दोनों ध्वनि उत्पन्न कर रहे हैं। – Michael

+0

परीक्षण के तहत सिस्टम के आधार पर उपयोगिता। कभी-कभी लॉगिंग वह है जो आपके पास है। –

+0

@Wayne एलन जब आप यूनिट परीक्षण कर रहे हैं, परिभाषा के अनुसार, आपके पास परीक्षा परिणाम भी हैं। क्या आप ऐसी स्थिति का सुझाव दे रहे हैं जिसमें कोई यूनिट टेस्ट करता है लेकिन परीक्षण के नतीजे नहीं होते? केवल लॉग है? – inor

12

सबसे महत्वपूर्ण अंतर यह है कि यह आपकी लॉग फ़ाइलों को कैसे प्रभावित करता है: किस श्रेणी में लॉग जाते हैं?

  • अपनी पहली पसंद में, एक उपवर्ग के लॉग सुपर क्लास की श्रेणी में खत्म। यह मेरे लिए बहुत उलझन में प्रतीत होता है।
  • अपने पहले मामले का एक प्रकार है:

    संरक्षित लॉग लोग इन = नए Log4JLogger (getClass());

    उस स्थिति में, आपकी लॉग श्रेणी कहती है कि लॉग ऑन करने वाले कोड पर कौन सा ऑब्जेक्ट काम कर रहा था।

  • आपकी दूसरी पसंद (निजी स्थैतिक) में, लॉग श्रेणी वह कक्षा है जिसमें लॉगिंग कोड होता है। तो आम तौर पर कक्षा जो लॉगिंग की जा रही चीज कर रही है।

मैं दृढ़ विकल्प की दृढ़ता से अनुशंसा करता हूं। अन्य समाधानों की तुलना में इन फायदे हैं:

  • लॉग और कोड के बीच सीधा संबंध है। यह पता लगाना आसान है कि एक लॉग संदेश कहां से आया था।
  • यदि किसी को लॉगिंग स्तर (जो प्रति श्रेणी किया जाता है) को ट्यून करना है, तो आमतौर पर ऐसा होता है क्योंकि किसी विशेष वर्ग द्वारा लिखे गए कुछ विशेष संदेशों में वे रुचि रखते हैं (या नहीं)।यदि श्रेणी संदेश लिखने वाली कक्षा नहीं है, तो स्तरों को ट्यून करना कठिन होता है।
  • आप स्थैतिक तरीकों में लॉग इन कर सकते हैं
  • लॉगर्स केवल प्रति कक्षा में एक बार प्रारंभ (या देखा) की आवश्यकता है, इसलिए स्टार्टअप पर, प्रत्येक इंस्टेंस के लिए बनाया गया है।

    • यह जरूरत है कि हर वर्ग में घोषित किया जाना है, जहां आप संदेश (सुपर क्लास वालों का पुन: उपयोग नहीं) लॉग इन करें:

    यह भी नुकसान है।

  • लॉगर को प्रारंभ करते समय आपको सही वर्गनाम डालने की देखभाल करने की आवश्यकता है। (लेकिन अच्छी आईडीई आपके लिए इसका ख्याल रखती है)।
38

मुझे लगता था कि सभी लॉगर्स स्थिर होना चाहिए; हालांकि, this article at wiki.apache.org क्लासलोडर लीक के संबंध में कुछ महत्वपूर्ण स्मृति चिंताओं को सामने लाता है। स्थैतिक के रूप में एक लॉगर घोषित करने से घोषित वर्ग (और संबंधित क्लासलोडर्स) को जे 2 ईई कंटेनरों में एकत्रित कचरा होने से रोकता है जो साझा क्लासलोडर का उपयोग करता है। यदि आप अपने आवेदन को पर्याप्त समय में पुन: नियोजित करते हैं तो इसके परिणामस्वरूप PermGen त्रुटियां होंगी।

लॉगर्स को गैर स्थैतिक घोषित करने के अलावा, मुझे इस क्लासलोडर रिसाव मुद्दे के आसपास काम करने का कोई तरीका नहीं दिखता है।

+4

मुझे संदेह है कि स्थिर क्षेत्र में स्मृति रिसाव की समस्या भी होगी। अन्य स्थैतिक के रूप में गैर स्थैतिक प्रदर्शन समस्या हो सकती है। तब आदर्श तरीका क्या है? – liang

+0

लेख आपको संदर्भित में वर्णित मुख्य समस्या @piepera प्रत्येक आवेदन में लॉगिंग स्तर नियंत्रित करने की क्षमता है जब "मामले पर विचार जब एक वर्ग का उपयोग कर" निजी स्थिर लॉग लॉग = "एक classloader कई के वंश में है कि के माध्यम से तैनात किया जाता है है माना जाता है कि स्वतंत्र "अनुप्रयोग" "। मुझे यह नहीं लगता कि एक समस्या के रूप में क्योंकि इस विशेष परिस्थिति में अनुप्रयोगों का "सामान्य आधार" होता है और उस "सामान्य जमीन" में कक्षा के लिए लॉगिंग स्तर तय होता है और हाँ, यह सभी आवेदकों के लिए रहता है ... लेकिन रखें ध्यान रखें कि यह वर्ग इन अनुप्रयोगों के बाहर [लोड] है – inor

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