Kettle5 log4j插件使用

1.前言

Kettle5.x版本本身没有使用log4j输出日志到文件。但是,有时候根据我们实际的需求,需要将日志保存起来,便于日后分析错误、排除故障。所幸在kettle5中有一个内置插件,叫做kettle5-log4j-plugin。本来以为只要将log4j.xml放在kettle安装目录,并在plugins目录下集成这个插件后就可以将kettle中执行的日志统统追加到log4j配置的日志输出位置。但是事实上,kettle官方源码里面并没有在KettleEnvironment中初始化注册logging plugin。所以我们需要做的是,在Kettle环境初始化过程中初始化注册logging plugin。

在Kettle中,所有的组件都是以插件的形式存在。Kettle还将插件分门别类,比如我们这篇文章所讲的是日志插件类型LoggingPluginType。

2.kettle5 log4j插件集成方式

下面我们将介绍在kettle5中实现log4j插件的集成,使日志以文件形式输出到指定的目录下。

(1) 修改KettleEnvironment源码,增加LoggingPlugin的初始化

在KettleEnvironment类里面增加如下方法:

1
2
3
4
5
6
7
private static void initLoggingPlugins() throws KettleException {
List<PluginInterface> plugins = PluginRegistry.getInstance().getPlugins(LoggingPluginType.class);
for(PluginInterface plugin : plugins) {
LoggingPluginInterface loggingPluginInterface = PluginRegistry.getInstance().loadClass(plugin, LoggingPluginInterface.class);
loggingPluginInterface.init();
}
}

然后在init方法里面植入该方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void init( boolean simpleJndi ) throws KettleException {
// ....
// Also read the list of variables.
//
KettleVariablesList.init();
// Initialize the Lifecycle Listeners
//
initLifecycleListeners();
initLoggingPlugins();
initialized = true;
}

其实Kettle内置已经为我们提供好LoggingPlugin的骨架,在log4j plugin中也已经写好了对应log4j日志插件的实现,只是kettle并没有在Kettle环境初始化过程初始化这些插件。

kettle5 log4j plugin在类Log4jLogging里实现了LoggingPluginInterface接口,kettle约定一切logging plugin都需要实现这个接口:

1
2
3
4
5
6
7
8
9
10
11
public interface LoggingPluginInterface extends KettleLoggingEventListener {
// @Override
// public void eventAdded(LoggingEvent event);
//
public void init();
public void dispose();
}

对于logging plugin,需要实现的只有3个方法:

  • 在eventAdded里处理日志记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void eventAdded( KettleLoggingEvent event ) {
switch ( event.getLevel() ) {
case ERROR:
pentahoLogger.log( Level.ERROR, event.getMessage() );
break;
case DEBUG:
case ROWLEVEL:
pentahoLogger.log( Level.DEBUG, event.getMessage() );
break;
default:
pentahoLogger.log( Level.INFO, event.getMessage() );
break;
}
}
  • 在init方法注册日志插件到内置Kettle日志事件监听器
1
2
3
4
@Override
public void init() {
KettleLogStore.getAppender().addLoggingEventListener( this );
}
  • 在dispose方法里取消日志插件的注册
1
2
3
public void dispose() {
KettleLogStore.getAppender().removeLoggingEventListener( this );
}

(2) 重新编译kettle engine模块

因为我们修改了KettleEnvironment源码,位于engine模块,因此我们需要重新执行ant命令并将成功生成的jar包扔到kettle安装目录的lib子目录里面

(3) 部署kettle log4j plugin

将kettle-log4j-plugin插件包放到kettle安装目录的plugins子目录里面并解压。

如果没有这个插件,可以在kettle plugins源码里面编译得到,官方源码里面有自带这个插件。

(4) 配置log4j.xml

配置log4j.xml并将log4j.xml文件放到kettle安装根目录(与Spoon.bat等文件同目录)。

log4j.xml配置参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MM-dd HH:mm:ss.SSS} %5p [%t] (%F:%L) -%m%n" />
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="${user.dir}/logs/kettle.log" />
<param name="Append" value="false"/>
<param name="MaxFileSize" value="10000KB"/>
<param name="MaxBackupIndex" value="10"/>
<param name="encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MM/dd HH:mm:ss.SSS} %5p [%t] (%F:%L) -%m%n" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="FILE" />
</root>
<category name="org.pentaho.di" additivity="false">
<priority value="INFO"/>
<appender-ref ref="FILE"/>
</category>
</log4j:configuration>

这里我们将日志文件输出到${user.dir} / logs / kettle.log,那么实际上对应的目录就是kettle安装目录下的logs子目录。

经过以上配置以后,双击Spoon.bat(假设你是在windows环境下),就可以看到logs目录生成并可以看到kettle.log文件,所有执行的转换或作业的日志都会同时输出到这个文件里面。

3.参考

坚持原创技术分享,您的支持将鼓励我继续创作!