2013-07-01 18 views
11

Log4j2 ayrıca hizmetlerini sonlandırmak için kapatma kancalarını kullanır. Ama tabii ki başvurumun tüm yaşam döngüsü boyunca kayıt olmak istiyorum - kapatma dahil. Log4j ile bu sorun değildi. Şimdi imkansız görünüyor. Uygulamam hala üzerinde çalışırken günlüğe kaydetme kapatılıyor. Benim için biraz umut var mı?Log4j2 ile kapatma kancaları nasıl kaydedilir?

Saygılarımızla Martin

bu

<configuration ... shutdownHook="disable"> 

onun artık engelli göz önüne alındığında, ben sonunda elle kapatma günlüğü sistemi gerek sanırım xml şimdi yapılandırılabilir 2.0-beta9 itibariyle

+0

Günlüğe kaydetme, veya kapatma kancalarındaki diğer servislere bağlı olarak, kötü bir uygulama olmuştur ve şimdi size yetişmektedir. –

+0

@MarkoTopolnik Eğer dediğiniz gibi kötü bir uygulama ise, bir kapatma kanca dişi çıkışının kayıt/günlüğe kaydetmesi gerekiyorsa ne yapılmasını önerirsiniz? – vegemite4me

+0

Kapanış kanadında, başlangıç ​​durumuna getirilmiş durumun herhangi bir parçasına hala sahip olamayacağınız için, yarı güvenilir olarak gördüğüm tek şey, bir dosya oluşturan ve ona yazılan tamamen kendi kendine yeten bir kod parçasıdır. Bir çekirdek dökümü yapıldığı gibi. –

cevap

19

benim kapatma kancası. Ancak yalnızca iç API

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.core.config.Configurator; 
import org.apache.logging.log4j.core.LoggerContext; 
... 

public static void main(String[] args) { 
    final AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class) 

    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      //shutdown application 
      LOG.info("Shutting down spring context"); 
      springContext.close(); 

      //shutdown log4j2 
      if(LogManager.getContext() instanceof LoggerContext) { 
       logger.info("Shutting down log4j2"); 
       Configurator.shutdown((LoggerContext)LogManager.getContext()); 
      } else 
       logger.warn("Unable to shutdown log4j2"); 
     } 
    }); 

    //more application initialization 
} 
+0

bunu hiç anladın mı? – user671731

+1

Sorun şu ki, Java'nın kapatma kancaları paralel olarak başlatılıyor. Bu yüzden, gerçekten de, sadece kancalarınızı verilen Runtime.getRuntime(). AddShutdownHook (Thread) -API'ye eklemekten kaçınmanız için her yere giriş yapabildiğinizden emin olun, ancak herşey bittikten sonra log4j 2.0'ı el ile durduran kendi iş akışınızı oluşturun. Ancak Log4j, shutdownHook-tetikleyiciyi sunarken ana sorun çözüldü. – Martin

+0

Kendi iş akışınızı oluşturmanız gerektiğini kabul ediyorum. Normalde uygulamanızı linux üzerinde çalıştırıyorum ve JVM'ye bir sinyal aracılığıyla kapatacağım, bu nedenle bir kapatma kancası bu amaç için uygun (bu içeriği göstermek için kod snippet'ini güncelledim).Kısa bir google'dan sonra hiç bir shutdownHookTrigger referansı bulamadım, bağlantı kurar mısınız? – Chomeh

7

yılında, kapsamlı dış arabirim bir araç bulamadık Temelde sadece aynı soruyu yanıtladı ve ben zor ben burada cevabımı paylaşacağız. complete answer available here'u okumanızı tavsiye ederim. Burada bir özet sağlamaya ve cevabımı mevcut içeriğe uyarlamaya çalışacağım.

İlk sürümde Log4j, kapatma yordamını el ile çağırmak için bir API sağlıyordu. Neden olmasa da, it was removed from the second version bilgisine sahip değiliz. Şimdi, bunu yapmanın doğru yolu (mevcut olmayan belgelere göre), kapatma işleminden sorumlu olan ShutdownCallbackRegistry arabirimini kendi uygulamanızı sağlamaktır.

Bu sorunu gidermek için ne yaptık önerilen çözüm

Ben ShutdownCallbackRegistry arayüzünün kendi versiyonunu hayata olmasıdır. Çoğunlukla varsayılan uygulamanın yaptığı aynı şeyleri yapar, fakat kendisini JVM'ye bir kapatma kancası olarak kaydetmek yerine, manuel olarak çağrılana kadar bekler.

Tüm çözümü ve talimatları GitHub/DjDCH/Log4j-StaticShutdown üzerinde bulabilir ve kendi projelerinizde kullanabilirsiniz. Temelde, sonunda, sadece uygulamada böyle bir şey yapmak zorunda:

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      // Do your usual shutdown stuff here that need logging 
     } finally { 
      // Shutdown Log4j 2 manually 
      StaticShutdownCallbackRegistry.invoke(); 
     } 
    } 
})); 

Bu mükemmel bir çözüm olduğunu hiç şüphesiz ve benim uygulama mükemmel olduğunu söyleyemeyiz, ama ben denedim bunu doğru şekilde yapmak. Bu çözümü uygun bulup bulmazsanız, sizden geri bildirim duymaktan memnuniyet duyarız.

İlgili konular