自定义钉钉机器人进行报警

整体代码逻辑

在这里插入图片描述

源码

assembly.xml

<assembly
        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
   http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>${project.version}</id>

    <formats>
        <format>tar.gz</format>
    </formats>

    <dependencySets>
        <dependencySet>
            <outputDirectory>/lib</outputDirectory>
            <outputFileNameMapping>${artifact.artifactId}.${artifact.extension}</outputFileNameMapping>
            <useProjectArtifact>false</useProjectArtifact>
        </dependencySet>
    </dependencySets>

    <files>
        <file>
            <source>src/main/resources/plugin.properties</source>
            <destName>conf/plugin.properties</destName>
        </file>
        <file>
            <source>${project.build.directory}/${project.artifactId}-${project.version}.jar</source>
            <destName>lib/${project.artifactId}-${project.version}.jar</destName>
        </file>
    </files>
</assembly>
DingAlerter
package com.qf.bigdata.azkaban.alert;

import azkaban.alert.Alerter;
import azkaban.executor.ExecutableFlow;
import azkaban.sla.SlaOption;
import azkaban.utils.Props;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.taobao.api.ApiException;
import org.apache.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.Map;

/**
 * 发送消息到钉钉
 */
public class DingAlerter implements Alerter {

    private final static Logger LOGGER = Logger.getLogger(DingAlerter.class);
    private String dingServerUrl;
    private Props props;

    public DingAlerter(Props props) {
        this.props = props;
        dingServerUrl = "https://oapi.dingtalk.com/robot/send?access_token=";
    }

    /**
     * 判断流是否被激活
     */
    public boolean isActived(ExecutableFlow flow, String type) {
        //获取工作流程中的所有的参数
        Map<String, String> parameters = flow.getExecutionOptions().getFlowParameters();
        // 拼凑一个azkaban的事件
        String property = "ding.alert.on." + type;
        // 设置默认值,如果根据ding.alert.on.success可以获取到值,就以这个值为准,否则false
        String defaultActive = props.getString(property, "false");
        // 获取默认值
        String actived = parameters.getOrDefault(property, defaultActive);
        return Boolean.parseBoolean(actived);
    }

