2010-06-17 9 views
16

लॉग 4j में, BufferedIO = true और BufferSize = xxx गुणों (यानी बफरिंग सक्षम है) के साथ फ़ाइल एपेंडर का उपयोग करते समय, मैं सामान्य शट डाउन प्रक्रिया के दौरान लॉग को फ़्लश करने में सक्षम होना चाहता हूं। इसे कैसे करना है इस पर कोई आइडिया?आप buffered log4j FileAppender को कैसे फ़्लश करते हैं?

+0

लॉग 4 जे सामान्य शटडाउन के दौरान स्वचालित रूप से एपेंडर को फ्लश नहीं करता है? मैं कम से कम ऐसा करने की उम्मीद करता हूं। –

+1

जैसा कि मैं कोड को समझता हूं - जब आप BufferedIO के लिए निर्णय लेते हैं तो कोई फ्लशिंग नहीं होती है। आप प्रदर्शन प्राप्त करते हैं लेकिन कीमत का भुगतान करते हैं: आप अंतिम लॉग प्रविष्टियों को खो देंगे ... –

+0

जब मैंने अपना स्वयं का एपेंडर लिखा (डीबी में, लेकिन वास्तव में कोई फर्क नहीं पड़ता), तो मैंने प्रत्येक कुछ सेकंड स्वचालित रूप से फ़्लश करते समय आउटपुट buffered किया। – ripper234

उत्तर

6
public static void flushAllLogs() 
{ 
    try 
    { 
     Set<FileAppender> flushedFileAppenders = new HashSet<FileAppender>(); 
     Enumeration currentLoggers = LogManager.getLoggerRepository().getCurrentLoggers(); 
     while(currentLoggers.hasMoreElements()) 
     { 
      Object nextLogger = currentLoggers.nextElement(); 
      if(nextLogger instanceof Logger) 
      { 
       Logger currentLogger = (Logger) nextLogger; 
       Enumeration allAppenders = currentLogger.getAllAppenders(); 
       while(allAppenders.hasMoreElements()) 
       { 
        Object nextElement = allAppenders.nextElement(); 
        if(nextElement instanceof FileAppender) 
        { 
         FileAppender fileAppender = (FileAppender) nextElement; 
         if(!flushedFileAppenders.contains(fileAppender) && !fileAppender.getImmediateFlush()) 
         { 
          flushedFileAppenders.add(fileAppender); 
          //log.info("Appender "+fileAppender.getName()+" is not doing immediateFlush "); 
          fileAppender.setImmediateFlush(true); 
          currentLogger.info("FLUSH"); 
          fileAppender.setImmediateFlush(false); 
         } 
         else 
         { 
          //log.info("fileAppender"+fileAppender.getName()+" is doing immediateFlush"); 
         } 
        } 
       } 
      } 
     } 
    } 
    catch(RuntimeException e) 
    { 
     log.error("Failed flushing logs",e); 
    } 
} 
+0

काम पूरा करने के लिए लगता है। धन्यवाद! – Amos

+0

यह सभी लॉगर्स फ्लश नहीं करता है। सभी को फ्लश करने के लिए, आपको प्रत्येक लॉगर पर getParent() को कॉल करने की आवश्यकता है और इन लॉगर्स को भी फ्लश करें। – h22

0

प्रयास करें:

LogManager.shutdown(); 

सभी बफ़र लॉग प्लावित मिलती है:

LogFactory.releaseAll(); 
+1

बुलाकर इसका कोई प्रभाव नहीं पड़ा, दुर्भाग्य से। – Amos

35

:-)

जब LogManager नीचे बंद अपने ही सवाल का जवाब देने प्रबंधित।

+6

कृपया इसे उत्तर के रूप में चुनें - यह स्पष्ट रूप से सबसे अच्छा विकल्प है। अगर आपने इसे अर्जित किया है तो किसी से हरे रंग की टिक निकालने के बारे में बुरा मत समझो। –

+0

यह सबसे अच्छा जवाब जैसा दिखता है ... लेकिन आप इस "LogManager" ऑब्जेक्ट को कैसे एक्सेस करते हैं? (log4php novice) –

1

शायद तुम, WriterAppender#shouldFlush(LoggingEvent) रद्द कर सकते थे तो यह एक विशेष प्रवेश वर्ग के लिए true वापसी होगी, log4j.flush.now की तरह, और फिर आप फोन:

LoggerFactory.getLogger("log4j.flush.now").info("Flush") 

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/WriterAppender.html#shouldFlush%28org.apache.log4j.spi.LoggingEvent%29

0

मैं एक appender लिखा है कि इसे ठीक करता है, GitHub देखें या name.wramner.log4j का उपयोग करें: मेवेन में फ्लशएपेंडर। इसे उच्च गंभीरता वाले कार्यक्रमों पर फ़्लश करने के लिए कॉन्फ़िगर किया जा सकता है और यह ऐपेंडर्स को एक विशिष्ट संदेश प्राप्त करने पर अनबफर कर सकता है, उदाहरण के लिए "शट डाउन"। कॉन्फ़िगरेशन उदाहरणों के लिए यूनिट परीक्षणों की जांच करें। यह निश्चित रूप से मुफ़्त है।

3
public static void flushAll() { 
    final LoggerContext logCtx = ((LoggerContext) LogManager.getContext()); 
    for(final org.apache.logging.log4j.core.Logger logger : logCtx.getLoggers()) { 
     for(final Appender appender : logger.getAppenders().values()) { 
      if(appender instanceof AbstractOutputStreamAppender) { 
       ((AbstractOutputStreamAppender) appender).getManager().flush(); 
      } 
     } 
    } 
} 
+0

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, इस बारे में अतिरिक्त संदर्भ प्रदान करता है कि यह कैसे और/या समस्या का समाधान क्यों करता है, इसका उत्तर उत्तर के दीर्घकालिक मूल्य में सुधार होगा। –

+0

यह कोड बस सभी फ्लश करने योग्य एपेंडर (सभी एपेंडर्स सार तत्वऑटपुटस्ट्रीमएपेंडर को विस्तारित करने की कोशिश करता है, जहां विधि "फ्लश" घोषित की जाती है)। मेरी परियोजना में Log4J2 v2.8.2 के साथ इसका उपयोग करना। –