2010-02-26 13 views
19

Şu anda Tomcat, Spring ve JAVA kullanarak bir uygulama yapıyorum. Günlük kitaplığım olarak Log4J kullanıyorum. Şu anda her şeyi bir metin dosyasına kaydediyorum. Yaşadığım sorunlardan biri RuntimeExceptions'un herhangi bir dosyada kayıtlı olmamasıdır. Belki de benim uygulama günlüğü dosyasına atılan tüm RuntimeExceptions günlüğünü kaydetmenin bir yolu olup olmadığını merak ediyordum. Eğer değilse başka bir günlük dosyasına giriş yapmak mümkün mü? Bunu yapmanın standart bir yolu var mı? Öyleyse, uygulamanızı Tomcat içinde çalıştırırken bunu yapmak için standart bir yol var mı?Günlük çalışma zamanı Java kullanarak log4j'deki istisnalar

Yardımlarınız için şimdiden teşekkür ederiz!

+2

siz "yakalanmamış" RuntimeExceptions ifade ediyor mu? –

+0

Evet "uncaught" demek istedim RuntimeExceptions – DkS

cevap

21

Aradığınızı istediğinizden emin değilim, ancak iş parçacıklarını sonlandıran istisnalar için bir işleyici var. İş parçacığının hedefi tarafından açıkça yakalanmayan herhangi bir özel durum için bir işleyicidir.

Varsayılan "yakalanmamış özel durum işleyici", numaralı yığınta numaralı çağrıları yığın yığınını System.err olarak yazdırmak için çağırır. Ancak, yapabilirsin replace yerine log4j için istisna kaydeder kendi UncaughtExceptionHandler ile bu:

class Log4jBackstop implements Thread.UncaughtExceptionHandler { 

    private static Logger log = Logger.getLogger(Log4jBackstop.class); 

    public void uncaughtException(Thread t, Throwable ex) { 
    log.error("Uncaught exception in thread: " + t.getName(), ex); 
    } 

} 

bir infaz çerçeve kullanıyorsanız hangi bir Runnable nesnesi geçirmek için, onun ipler muhtemelen önlemek kendi catch blok var yakalanmamış istisna işleyicisine ulaşmanın istisnaları. Orada Runtime durumları yakalamak istiyorsanız, yapmanın bir yolu böyle bir günlüğü ambalajında ​​her görevi sarmak için geçerli:

class Log4jWrapper { 

    private final Logger log; 

    private final Runnable target; 

    Log4jWrapper(Logger log, Runnable target) { 
    this.log = Objects.requireNonNull(log); 
    this.target = Objects.requireNonNull(target); 
    } 

    public void run() { 
    try { 
     target.run(); 
    } catch(RuntimeException ex) { 
     log.error("Uncaught exception.", ex); 
     throw ex; 
    } 
    } 

} 

... 

Runnable realTask = ...; 
executor.submit(new Log4jWrapper(Logger.getLogger(Whatever.class), realTask)); 
+0

Bu normalde bu RuntimeExceptions uygulamalarda nasıl kullanılır? Sanırım bunun bununla ilgili standart bir yol olup olmadığını merak ediyorum. – DkS

+0

Ayrıca Spring API'dan ThreadPoolTaskExecutor kullanıyorum, bu hala bu sınıf kullanılarak yapılabilecek bir şey mi? – DkS

+0

Runnable'da bir RuntimeException varsa, bu harika çalışır, ancak ThreadPoolTaskExecutor ile bir özel durum varsa ne olur? Havuzun doğru şekilde yapılandırıldığı için bir RunTimeException attığını söyleyin. Bu hala konsola yazdırılacak ve oturum açılmayacaktır .... herhangi bir öneri? – DkS

1

Kaydedicinizi kullanmak için StdErr'i yeniden yönlendirmeyi deneyebilirsiniz. Bu, sizin std err'inize yazılan herhangi bir sonucun sonucunu vermelidir (işlenmeyen özel durumlar dahil edilmelidir)

Bu blog yazısı, yeniden yönlendirme işleminin, dosyalayıcınızın dışında bir FileHandler'a nasıl yapıldığına dair iyi bir bilgi vermektedir. yakalanmamış RuntimeExceptions (ya da bu konuda herhangi yakalanmamış Throwables) günlüğe

https://blogs.oracle.com/nickstephen/entry/java_redirecting_system_out_and

12

bir yolu Thread.UncaughtExceptionHandler uygulayan bir sınıf yaratmaktır. Bu sınıfın uncaughtException() yöntemi, yalnızca özel durum ayrıntılarını günlüğe yazar. Sen JVM görüşme yakalanmamış RuntimeException kodunuzu satır

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler()); 

ekleyerek iş parçacığı sonlandırır zaman bu durum işleyici yapabilirsiniz.