2012-02-18 9 views
13

हम एक दिलचस्प मुद्दे में भाग रहे हैं जिसे हमने हमारे सिस्टम के तनाव परीक्षण करते समय देखा। हम log4j (जेबीओएसएस में) का उपयोग कर रहे हैं हमारे लॉगिंग के लिए बहुत भारी है। यहाँ कुछ लॉगिंग हम एवेन्यूLog4j: क्या यह मल्टीथ्रेड कॉल के लिए सिंक्रनाइज़ किया गया है?

void someFunction() 
{ 
Log.info("entered some function"); 
... 

Log.info("existed some function"); 
} 

के एक अनुभवहीन उदाहरण है अब दिलचस्प बात यह हमने देखा है कि अगर हम इस समारोह के खिलाफ 100 धागे का शुभारंभ; Log.info() कॉल प्रति थ्रेड को अवरुद्ध कर रहा है .. जिसका अर्थ है थ्रेड 2 थ्रेड 1 के लिए "Log.info" कॉल को समाप्त करने का इंतजार कर रहा है। थ्रेड 100 के मामले में; यह काफी लंबे समय तक इंतजार कर रहा है .. हम मूल फ़ाइल लॉगर का उपयोग कर रहे हैं।

क्या यह ज्ञात मुद्दा है?

Asynchronous logging with log4j

इसके अलावा, सही लॉग स्तरों का उपयोग करें:

+0

'लॉग' एक कक्षा है? या 'लॉगर' प्रकार का ऑब्जेक्ट? – Tudor

+0

लॉग लॉगरफ़ैक्टरी – shergill

+0

से प्राप्त प्रकार लॉगर का ऑब्जेक्ट ठीक है धन्यवाद। बस सुनिश्चित करना चाहता था। मैं 'लॉगर' के स्रोत कोड के बावजूद जा रहा था और पाया कि वास्तव में वहां 'सिंक्रनाइज़' अनुभाग है। – Tudor

उत्तर

2

तुम क्या चाहते हो सकता है अतुल्यकालिक प्रवेश है, कैसे है कि प्राप्त करने के लिए पर यह लेख देखें। entered... और exi(s)ted... कथन आमतौर पर TRACE स्तर पर लॉग इन होना चाहिए, जो डिबगिंग के दौरान आसान हो सकता है (फिर TRACE स्तर पर लॉग इन करने के लिए लॉग 4j कॉन्फ़िगर करें)। एक उत्पादन सेटिंग में आप केवल लॉग 0j को स्तर INFO या DEBUG से लॉग इन करना चाहते हैं, इस प्रकार अनावश्यक लॉग क्रियाओं से परहेज कर सकते हैं।

log4j के प्रदर्शन पर भी इस सवाल देखें:

log4j performance

+0

लिंक काम नहीं करता –

+0

धन्यवाद, लिंक –

10

Log4J सिंक्रनाइज़ किया जाना है, अन्यथा आप अपनी फ़ाइल में interleaved और विकृत लॉग संदेशों देखना होगा। लेकिन कम से कम लॉगबैक में केवल परिशिष्ट सिंक्रनाइज़ होते हैं, पूरे लॉगिंग संदेश नहीं (इसलिए कंप्यूटिंग प्रभावी लॉग स्तर, लॉग संदेश इत्यादि बहु-थ्रेडेड हैं)।

हालांकि सिंक्रनाइज़ेशन हटा दिए जाने पर भी, I/O बाधा होगी क्योंकि यह मूल रूप से सिंगल-थ्रेडेड है। इस प्रकार लॉगिंग की मात्रा को कम करने पर विचार करें, क्योंकि यह फ़ाइल एक्सेस है जो धीमी है, लॉग 4 जे नहीं।

आपको AsyncAppender में भी एक ही, अलग थ्रेड में लॉगिंग संदेशों को कतार में रुचि हो सकती है।

+2

