良好的日誌記錄是軟體開發不可或缺的實務。Eclipse 雖提供基本日誌服務(org.eclipse.core.runtime.ILog),但在靈活配置、效能控制與外部化設定上存在不足。本文介紹兩種改進方案,核心採用 Apache Log4j 整合。
Eclipse 透過 Plugin.getLog() 取得 ILog 實例,支援多個 ILogListener,預設包含「Error Log」視圖與 ${workspace}/.metadata/.log 檔案兩個監聽器。但缺乏外部配置檔、無法精細控制日誌層級與輸出目的地,且效能上會向所有監聽器廣播事件。
Hierarchy 物件,實現隔離性(解決 java.util.logging 單一 LogManager 共享設定的問題)。PluginFileAppender:繼承 RollingFileAppender,日誌寫入 ${workspace}/.metadata/.plugins/${plugin.name}/,支援檔案大小限制與滾動。PluginLogAppender:將事件轉發至 Eclipse 原生 ILog,整合至 Error Log 視圖。HierarchyEventListener,在 Appender 加入時注入必要的 ILog 與儲存路徑參考。PluginLogManager,外掛停用時正確關閉 Hierarchy、移除 Appender 與 Logger。private static final String LOG_PROPERTIES_FILE = "logger.properties";
public void start(BundleContext context) throws Exception {
super.start(context);
configure();
}
private void configure() {
try {
URL url = getBundle().getEntry("/" + LOG_PROPERTIES_FILE);
InputStream in = url.openStream();
Properties props = new Properties();
props.load(in);
in.close();
this.logManager = new PluginLogManager(this, props);
this.logManager.hookPlugin(
TestPlugin.getDefault().getBundle().getSymbolicName(),
TestPlugin.getDefault().getLog());
} catch (Exception e) {
// 錯誤處理...
}
}
log4j.rootCategory=, A1
log4j.appender.A1=com.tools.logging.PluginFileAppender
log4j.appender.A1.File=helloplugin.log
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%p %t %c - %m%n
log4j.appender.A2=com.tools.logging.PluginLogAppender
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%p %t %c - %m%n
log4j.logger.helloplugin=, A2
根 Logger 使用檔案 Appender (A1);helloplugin Logger 額外加入 Error Log Appender (A2),避免重複記錄。
實作 PluginLogListener (ILogListener),將依賴外掛的 Eclipse 原生日誌重導向至主外掛的 Log4j 架構,統一配置、集中儲存,保留完整事件時序。
方案一提供完整 Log4j 功能(分級、多 Appender、外部配置、效能優化),方案二讓現有 Eclipse API 呼叫也能受惠於統一日誌管理。兩者可並行使用。完整原始碼採 OSGI 開發,需自行下載 log4j-1.2.8.jar 放入專案。