企业微信机器人告诉
描绘
出产环境对反常监控实时性要求比较高,通常状况咱们都会运用邮件报警,非常重要的会运用短信报警。邮件咱们简略忽略,并且邮箱空间有限需求定期整理,短信又要收费,所以咱们要采用一种既要免费又要实时性高的方法,那就是咱们平常作业所用的交流东西(企微,钉钉)
意图
ERROR等级日志实时报警
自定义业务预正告诉
对系统无侵入规划
能够快速定位问题
最重要能够实时群发告诉
邮件告诉

可以看到邮件告诉非常多,并且及时性也不行
计划
已然要无侵入规划,就不能到处埋点,终究挑选自定义Appender的方法处理
因为公司内部作业交流东西是企业微信,所以就凭借企业微信机器人发送实时告诉音讯,根据恳求链路ID结合ELK东西就可以从音讯告诉直接跳转到ELK,检查完整的链路日志从而快速定位问题
废话不多说直接上代码。。。
ErrorWarnAppender
public class ErrorWarnAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
@Setter
private String packageNames;
@Override
protected void append(ILoggingEvent event) {
if (null == event || "DEV".equalsIgnoreCase(ApplicationHelper.getEnv()) || StrUtil.isEmpty(MDC.get(ScmConstant.REQUEST_ID))) {
return;
}
boolean success = Arrays.stream(packageNames.split(",")).anyMatch(event.getLoggerName()::startsWith);
if (!success) {
return;
}
if (null == event.getThrowableProxy()) {
RobotUtil.sendWarn(event.getFormattedMessage());
} else {
RobotUtil.sendWarn(event.getFormattedMessage(), event.getThrowableProxy().getClassName() + ":" + event.getThrowableProxy().getMessage());
}
}
}
RobotUtil
public class RobotUtil {
/**
* 正告地址
*/
private static final String WARN_URL = "XXX";
/**
* 告诉地址
*/
private static final String NOTICE_URL = "XXX";
/**
* 测验环境ELK地址
*/
private static final String ELK_URL = "XXX";
/**
* 出产环境ELK地址
*/
private static final String PRD_ELK_URL = "XXX";
/**
* 发送企业微信机器人告诉音讯
*
* @param message
*/
public static void sendNotice(StringBuilder message) {
try {
// 发送告诉音讯
if (isPro()) {
HttpUtil.post(NOTICE_URL, RobotUtil.getMessage(message));
} else {
message.insert(0, "env:" + ApplicationHelper.getEnv() + "\n");
HttpUtil.post(WARN_URL, RobotUtil.getMessage(message));
}
} catch (Exception ignored) {
}
}
/**
* 发送企业微信机器人正告音讯
*
* @param message
*/
public static void sendWarn(String message) {
sendWarn(message, null);
}
/**
* 发送企业微信机器人正告音讯
*
* @param message
* @param exception
*/
public static void sendWarn(String message, String exception) {
if (!ApplicationHelper.getSendWarnEnable()) {
return;
}
try {
String requestId = MDC.get(ScmConstant.REQUEST_ID);
StringBuilder text = new StringBuilder();
text.append("env:").append(isPro() ? "<font color=\"red\">**出产环境**</font>" : ApplicationHelper.getEnv()).append("\n");
text.append("applicationName:").append(ApplicationHelper.getApplicationName()).append("\n");
if (StrUtil.isNotEmpty(requestId)) {
text.append("requestId:").append("[").append(requestId).append("](").append(String.format(isPro() ? PRD_ELK_URL : ELK_URL, requestId)).append(")").append("\n");
}
text.append("message:").append(StrUtil.subPre(message, 1000)).append("\n");
if (StrUtil.isNotEmpty(exception)) {
text.append("exception:").append(StrUtil.subPre(exception, 1000)).append("\n");
}
// 发送正告音讯
HttpUtil.post(WARN_URL, RobotUtil.getMessage(text));
} catch (Exception ignored) {
}
}
/**
* 音讯内容
*
* @param message
* @return
*/
private static String getMessage(Object message) {
Map<String, Object> textMap = new HashMap<>();
textMap.put("msgtype", "markdown");
Map<String, Object> contentMap = new HashMap<>();
contentMap.put("content", message);
textMap.put("markdown", contentMap);
return JSONUtil.toJsonStr(textMap);
}
/**
* 是否出产环境
*
* @return
*/
private static boolean isPro() {
return "PRO".equalsIgnoreCase(ApplicationHelper.getEnv());
}
}
logback装备
1、添加appender 装备
<appender name="ERROR_WARN" class="org.slf4j.ErrorWarnAppender">
<packageNames>org.xx,com.xx,com.yy</packageNames>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
2、各个环境增加appender
<springProfile name="test">
<root level="INFO">
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="ERROR_WARN"/>
</root>
</springProfile>
<springProfile name="prd">
<root level="INFO">
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
<appender-ref ref="ERROR_WARN"/>
</root>
</springProfile>
作用展现


可以看到音讯能够区分环境,使用名称,链路ID,错误信息(出产环境红色夺目提醒)
注意事项
1、音讯每分钟最多发送20条\color{red}音讯每分钟最多发送20条
发送企业微信音讯是https恳求接口,每分钟约束最多20条音讯,所以反常报警只发送error等级的告诉
同时还可以凭借于kafka异步音讯,发送邮件,短信 等等音讯告诉
2、音讯体长度最大支撑4000字符\color{red}音讯体长度最大支撑4000字符
咱们会把message和exception 截取前1000个字符
3、需求简略了解markdown语法\color{red}需求简略了解markdown语法
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。