• ElasticSearch异常情况监控处理


    1.异常类型

    在公司使用Canal-Server作为数据同步监听,在同步过程中,会出现各种问题异常,

    比如常见一下几种:

    1.表结构发生变更,导出BinLog字段对比异常

    2.数据库连接失败,账号密码错误, 权限不足等

    3.Binlog文件过期或者丢失

    2.传统监控手段-ELK

    1.应用端按固定格式,把日志写入到log文件中

    2.logstash读取日志文件, 写入到ES中

    3.通过logstash分析日志,按特定规则配置告警规则,发送钉钉报警

    3.轻量级监控手段logback

    1.自定义LogDingDingAppende

    1. package com.logtest.appender;
    2. import ch.qos.logback.classic.Level;
    3. import ch.qos.logback.classic.PatternLayout;
    4. import ch.qos.logback.classic.spi.LoggingEvent;
    5. import ch.qos.logback.core.UnsynchronizedAppenderBase;
    6. import com.alibaba.fastjson.JSON;
    7. import com.logtest.appender.endity.DingtalkMessage;
    8. import com.logtest.util.HttpsUtils;
    9. import lombok.extern.slf4j.Slf4j;
    10. import org.springframework.util.StringUtils;
    11. import java.util.HashMap;
    12. import java.util.Map;
    13. @Slf4j
    14. public class LogDingDingAppender extends UnsynchronizedAppenderBase<LoggingEvent> {
    15. private String pattern = "%level\n%m\n%logger\n%ex";
    16. private PatternLayout layout;
    17. private String profilesActive = "unknown";
    18. private String dingdingUrl;
    19. private Level nowLevel = Level.ERROR;
    20. private String secret;
    21. private String serverName;
    22. /**
    23. * 排除的类集合用逗号分隔
    24. */
    25. private String excludeThrowableClasses;
    26. public String getProfilesActive() {
    27. return profilesActive;
    28. }
    29. public void setProfilesActive(String profilesActive) {
    30. this.profilesActive = profilesActive;
    31. }
    32. public void setPattern(String pattern) {
    33. this.pattern = pattern;
    34. }
    35. public String getServerName() {
    36. return serverName;
    37. }
    38. public void setServerName(String serverName) {
    39. this.serverName = serverName;
    40. }
    41. public String getPattern() {
    42. return pattern;
    43. }
    44. public PatternLayout getLayout() {
    45. return layout;
    46. }
    47. public void setLayout(PatternLayout layout) {
    48. this.layout = layout;
    49. }
    50. public String getDingdingUrl() {
    51. return dingdingUrl;
    52. }
    53. public void setDingdingUrl(String dingdingUrl) {
    54. this.dingdingUrl = dingdingUrl;
    55. }
    56. public void setLevel(String level) {
    57. this.nowLevel = Level.toLevel(level, Level.ERROR);
    58. }
    59. public void setExcludeThrowableClasses(String excludeThrowableClasses) {
    60. this.excludeThrowableClasses = excludeThrowableClasses;
    61. }
    62. public String getSecret() {
    63. return secret;
    64. }
    65. public void setSecret(String secret) {
    66. this.secret = secret;
    67. }
    68. @Override
    69. protected void append(LoggingEvent eventObject) {
    70. try {
    71. if (eventObject.getLevel().isGreaterOrEqual(nowLevel)) {
    72. if (excludeThrowableClasses != null && eventObject.getThrowableProxy() != null) {
    73. if (excludeThrowableClasses.contains(eventObject.getThrowableProxy().getClassName())) {
    74. return;
    75. }
    76. }
    77. String toMsg = layout.doLayout(eventObject);
    78. sendMarkDownMsg("Canal-Server监听异常", toMsg);
    79. }
    80. } catch (Exception e) {
    81. e.printStackTrace();
    82. }
    83. }
    84. @Override
    85. public void start() {
    86. //sendStartMsg();
    87. System.out.println("Canal-Server开始监控,应用名:" + getServerName());
    88. PatternLayout patternLayout = new PatternLayout();
    89. patternLayout.setContext(context);
    90. patternLayout.setPattern(getPattern());
    91. patternLayout.start();
    92. this.layout = patternLayout;
    93. super.start();
    94. }
    95. /**
    96. * @Author
    97. * @Description 开始监听
    98. * @Date 2021-09-29 18:05
    99. * @Param
    100. * @return
    101. **/
    102. public void sendStartMsg() {
    103. String title = "Canal-Server开始监控";
    104. String prefixEnd = "</font> \n";
    105. String prefixStart = "####";
    106. String msg = "### " + title + prefixEnd +
    107. prefixStart + " 应用名:<font color=#1A73E8 size=2>" + getServerName() + prefixEnd;
    108. DingtalkMessage message = new DingtalkMessage();
    109. DingtalkMessage.Markdown markdown = new DingtalkMessage.Markdown();
    110. markdown.setTitle(title);
    111. markdown.setText(msg);
    112. message.setMarkdown(markdown);
    113. Map<String, String> header = new HashMap<>();
    114. header.put("Content-Type", "application/json");
    115. String sendMsgRet = HttpsUtils.post(dingdingUrl, JSON.toJSONString(message), header);
    116. log.info("钉钉机器人返回:{}" + sendMsgRet);
    117. }
    118. /**
    119. * @Author
    120. * @Description 钉钉发送信息
    121. * @Date 2021-09-29 18:04
    122. * @Param
    123. * @return
    124. **/
    125. public void sendMarkDownMsg(String title, String msg) {
    126. DingtalkMessage message = new DingtalkMessage();
    127. DingtalkMessage.Markdown markdown = new DingtalkMessage.Markdown();
    128. markdown.setTitle(title);
    129. markdown.setText(getMarkdown(title, msg));
    130. message.setMarkdown(markdown);
    131. Map<String, String> header = new HashMap<>();
    132. header.put("Content-Type", "application/json");
    133. String sendMsgRet = HttpsUtils.post(dingdingUrl, JSON.toJSONString(message), header);
    134. log.info("钉钉机器人返回:{}" + sendMsgRet);
    135. }
    136. /**
    137. * @Author
    138. * @Description 格式化钉钉文本内容
    139. * @Date 2021-09-29 18:04
    140. * @Param
    141. * @return
    142. **/
    143. private String getMarkdown(String title, String msg) {
    144. if (StringUtils.isEmpty(msg)) {
    145. return null;
    146. }
    147. String resultStr = "";
    148. //日志格式logback配置<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}|-|${appName}|-|%thread|-|%level|-|%logger|-|%msg%n</pattern>
    149. String[] msgs = msg.split("\\|-\\|");
    150. if (msgs.length > 0) {
    151. String prefixEnd = "</font> \n";
    152. String prefixStart = "####";
    153. resultStr = "### " + title + prefixEnd +
    154. prefixStart + " 应用名:<font color=#1A73E8 size=2>" + getServerName() + prefixEnd +
    155. prefixStart + " 类路径:<font color=#666666 size=2>" + msgs[4] + prefixEnd +
    156. prefixStart + " 异常时间:<font color=#666666 size=2>" + msgs[0] + prefixEnd +
    157. prefixStart + " 异常信息:<font color=#FF0000 size=2>" + msgs[5] + prefixEnd;
    158. }
    159. return resultStr;
    160. }
    161. }

    2.配置logback.xml

    1. <appender name="LogDingDing" class="com.logtest.appender.LogDingDingAppender">
    2. <serverName>log-test</serverName>
    3. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}|-|${appName}|-|%thread|-|%level|-|%logger|-|%msg%n</pattern>
    4. <!--钉钉机器人Webhook url-->
    5. <dingdingUrl>*****</dingdingUrl>
    6. <!--机器人签名密钥 新版需要签名推送-->
    7. <secret></secret>
    8. <!--排除的异常类,用逗号分隔-->
    9. <excludeThrowableClasses></excludeThrowableClasses>
    10. <!--机器人的推送级别-->
    11. <level>ERROR</level>
    12. </appender>
    13. <root level="INFO">
    14. <!--<root level="DEBUG">-->
    15. <appender-ref ref="STDOUT"/>
    16. <appender-ref ref="infoAppender"/>
    17. <appender-ref ref="debugAppender"/>
    18. <appender-ref ref="warnAppender"/>
    19. <appender-ref ref="errorAppender"/>
    20. <!--机器人的推送-->
    21. <appender-ref ref="LogDingDing"/>
    22. </root>

    3.项目所需POM文件

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-logging</artifactId>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.apache.httpcomponents</groupId>
    8. <artifactId>httpclient</artifactId>
    9. <version>4.5.5</version>
    10. </dependency>
    11. <dependency>
    12. <groupId>com.alibaba</groupId>
    13. <artifactId>fastjson</artifactId>
    14. <version>1.2.58</version>
    15. </dependency>
    16. <dependency>
    17. <groupId>org.springframework.boot</groupId>
    18. <artifactId>spring-boot-starter-web</artifactId>
    19. </dependency>
    20. <dependency>
    21. <groupId>org.springframework.boot</groupId>
    22. <artifactId>spring-boot-starter-test</artifactId>
    23. <scope>test</scope>
    24. </dependency>
    25. <dependency>
    26. <groupId>org.springframework.boot</groupId>
    27. <artifactId>spring-boot-autoconfigure</artifactId>
    28. <version>2.0.1.RELEASE</version>
    29. </dependency>
    30. <dependency>
    31. <groupId>org.projectlombok</groupId>
    32. <artifactId>lombok</artifactId>
    33. <version>1.18.16</version>
    34. </dependency>
    35. </dependencies>

    4.新建SpringBoot项目&测试

    1. package com.logtest;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. import lombok.extern.slf4j.Slf4j;
    5. @SpringBootApplication
    6. @Slf4j
    7. public class LogTestApplication {
    8. public static void main(String[] args) {
    9. SpringApplication.run(LogTestApplication.class, args);
    10. log.error("测试钉钉日志告警");
    11. }
    12. }

    测试结果如下:

    5.项目源码

    链接:百度网盘 请输入提取码

    提取码:b293

     

  • 相关阅读:
    Mybatis的生命周期和作用域
    MySQL 过滤重复数据
    Scheduling in Kubernetes
    学习Vue3 第一章
    机器学习-最小二乘法
    win10 IIS部署.NET Core api
    【校招VIP】产品深入分析之电商运营
    iOS获取当前网络连接状态WiFi、5G、4G、3G、2G
    “量化交易”、“算法交易”、“电子交易”等新型交易模式是如何发展起来的呢?
    打破焦虑!AI 时代的程序员为什么需要云端 IDE?
  • 原文地址:https://blog.csdn.net/qq_19734597/article/details/125563071