2015-11-24 40 views
0

我正在編寫一個Web應用程序,其中用戶(包括許多其他內容)可以構建和運行自己的腳本。這些腳本運行在後端,它們可能會或可能不會生成錯誤 - 此類錯誤現在寫入系統日誌。以編程方式從log4j獲取日誌事件

如果用戶通過web應用程序本身查看這些類型的日誌事件將會有所幫助,所以我想管道&以某種方式從log4j過濾它們(在事件發生之前),這樣我就可以編程訪問他們。 Elasticsearch有類似的東西 - 當沒有找到結果時,它會顯示在給定的時間範圍內發生的錯誤。

我想我可以只抽象記錄,並確保所有的事件都發送到log4j和客戶端,但我希望有一個更好的方法,而不必觸摸記錄器調用(或必須從日誌文件中讀取)。

看着log4j2網站,但沒有找到任何有用的東西 - 任何想法如何實現這樣的東西?

回答

2

要攔截日誌事件,你可以在三個點插入你的一部分:

  • 的log4j後:我們的Log4j日誌的東西,你可以很容易地「查詢「在你的應用程序中。有各種各樣的Appender可用於此。記錄到數據庫是一種選擇,您可以登錄到標準輸出並將其重定向到您的應用程序,因此您可以獲得某種流

  • 使用appender:您可以實現自己的appender,使用log4j進行配置並執行無論你想在那裏。

  • 在log4j之前:將每次調用Log4j Logger包裝爲您自己的實現,並在實際記錄您的事件之前或之後在其中執行您的邏輯。

的附加器的方法似乎是最優雅:它允許使用log4j的配置選項來控制您的前端顯示的內容,並沒有什麼,並且由於附加目的地在同一文件中配置使得它不太由於沒有意識到對用戶來說很重要,有可能有人會禁用日誌記錄。但它需要關於log4j內部的大部分知識。

+0

同意appender方法是最優雅的。我做了一些試驗,似乎工作得很好。 – sfThomas

0

因爲你不想分析日誌,所以我會去記錄數據庫。一個建議可能是log4j_logging_database。

這當然意味着你編寫查詢和格式化日誌記錄以使其可以從sql進行分析,並且還可以構建一種向客戶端展示這些查詢的方法。

你可以找到一個教程here。有一個日誌記錄級別,所以你可以根據你的配置過濾錯誤和重要的工作人員。不要忘記將索引添加到感興趣的表列中,因爲一段時間後日志記錄會變得很大。

此致

薩諾斯

1

一種可能的解決方案可能是使用一個管道輸入流。

// pipes output in the output stream to the input stream 
PipedInputStream in = new PipedInputStream(); 
PipedOutputStream out = new PipedOutputStream(in); 

// create custom l4j appender 
Appender customAppender = new WriterAppender(
            new PatternLayout("%-5p %d [%t][%F:%L] : %m%n"), out); 

//use any logger: 
logger.addAppender(customAppender); 
//or the root logger: Logger.getRootLogger().addAppender(customAppender); 

// write a test message to log 
logger.error("test"); 

// printing entries in piped input stream 
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); 
String line; 
while (bufferedReader.ready() && (line = bufferedReader.readLine()) != null) { 
    System.out.println("log entry: " + line); 
} 

結果輸出:

log entry: ERROR 2015-11-24 11:58:18,366 [main][Main.java:52] : test 

原因,你可以使用過濾器的附加器(或定義自己的過濾器)。 例如過濾日誌級別範圍:

LevelRangeFilter levelRangeFilter = new LevelRangeFilter(); 
levelRangeFilter.setLevelMin(Level.INFO); 
levelRangeFilter.setLevelMax(Level.ERROR); 
customAppender.addFilter(levelRangeFilter); 
相關問題