    /**
     * 将long的ts转换string的时间
     */
    private String formatTime(long time) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(time);
    }

    /**
     * 将间隔时间转换为字符串表现形式
     */
    private String formatDuration(long startTime, long endTime) {
        if (startTime == -1) {
            return "-";
        }
        long durationMs;
        if (endTime == -1) {
            durationMs = System.currentTimeMillis() - startTime;
        } else {
            durationMs = endTime - startTime;
        }

        long seconds = durationMs / 1000;
        if (seconds < 60) {
            return seconds + " sec";
        }

        long minute = seconds / 60;
        seconds %= 60;
        if (minute < 60) {
            return minute + " min " + seconds + " sec";
        }

        long hour = minute / 60;
        minute %= 60;
        if (hour < 24) {
            return hour + "h " + minute +" min ";
        }

        long day = hour / 24;
        hour %= 24;
        return day + " days " + hour + " h";
    }

    /**
     * 从azkaban的流程中获取发送钉钉消息的令牌(token)
     */
    private String getPropertiesByFlowParameter(ExecutableFlow flow, String propKey) {
        // 获取到整个流程的参数
        Map<String, String> parameters = flow.getExecutionOptions().getFlowParameters();
        String value = props.getString(propKey);
        return parameters.getOrDefault(propKey, value);
    }

    /**
     * 钉钉发消息
     */
    private void send(ExecutableFlow flow, String title, int execId, String msg) throws Exception {
        // 获取到令牌字符串
        String dingdingToken = getPropertiesByFlowParameter(flow, "ding.token");
        // 获取发送消息的客户端
        DefaultDingTalkClient client = new DefaultDingTalkClient(dingServerUrl + dingdingToken);
        // 读取azkaban的host
        String linkHost = getPropertiesByFlowParameter(flow, "ding.link.azkaban.host");
        // 读取关键字
        String dingAuthWord = getPropertiesByFlowParameter(flow, "ding.auth.word");
        // 拼接一个地址
        String linkAddress = linkHost + "/executor?execid=" + execId + "#joblist";
        // 创建请求
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("link");
        OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link();
        link.setTitle(dingAuthWord + title);
        link.setPicUrl("");
        link.setMessageUrl("http://www.1000phone.com/");
        link.setText(msg);
        request.setLink(link);
        try {
            client.execute(request);
        }catch (ApiException e) {
            String errorMsg = "send dingding message fail " + e.getMessage();
            LOGGER.error(errorMsg);
            throw new ApiException(errorMsg, e);
        }
    }

    /**
     * 钉钉发消息
     */
    private void sendSla(String title,String msg) throws Exception {
        // 获取到令牌字符串
        //String dingdingToken = props.getString("ding.token");
        String dingdingToken="660de36fffae0f1e34bcd47926a70a44afeed1a8e5a15ed057ca7f02c220276a";
        // 获取发送消息的客户端
        DefaultDingTalkClient client = new DefaultDingTalkClient(dingServerUrl + dingdingToken);
        // 读取azkaban的host
        //String linkHost = props.getString("ding.link.azkaban.host");
        String linkHost="http://172.16.53.11:8081";
        // 读取关键字
        //String dingAuthWord = props.getString("ding.auth.word");
        String dingAuthWord="1000phone";
        // 创建请求
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("link");
        OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link();
        link.setTitle(dingAuthWord + title);
        link.setPicUrl("");
        link.setMessageUrl("http://www.1000phone.com/");
        link.setText(msg);
        request.setLink(link);
        try {
            client.execute(request);
        }catch (ApiException e) {
            String errorMsg = "send sla dingding message fail " + e.getMessage();
            LOGGER.error(errorMsg);
            throw new ApiException(errorMsg, e);
        }
    }


    @Override
    public void alertOnSuccess(ExecutableFlow flow) throws Exception {
        if (isActived(flow, "success")) {
            int execId = flow.getExecutionId();
            StringBuilder sb = new StringBuilder("Flow 1000phone").append(flow.getFlowId()).append("has success:\n");
            String title = sb.toString();
            sb.append("\t- Start: ").append(formatTime(flow.getStartTime())).append("\n");
            sb.append("\t- End: ").append(formatTime(flow.getEndTime())).append("\n");
            sb.append("\t- Duration: ").append(formatDuration(flow.getStartTime(), flow.getEndTime()));
            send(flow, title, execId, sb.toString());
        }
    }

    @Override
    public void alertOnError(ExecutableFlow flow, String... strings) throws Exception {
        if (isActived(flow, "error")) {
            int execId = flow.getExecutionId();
            StringBuilder sb = new StringBuilder("Flow 1000phone").append(flow.getFlowId()).append("has fail:\n");
            String title = sb.toString();
            sb.append("\t- Start: ").append(formatTime(flow.getStartTime())).append("\n");
            sb.append("\t- End: ").append(formatTime(flow.getEndTime())).append("\n");
            sb.append("\t- Duration: ").append(formatDuration(flow.getStartTime(), flow.getEndTime()));
            send(flow, title, execId, sb.toString());
        }
    }

    @Override
    public void alertOnFirstError(ExecutableFlow flow) throws Exception {
        if (isActived(flow, "first.error")) {
            int execId = flow.getExecutionId();
            StringBuilder sb = new StringBuilder("Flow 1000phone").append(flow.getFlowId()).append("has first fail:\n");
            String title = sb.toString();
            sb.append("\t- Start: ").append(formatTime(flow.getStartTime())).append("\n");
            sb.append("\t- End: ").append(formatTime(flow.getEndTime())).append("\n");
            sb.append("\t- Duration: ").append(formatDuration(flow.getStartTime(), flow.getEndTime()));
            send(flow, title, execId, sb.toString());
        }
    }

    @Override
    public void alertOnSla(SlaOption slaOption, String s) throws Exception {
        sendSla("sla alerter", "sla xxxx:\n" + s);
    }
}

plugin.properties

alerter.name = dingding
alerter.class = com.qf.bigdata.azkaban.alert.DingAlerter

ding.token = 660de36fffae0f1e34bcd47926a70a44afeed1a8e5a15ed057ca7f02c220276a
ding.auth.word = 1000phone
ding.link.azkaban.host = http://172.16.53.11:8081
ding.alert.on.success=true
ding.alert.on.first.error=true
ding.alert.on.error=true

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.qf.bigdata</groupId>
    <artifactId>azkaban-dingding</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <azkaban.version>2.5.0</azkaban.version>
        <junit.version>4.13</junit.version>
        <dingtalk-api.version>1.0.0</dingtalk-api.version>
        <slf4j.version>1.6.4</slf4j.version>
        <log4j.version>1.2.16</log4j.version>
    </properties>


    <repositories>
        <repository>
            <id>ali-maven</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>fail</checksumPolicy>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>ali-maven</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
        </pluginRepository>
    </pluginRepositories>


    <dependencies>
        <dependency>
            <groupId>com.linkedin.azkaban</groupId>
            <artifactId>azkaban</artifactId>
            <version>${azkaban.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>com.dingtalk</groupId>
            <artifactId>dingtalk-api</artifactId>
            <version>${dingtalk-api.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>create-distribution</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <descriptors>I
                                <descriptor>src/main/assembly/assembly.xml</descriptor>
                            </descriptors>
                            <finalName>${project.artifactId}</finalName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
                <version>2.5.3</version>
                <configuration>
                    <tagNameFormat>@{project.version}</tagNameFormat>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <forkMode>once</forkMode>
                    <argLine>-Dfile.encoding=UTF-8</argLine>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                    <excludes>
                    </excludes>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

并把自己的项目装载到azkaban上

并在执行的时候一定要说明警告类型
即:alert.type   dingding

在这里插入图片描述

当任务有错或者任务完成时钉钉机器人会自动报警(就是向群里发出信息)

如果想了解更多,可以去哔站搜一下视频观看

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值