2012-12-11 10 views
6

मेरे पास एक विशेष लॉगर क्लास है जो java.util.logging.Logger कक्षा का उपयोग करती है। मैं इस लॉगर को किसी अन्य वर्ग के शटडाउन हुक में उपयोग करने में सक्षम होना चाहता हूं। हालांकि, ऐसा लगता है कि शटडाउन पर लॉग ऑन नहीं है। जो मैंने पढ़ा है, वहां से पहले से ही शटरडाउन हुक लॉगर के लिए सक्रिय हो सकता है जो इस मुद्दे को जन्म दे रहा है।जावा- शटडाउन हुक में काम करने के लिए लॉगर कैसे प्राप्त करें?

मैं इसे काम करने के लिए कैसे प्राप्त कर सकता हूं? आदर्श रूप में, मैं इसे लॉग फ़ाइल में देखना चाहता हूं कि वास्तव में प्रक्रिया समाप्त होने पर मैंने शटडाउन हुक निष्पादित किया था।

+0

मुझे यकीन नहीं है कि यह सच है या नहीं, लेकिन आपके पास शटडाउन हुक होने के क्रम पर कोई नियंत्रण नहीं है। –

+1

यह सच है, वे [समवर्ती] चलाते हैं (http://docs.oracle.com/javase/1.5.0/docs/guide/lang/hook-design.html) –

उत्तर

8

फिर स्रोत पर देख रहे हैं, समाधान एक प्रणाली संपत्ति java.util.logging.manager जो LogManager का एक उपवर्ग जो reset(); विधि ओवरराइड करता है तो संग्रह करने वालों शटडाउन पर काम करना जारी है परिभाषित करने के लिए प्रतीत होता है।

import java.util.logging.LogManager; 
import java.util.logging.Logger; 

public class Main { 
    static { 
     // must be called before any Logger method is used. 
     System.setProperty("java.util.logging.manager", MyLogManager.class.getName()); 
    } 

    public static class MyLogManager extends LogManager { 
     static MyLogManager instance; 
     public MyLogManager() { instance = this; } 
     @Override public void reset() { /* don't reset yet. */ } 
     private void reset0() { super.reset(); } 
     public static void resetFinally() { instance.reset0(); } 
    } 

    public static void main(String... args) { 
     Logger logger1 = Logger.getLogger("Main1"); 
     logger1.info("Before shutdown"); 
     Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Logger logger2 = Logger.getLogger("Main2"); 
        logger2.info("Shutting down 2"); 

       } finally { 
        MyLogManager.resetFinally(); 
       } 
      } 
     })); 
    } 
} 

प्रिंट

Dec 11, 2012 5:56:55 PM Main main 
INFO: Before shutdown 
Dec 11, 2012 5:56:55 PM Main$1 run 
INFO: Shutting down 2 

LogManager के लिए इस कोड से, आप देख ही बंद हुक जो संचालकों dismantles और उन्हें बंद कर देता है वहाँ देख सकते हैं। लॉगर केवल शट डाउन में काम करता है अगर इसका उपयोग पहले नहीं किया गया है, इसलिए यह कोड नहीं चला है।

// This private class is used as a shutdown hook. 
// It does a "reset" to close all open handlers. 
private class Cleaner extends Thread { 

    private Cleaner() { 
     /* Set context class loader to null in order to avoid 
     * keeping a strong reference to an application classloader. 
     */ 
     this.setContextClassLoader(null); 
    } 

    public void run() { 
     // This is to ensure the LogManager.<clinit> is completed 
     // before synchronized block. Otherwise deadlocks are possible. 
     LogManager mgr = manager; 

     // If the global handlers haven't been initialized yet, we 
     // don't want to initialize them just so we can close them! 
     synchronized (LogManager.this) { 
      // Note that death is imminent. 
      deathImminent = true; 
      initializedGlobalHandlers = true; 
     } 

     // Do a reset to close all active handlers. 
     reset(); 
    } 
} 


/** 
* Protected constructor. This is protected so that container applications 
* (such as J2EE containers) can subclass the object. It is non-public as 
* it is intended that there only be one LogManager object, whose value is 
* retrieved by calling Logmanager.getLogManager. 
*/ 
protected LogManager() { 
    // Add a shutdown hook to close the global handlers. 
    try { 
     Runtime.getRuntime().addShutdownHook(new Cleaner()); 
    } catch (IllegalStateException e) { 
     // If the VM is already shutting down, 
     // We do not need to register shutdownHook. 
    } 
} 

मेरे अपने परीक्षण से

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      Logger logger2 = Logger.getLogger("Main2"); 
      logger2.info("Shutting down 2"); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
    } 
})); 

प्रिंट

Dec 11, 2012 5:40:15 PM Main$1 run 
INFO: Shutting down 2 

लेकिन अगर आप इस ब्लॉक के बाहर

Logger logger1 = Logger.getLogger("Main1"); 

जोड़ने आप कुछ भी नहीं मिलता है।

+1

यहां तक ​​कि 'Logger.getLogger (नाम) का उपयोग करके भी मुझे अपने लॉग में मुद्रित कुछ भी दिखाई नहीं देता है। हालांकि, सिस्टम प्रॉपर्टी को सेट करना और MyLogManager कोड पर कॉपी करना मैं इसे काम करने में सक्षम था।सुन्दर, शुक्रिया! – Marianna

1

क्या शट डाउन हुक का कोई फायदा है? को छोड़कर जब वी एम दुर्घटनाओं लेकिन फिर बंद हुक निष्पादित नहीं किया जाएगा, भी अंत में ब्लॉक सभी मामलों में निष्पादित किया जाएगा, :

बेहतर होगा कि तुम, अंतिम पंक्ति में प्रवेश करें उत्पादन मुख्य में जोड़ें।

static void main(String[] argv) { 

    try { 
    startApp(); 
    } finally { 
    LOGGER.info("shudown"); 
    } 
} 
+0

मेरी प्रक्रिया वह है जो पूरे दिन लाइव होती है - बैठने और कुछ होने की प्रतीक्षा कर रहा है। एक और काम की जाने वाली चीज़ नहीं है जहां मैं कोड के अंत में जो कुछ भी कर सकता हूं उसे बस रख सकता हूं। मुझे विश्वास है कि शटडाउन हुक सही समाधान – Marianna

+1

है, ऐसा लगता है कि आप नहीं जानते कि कोड का अंत कहां है? आपको यह पता होना चाहिए, और पता लगाना चाहिए। इसका एक शॉट से कोई लेना देना नहीं है! हमारा sw शटडाउन के बिना हफ्तों तक चलता है, लेकिन हम जानते हैं कि अंत कहां है। हो सकता है कि वसंत या अन्य ढांचे का उपयोग करके यह थोड़ा मुश्किल हो। लेकिन आपको साफ करने के बारे में पता होना चाहिए, क्योंकि अक्सर एक आदेश दिया गया shutdoiwn आवश्यक है! लॉजिंग को शटडाउन हैंडलर की आवश्यकता क्यों है कि यह एक lib है और "कोड के अंत" को दोहरा नहीं सकता है – AlexWien

+0

प्रक्रिया अपने आप से बाहर नहीं निकलती है, इसी प्रकार कोई तार्किक अंत नहीं होता है। – Marianna

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