+1 अपडेट किया गया - एक बात जो मुझे लगता है वह उल्लेखनीय है एसिंक दृष्टिकोण के साथ व्यापार-बंद है; आपको गारंटी नहीं है कि सभी लॉगिंग ने इसे किसी प्रक्रिया या सिस्टम क्रैश के मामले में डिस्क पर बना दिया है –

+0

मुझे यकीन नहीं है कि मैं AsyncAppender को समझता हूं। लॉगिंग वास्तव में 'asynchornous' नहीं है .. मतलब एक अलग धागे में हो रहा है? ऊपर मेरे उदाहरण में मतलब; जब मैं "Log.Info (" abc ") कहता हूं; यह वास्तव में फ़ाइल में तुरंत लिखता नहीं है .. ऐसा लगता है कि देरी हो रही है? – shergill

+0

@shegill, हाँ यह देरी हो रही है। इसे AsyncAppender में इससे पहले बफर किया गया है प्रतिनिधि अभ्यर्थियों को भेजा जाता है। सिस्टम क्रैश की स्थिति में लॉग संदेशों को खोने के बारे में ब्रायन की चेतावनी का यही कारण है; यदि आप अपने लॉग इन प्रत्येक लॉग संदेश के बाद डिस्क पर फ्लश नहीं कर रहे हैं तो आप एक ही खतरे को चलाते हैं। – Victor

1

दूसरों को पहले से ही आप विकल्प का सुझाव दिया है, मैं स्रोत कोड के माध्यम से खुदाई कर रहा है और वास्तव में वहाँ एक synchronized अनुभाग है:

public void info(Object message) { 
    if(repository.isDisabled(Level.INFO_INT)) 
     return; 
    if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel())) 
     forcedLog(FQCN, Level.INFO, message, null); 
} 

... 

protected void forcedLog(String fqcn, Priority level, Object message, Throwable t) { 
    callAppenders(new LoggingEvent(fqcn, this, level, message, t)); 
} 

... 

public void callAppenders(LoggingEvent event) { 
    int writes = 0; 

    for(Category c = this; c != null; c=c.parent) { 
     // Protected against simultaneous call to addAppender, removeAppender,... 
     synchronized(c) { 
      if(c.aai != null) { 
       writes += c.aai.appendLoopOnAppenders(event); 
      } 
      if(!c.additive) { 
       break; 
      } 
     } 
    } 

    if(writes == 0) { 
     repository.emitNoAppenderWarning(this); 
    } 
} 
1

हाँ, log4j multithread syncronyzation उपयोग करता है। और कभी नहीं, कभी-कभी।

हमने log4j ताले और जटिल toString() विधि के उपयोग के साथ भी deadlocks के लिए विवाद के कारण कुछ प्रदर्शन गिरावट का अनुभव किया था।

उदाहरण के लिए https://issues.apache.org/bugzilla/show_bug.cgi?id=24159 और https://issues.apache.org/bugzilla/show_bug.cgi?id=41214#c38 देखें।मेरी एक और जवाब में

अधिक विवरण: Production settings file for log4j?

मुझे लगता है कि इस logback अस्तित्व के कारणों में से एक है और के रूप में 6.

-4

JBoss के बाद से कस्टम logmanager करने के लिए स्विच पिछले जवाब के साथ सहमत हूँ। किसी भी एप्लिकेशन में पहले प्रदर्शन सुधार चरणों में से एक लॉग स्तर को कम करना है और इसे कम लॉग डंप करना है। आवेदन डेवलपर्स सही लॉगिंग स्तरों का उपयोग करने में मेहनती होना चाहिए। लॉगिंग का प्रदर्शन I/O के साथ-साथ सिंक्रनाइज़ेशन के कारण प्रदर्शन पर एक बड़ा प्रभाव पड़ता है, खासकर जब लॉगर ऑब्जेक्ट स्थिर होते हैं और विभिन्न धागे के बीच साझा होते हैं।

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