azkaban二次开发 – 自定义钉钉告警

azkaban默认只支持邮件告警,但支持plugin扩展机制自定义告警,所以我决定实现一个钉钉告警,毕竟没人天天盯着邮箱。

azkaban插件原理

下载azkaban最新代码,我们分析一下告警plugin的完整工作流程,以便正确开发&配置plugin。

插件回调

源码文件:azkaban-common/src/main/java/azkaban/executor/ExecutionControllerUtils.java,关键函数:

可见:

  • alerterHolder.get()可以获取alerter插件的实例对象,默认有email实现,也可以获取到自定义的实现。
  • 必须在flow执行时配置参数alert.type,其值为插件的名字。
  • flow执行失败会回调插件的alertOnError函数,其他情况会有其他函数对应,这里没有粘完整代码。

alerterHolder加载插件

源码文件:azkaban-common/src/main/java/azkaban/executor/AlerterHolder.java

该类初始化时会直接得到一个现成的email实现,另外会去plugins/alerter目录下加载自定义插件:

plugins/alerter目录下应该放置我们的告警插件,每个告警插件一个目录,它会逐个扫描加载:

它首先loadPluginProps加载插件私有配置,位于插件目录的conf子目录下的plugin.properties:

例如我的插件是这样放置的:

文件里的alert.name为插件的唯一标识,alert.class为插件的类名。

上述代码最终通过getPluginClass来实例化插件class对象,它要做的事情其实是创建一个classLoader可以从我们上传的jar包中找到alert.class类,因此我们仔细看看getPluginClass函数的实现。

它的重要传参包含azkaban当前的classloader,插件的class名字,插件的目录。

源码文件:az-core/src/main/java/azkaban/utils/PluginUtils.java

上面定义了自己的classloader对象,由它负责去插件目录下的jar包寻找要加载的alert.class类以及依赖的各种class,熟悉java classloader机制的话应该不会有疑惑。

至此,插件的加载过程就基本熟悉了,至于我们要实现的Alerter接口,就很简单了:

flow成功、flow失败、flow首次失败、flow SLA违约,一共4个回调时机。

实现插件

我开源了一个demo项目供大家参考:https://github.com/owenliang/azkaban-dingding-alert

POM的配置比较重要:

我们只在provided模式依赖了一下azkaban库和log4j库,前者包含了实现Alerter需要的那些class,后者是azkaban打日志用的库,我们打包的jar中不需要包含这些包,因为azkaban运行时classloader都能加载得到。

特别一点的是dingding的SDK,他们没提供maven只提供了jar包,我们把jar包放在项目下做本地编译时依赖,真正运行环境则是将dingding的jar包放在plugin的lib目录下来满足URLClassLoader的查找即可。

我只实现了flow失败时报警的逻辑,调用钉钉报警:

dingding.serverUrl配置由azkaban加载自插件的plugin.properties文件。

插件部署

我写了一个build.sh编译脚本,它把插件jar包放到了一个符合azkaban plugin要求的目录结构下,该目录下我提前放好了插件配置和dingding sdk的jar包。

这是最终插件目录结构:

把上述azkaban-dingding-alert放到azkaban安装目录的plugins/alerter目录下,重启azkaban(我是solo server)即可生效。

插件使用

根据源码分析,使用时必须在配置flow时传参alter.type为插件的唯一标识,在flow里面或者global.properties配置都无效:

运行flow,观察azkaban的日志文件可以看到我们插件打印的log:

完成~

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~