2013-07-01 25 views
11

Log4j2 cũng sử dụng các móc tắt máy để kết thúc các dịch vụ của nó. Nhưng tất nhiên tôi muốn đăng nhập trong suốt toàn bộ vòng đời của ứng dụng của tôi - bao gồm tắt máy. Với Log4j, điều này không thành vấn đề. Bây giờ nó có vẻ là không thể. Việc đăng xuất tắt, trong khi ứng dụng của tôi vẫn đang hoạt động. Có ai hy vọng cho tôi không?Làm thế nào để đăng nhập trong móc tắt máy với Log4j2?

Trân trọng Martin

+0

Ghi nhật ký hoặc tùy thuộc vào bất kỳ dịch vụ nào khác trong móc tắt máy, đã hoạt động không tốt và tất cả đều bắt kịp với bạn. –

+0

@MarkoTopolnik Nếu thực hành không tốt như bạn nói, bạn đề nghị làm gì nếu đầu ra của một móc móc tắt máy cần ghi/ghi? – vegemite4me

+0

Vì trong hook shutdown bạn không thể đếm trên bất kỳ phần nào của trạng thái khởi tạo vẫn tồn tại, thứ duy nhất tôi thấy là semi-trusted là một đoạn code hoàn toàn khép kín tạo ra một tệp và ghi vào nó. Tương tự như cách mà một phân đoạn lõi được tạo ra. –

Trả lời

19

Tính đến 2.0 beta9 này bây giờ đã cấu hình trong xml

<configuration ... shutdownHook="disable"> 

Xét bây giờ nó tàn tật, tôi đoán tôi cần phải tự shutdown hệ thống khai thác gỗ ở phần cuối của tôi tắt máy móc. Tuy nhiên tôi không thể tìm thấy một phương tiện triệt để giao diện bên ngoài, chỉ trong api nội

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

bạn đã bao giờ tìm ra điều này chưa? – user671731

+1

Vấn đề là, các móc tắt của Java được khởi động song song. Vì vậy, để thực sự chắc chắn rằng bạn có thể đăng nhập ở khắp mọi nơi bạn phải tránh chỉ cần thêm các móc của bạn vào Runtime.getRuntime(). AddShutdownHook (Thread) -API nhưng tạo ra công việc của riêng bạn tự dừng lại log4j 2.0 sau khi tất cả mọi thứ là xuống. Nhưng vấn đề chính đã được giải quyết khi Log4j cung cấp shutdownHook-trigger. – Martin

+0

Tôi đồng ý rằng bạn cần tạo quy trình làm việc của riêng mình. Tôi thường chạy ứng dụng của tôi trên Linux và tắt máy thông qua một tín hiệu đến JVM, do đó, một móc tắt máy phù hợp cho mục đích này (tôi đã cập nhật đoạn mã để hiển thị ngữ cảnh này).Tôi không thể tìm thấy bất kỳ tài liệu tham khảo shutdownHookTrigger sau một google ngắn gọn, bạn có nhớ liên kết? – Chomeh

7

tôi về cơ bản chỉ trả lời cùng một câu hỏi và tôi khó khăn tôi sẽ chia sẻ câu trả lời của tôi ở đây. Tôi khuyến khích bạn đọc số complete answer available here. Tôi sẽ cố gắng cung cấp một bản tóm tắt ở đây và điều chỉnh câu trả lời của tôi cho ngữ cảnh hiện tại.

Trong phiên bản đầu tiên, Log4j đã cung cấp API để thủ công gọi thủ tục tắt máy. Vì lý do chúng tôi không có kiến ​​thức về, it was removed from the second version. Bây giờ, đúng cách để làm điều đó (theo tài liệu không tồn tại), là cung cấp việc thực hiện của riêng bạn về giao diện ShutdownCallbackRegistry, chịu trách nhiệm về thủ tục tắt máy.

giải pháp đề xuất

Tôi đã làm gì để khắc phục vấn đề này là tôi thực hiện phiên bản riêng của tôi về giao diện ShutdownCallbackRegistry. Nó chủ yếu làm những việc tương tự như việc thực thi mặc định, nhưng thay vì tự đăng ký như là một hook shutdown cho JVM, nó đợi cho đến khi nó được gọi thủ công.

Bạn có thể tìm giải pháp và hướng dẫn đầy đủ trên GitHub/DjDCH/Log4j-StaticShutdown và sử dụng nó trong các dự án của riêng bạn. Về cơ bản, ở cuối, bạn chỉ phải làm một cái gì đó như thế này trong ứng dụng của bạn:

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(); 
     } 
    } 
})); 

Tôi không thể nói không chút nghi ngờ rằng đây là giải pháp hoàn hảo và rằng việc thực hiện của tôi là hoàn hảo, nhưng tôi đã cố gắng để làm điều đó đúng cách. Tôi sẽ rất vui khi được nghe ý kiến ​​phản hồi của bạn, hoặc nếu bạn thấy giải pháp này phù hợp hay không.

Các vấn đề liên quan