diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/conf/Config.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/conf/Config.java index aea6f2359..bbc62a1db 100644 --- a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/conf/Config.java +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/conf/Config.java @@ -84,11 +84,7 @@ public class Config { public static boolean ALARM_OFF_FLAG = false; - public static class Checker { - public static boolean TURN_ON_EXCEPTION_CHECKER = true; - - public static boolean TURN_ON_EXECUTE_TIME_CHECKER = true; - } + public static String ALARM_TYPE_CONFIG_ID = "1004"; } public static class MailSenderInfo { @@ -97,5 +93,5 @@ public class Config { public static class TemplateInfo { public static String CONFIG_ID = "1001"; - } + } } \ No newline at end of file diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/dao/SystemConfigDao.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/dao/SystemConfigDao.java index 8b08c14c1..767ba4cd0 100644 --- a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/dao/SystemConfigDao.java +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/dao/SystemConfigDao.java @@ -4,6 +4,7 @@ import com.ai.cloud.skywalking.alarm.util.DBConnectUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -12,15 +13,29 @@ public class SystemConfigDao { private static Logger logger = LogManager.getLogger(AlarmMessageDao.class); public static String getSystemConfig(String configId) throws SQLException { - PreparedStatement ps = DBConnectUtil.getConnection().prepareStatement( - "SELECT system_config.conf_value FROM system_config WHERE system_config.sts = " + - "? AND system_config.config_id = ?"); - ps.setString(1, "A"); - ps.setString(2, configId); + + String result = ""; + Connection connection = DBConnectUtil.getConnection(); + + try { + PreparedStatement ps = connection.prepareStatement( + "SELECT system_config.conf_value FROM system_config WHERE system_config.sts = " + + "? AND system_config.config_id = ?"); + ps.setString(1, "A"); + ps.setString(2, configId); - ResultSet resultSet = ps.executeQuery(); - resultSet.next(); - - return resultSet.getString("conf_value"); + ResultSet resultSet = ps.executeQuery(); + resultSet.next(); + + result = resultSet.getString("conf_value"); + } catch (Exception e) { + logger.error("Failed to find systemConfig."); + throw e; + } finally { + if(connection != null) { + connection.close(); + } + } + return result; } } diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmMessage.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmMessage.java index 34ca09ecf..6b25c14a5 100644 --- a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmMessage.java +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmMessage.java @@ -1,14 +1,18 @@ package com.ai.cloud.skywalking.alarm.model; +import java.util.Date; + public class AlarmMessage { - private String traceid; + private String traceid; private String exceptionMsg; + private Date date; public AlarmMessage(String traceid, String exceptionMsg) { super(); this.traceid = traceid; this.exceptionMsg = exceptionMsg; + this.date = this.getDate(traceid); } public String getTraceid() { @@ -17,5 +21,28 @@ public class AlarmMessage { public String getExceptionMsg() { return exceptionMsg; + } + + public Date getDate() { + return date; } + + public void setDate(Date date) { + this.date = date; + } + private Date getDate(String traceid) { + + Date date; + String[] traceidPartitions = traceid.split("\\."); + + try { + String timeStr = traceidPartitions[2]; + Long timeStamp = Long.parseLong(timeStr); + date = new Date(timeStamp); + } catch (Exception e) { + return null; + } + return date; + } + } diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmType.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmType.java new file mode 100644 index 000000000..b64c87d9d --- /dev/null +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/model/AlarmType.java @@ -0,0 +1,36 @@ +package com.ai.cloud.skywalking.alarm.model; + + +public class AlarmType { + + //告警类型名称 + private String type; + //告警标签 + private String label; + //告警描述 + private String desc; + + @Override + public String toString() { + return "AlarmType [type=" + type + ", label=" + label + ", desc=" + desc + "]"; + } + + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + public String getDesc() { + return desc; + } + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/procesor/AlarmMessageProcessor.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/procesor/AlarmMessageProcessor.java index 9f0df9026..9c344aa4a 100644 --- a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/procesor/AlarmMessageProcessor.java +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/procesor/AlarmMessageProcessor.java @@ -1,28 +1,30 @@ package com.ai.cloud.skywalking.alarm.procesor; import java.io.IOException; -import java.io.StringReader; import java.io.StringWriter; import java.sql.SQLException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import redis.clients.jedis.Jedis; - import com.ai.cloud.skywalking.alarm.model.AlarmMessage; import com.ai.cloud.skywalking.alarm.model.AlarmRule; +import com.ai.cloud.skywalking.alarm.model.AlarmType; import com.ai.cloud.skywalking.alarm.model.ApplicationInfo; import com.ai.cloud.skywalking.alarm.model.MailInfo; import com.ai.cloud.skywalking.alarm.model.UserInfo; +import com.ai.cloud.skywalking.alarm.util.AlarmTypeUtil; import com.ai.cloud.skywalking.alarm.util.MailUtil; import com.ai.cloud.skywalking.alarm.util.RedisUtil; import com.ai.cloud.skywalking.alarm.util.RedisUtil.Executable; @@ -30,62 +32,74 @@ import com.ai.cloud.skywalking.alarm.util.TemplateConfigurationUtil; import freemarker.template.Template; import freemarker.template.TemplateException; +import redis.clients.jedis.Jedis; public class AlarmMessageProcessor { - private static Logger logger = LogManager - .getLogger(AlarmMessageProcessor.class); - - static String mailTemplate = ""; + private static Logger logger = LogManager .getLogger(AlarmMessageProcessor.class); + + static List alarmTypeList; + static Template t; static { - Properties properties = new Properties(); - try { - properties.load(AlarmMessageProcessor.class.getResourceAsStream("/mail-template_new.config")); - mailTemplate = properties.getProperty("template.default"); - } catch (IOException e) { - e.printStackTrace(); - } + alarmTypeList = AlarmTypeUtil.getAlarmTypeList(); } - public void process(UserInfo userInfo, AlarmRule rule) throws TemplateException, IOException, SQLException { - Set warningObjects = new HashSet(); + public void process(UserInfo userInfo, AlarmRule rule) throws TemplateException, IOException, SQLException { + + Map> warningMap = new HashMap>(); Set warningMessageKeys = new HashSet(); - long currentFireMinuteTime = System.currentTimeMillis() / (10000 * 6); + long currentFireMinuteTime = System.currentTimeMillis() / (1000 * 60); long warningTimeWindowSize = currentFireMinuteTime - rule.getPreviousFireTimeM(); - // 获取待发送数据 - if (warningTimeWindowSize >= rule.getConfigArgsDescriber().getPeriod()) { - for (ApplicationInfo applicationInfo : rule.getApplicationInfos()) { - for (int period = 0; period < warningTimeWindowSize; period++) { - String alarmKey = userInfo.getUserId() - + "-" - + applicationInfo.getAppCode() - + "-" - + (currentFireMinuteTime - period - 1); - - warningMessageKeys.add(alarmKey); - setAlarmMessages(alarmKey, warningObjects); + + // 获取待发送数据 + if (warningTimeWindowSize >= rule.getConfigArgsDescriber().getPeriod()) { + for(AlarmType alarmType : alarmTypeList) { + String type = alarmType.getType(); + List warningObjects = new ArrayList(); + for (ApplicationInfo applicationInfo : rule.getApplicationInfos()) { + for (int period = 0; period < warningTimeWindowSize; period++) { + Long currentMinuteTime = currentFireMinuteTime - period - 1; + String alarmKey = userInfo.getUserId() + + "-" + + applicationInfo.getAppCode() + + "-" + + currentMinuteTime; + if(!type.equals("default")) { + alarmKey += "-" + type; + } + warningMessageKeys.add(alarmKey); + setAlarmMessages(alarmKey, warningObjects); + } + } + if(warningObjects.size() > 0) { + warningMap.put(type, warningObjects); } - } + } // 发送告警数据 - if (warningObjects.size() > 0) { + int warningSize = this.getWarningSize(warningMap); + if ( warningSize > 0) { if ("0".equals(rule.getTodoType())) { - logger.info("A total of {} alarm information needs to be sent {}", warningObjects.size(), + logger.info("A total of {} alarm information needs to be sent {}", warningSize, rule.getConfigArgsDescriber().getMailInfo().getMailTo()); // 发送邮件 - String subjects = generateSubject(warningObjects.size(), + String subjects = generateSubject(userInfo.getUserName(), warningSize, rule.getPreviousFireTimeM(), currentFireMinuteTime); Map parameter = new HashMap(); - parameter.put("warningObjects", warningObjects); + + parameter.put("alarmTypeList", alarmTypeList); + parameter.put("warningMap", warningMap); parameter.put("name", userInfo.getUserName()); parameter.put("startDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date( rule.getPreviousFireTimeM() * 10000 * 6))); parameter.put("endDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date( currentFireMinuteTime * 10000 * 6))); - String mailContext = generateContent(mailTemplate, parameter); + + + String mailContext = generateContent(parameter); if (mailContext.length() > 0) { MailInfo mailInfo = rule.getConfigArgsDescriber() .getMailInfo(); @@ -113,8 +127,11 @@ public class AlarmMessageProcessor { currentFireMinuteTime); } - private String generateSubject(int count, long startTime, long endTime) { - String title = "[Warning] There were " + private String generateSubject(String userName, int count, long startTime, long endTime) { + //TODO:邮件标题修改,添加了名称 + String title = "[Warning] Dear " + + userName + + ", there were " + count + " alarm information between " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date( @@ -145,7 +162,7 @@ public class AlarmMessageProcessor { }); } - private void setAlarmMessages(final String key, final Collection warningTracingIds) { + private void setAlarmMessages(final String key, final Collection warningTracingIds) { RedisUtil.execute(new Executable() { @Override public Collection exe(Jedis client) { @@ -160,11 +177,23 @@ public class AlarmMessageProcessor { }); } - private String generateContent(String templateStr, Map parameter) throws IOException, TemplateException, SQLException { - Template t = null; - t = new Template(null, new StringReader(templateStr), TemplateConfigurationUtil.getConfiguration()); + private String generateContent(Map parameter) throws IOException, TemplateException, SQLException { + + if(t == null) { + t = TemplateConfigurationUtil.getConfiguration().getTemplate("mail-template.ftl"); + } StringWriter out = new StringWriter(); t.process(parameter, out); return out.getBuffer().toString(); - } + } + + private int getWarningSize(Map> warningMap) { + int result = 0; + for(Entry> entry :warningMap.entrySet()) { + if(entry.getValue() != null) { + result += entry.getValue().size(); + } + } + return result; + } } diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/AlarmTypeUtil.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/AlarmTypeUtil.java new file mode 100644 index 000000000..a459f63d9 --- /dev/null +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/AlarmTypeUtil.java @@ -0,0 +1,45 @@ +package com.ai.cloud.skywalking.alarm.util; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.ai.cloud.skywalking.alarm.conf.Config; +import com.ai.cloud.skywalking.alarm.dao.SystemConfigDao; +import com.ai.cloud.skywalking.alarm.model.AlarmType; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +public class AlarmTypeUtil { + + private static Logger logger = LogManager.getLogger(AlarmTypeUtil.class); + private static List alarmTypeList; + + static { + try { + String typeInfo = SystemConfigDao.getSystemConfig(Config.Alarm.ALARM_TYPE_CONFIG_ID); + alarmTypeList = new Gson().fromJson(typeInfo, new TypeToken>() { + }.getType()); + } catch (Exception e) { + logger.error("Failed to load alarm type info.", e); + System.exit(-1); + } + } + + public static List getAlarmTypeList() { + + if (alarmTypeList == null || alarmTypeList.isEmpty()) { + alarmTypeList = new ArrayList(); + } + + AlarmType defaultType = new AlarmType(); + defaultType.setType("default"); + defaultType.setLabel("mark"); + defaultType.setDesc("Others"); + alarmTypeList.add(defaultType); + + return alarmTypeList; + } +} diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/MailUtil.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/MailUtil.java index f30fdba81..c17a60ac6 100644 --- a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/MailUtil.java +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/MailUtil.java @@ -1,31 +1,37 @@ package com.ai.cloud.skywalking.alarm.util; +import java.util.Properties; + +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.NoSuchProviderException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import com.ai.cloud.skywalking.alarm.conf.Config; import com.ai.cloud.skywalking.alarm.dao.SystemConfigDao; import com.google.gson.Gson; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.mail.*; -import javax.mail.internet.AddressException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; -import java.util.Properties; public class MailUtil { private static Logger logger = LogManager.getLogger(MailUtil.class); - private static String sendAccount; + private static String mailSender; private static Properties config; static { try { String senderInfo = SystemConfigDao.getSystemConfig(Config.MailSenderInfo.configId); config = new Gson().fromJson(senderInfo, Properties.class); - sendAccount = config.getProperty("mail.username") + config.getProperty("mail.account.prefix"); + mailSender = config.getProperty("mail.sender"); } catch (Exception e) { - logger.error("Failed to connect the mail System.", e); + logger.error("Failed to load mail sender info.", e); System.exit(-1); } } @@ -38,7 +44,7 @@ public class MailUtil { ts = session.getTransport(); ts.connect(config.getProperty("mail.host"), config.getProperty("mail.username"), config.getProperty("mail.password")); MimeMessage message = new MimeMessage(session); - message.setFrom(new InternetAddress(sendAccount)); + message.setFrom(new InternetAddress(mailSender)); InternetAddress[] recipientAccountArray = new InternetAddress[recipientAccounts.length]; for (int i = 0; i < recipientAccounts.length; i++) { recipientAccountArray[i] = new InternetAddress(recipientAccounts[i]); diff --git a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/TemplateConfigurationUtil.java b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/TemplateConfigurationUtil.java index 12b3718e1..d63520fae 100644 --- a/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/TemplateConfigurationUtil.java +++ b/skywalking-alarm/src/main/java/com/ai/cloud/skywalking/alarm/util/TemplateConfigurationUtil.java @@ -1,22 +1,29 @@ package com.ai.cloud.skywalking.alarm.util; +import java.io.File; +import java.io.IOException; +import java.sql.SQLException; + import com.ai.cloud.skywalking.alarm.conf.Config; import com.ai.cloud.skywalking.alarm.dao.SystemConfigDao; + import freemarker.template.Configuration; import freemarker.template.TemplateModelException; import freemarker.template.Version; -import java.sql.SQLException; - public class TemplateConfigurationUtil { private static Configuration cfg; - public static Configuration getConfiguration() throws SQLException, TemplateModelException { + public static Configuration getConfiguration() throws SQLException, TemplateModelException, IOException { if (cfg == null) { cfg = new Configuration(new Version("2.3.23")); cfg.setDefaultEncoding("UTF-8"); cfg.setSharedVariable("portalAddr", SystemConfigDao.getSystemConfig(Config.TemplateInfo.CONFIG_ID)); + + //获取资源路径 + String classPath = cfg.getClass().getResource("/").getFile().toString(); + cfg.setDirectoryForTemplateLoading(new File(classPath)); } return cfg; diff --git a/skywalking-alarm/src/main/resources/config.properties b/skywalking-alarm/src/main/resources/config.properties index d854596d6..58f335892 100644 --- a/skywalking-alarm/src/main/resources/config.properties +++ b/skywalking-alarm/src/main/resources/config.properties @@ -59,11 +59,8 @@ alarm.redis_min_idle=1 alarm.redis_max_total=50 #是否关闭告警发送 alarm.alarm_off_flag=false - -#告警检查器:异常告警检查 -alarm.checker.turn_on_exception_checker=true -#告警检查器:执行时间超时告警检查 -alarm.checker.turn_on_execute_time_checker=true +#告警类型配置id +alarm.alarm_type_config_id=1004 #邮件发送配置id mailsenderinfo.configid=1000 diff --git a/skywalking-alarm/src/main/resources/mail-template.ftl b/skywalking-alarm/src/main/resources/mail-template.ftl new file mode 100644 index 000000000..ae7c767ca --- /dev/null +++ b/skywalking-alarm/src/main/resources/mail-template.ftl @@ -0,0 +1,124 @@ + + + + + + + templete1_welcome + + + + + +
+

Dear ${name!}:

+

    Our platform received alarm infomation between ${startDate!} to ${endDate!} as follows: +

+ + + + + + <#list alarmTypeList as alarmType> + <#if warningMap?exists> + <#if warningMap[alarmType.type]?exists> + + + + <#list warningMap[alarmType.type] as element> + + + + + + + + + + + + +

${alarmType.desc}

traceid

${element.traceid!}<#if element.date?exists>    ${element.date?string("yyyy-MM-dd HH:mm:ss ")}

${(alarmType.label)}

${element.exceptionMsg}

+ + + \ No newline at end of file