package com.jthink.skyeye.web.task; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.jthink.skyeye.data.http.HttpRequest; import com.jthink.skyeye.data.rabbitmq.service.RabbitmqService; import com.jthink.skyeye.base.constant.Constants; import com.jthink.skyeye.base.constant.EventType; import com.jthink.skyeye.base.dto.AlertDto; import com.jthink.skyeye.base.util.DateUtil; import com.jthink.skyeye.web.constant.EsSqlTemplate; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.util.StopWatch; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * JThink@JThink * * @author JThink * @version 0.0.1 * @desc * @date 2016-12-01 17:07:37 */ @Configuration @EnableScheduling @ConfigurationProperties(prefix = "spring.monitor.es") public class MonitorTask { private static final Logger LOGGER = LoggerFactory.getLogger(MonitorTask.class); @Autowired private RabbitmqService rabbitmqService; private String mail; private int interval; private String url; private String middlewareResponseTime; private double middlewareThreshold; private String thirdResponseTime; private double thirdThreshold; private String totalTemplate; private String template; private String apiResponseTime; private double apiThreshold; private int delay; /** * 根据传递的sql语句查询es * @param sql * @return */ private String query(String sql) { String response = HttpRequest.get(this.url, sql); return response; } /** * 对第三方进行监控报警 */ @Scheduled(cron = "${spring.monitor.es.window}") private void monitorThirdParty() { LOGGER.info("开始对第三方进行监控"); StopWatch sw = new StopWatch(); sw.start(); long timestamp = System.currentTimeMillis(); String scope = "uniqueName"; Map<String, Integer> thirdTotalInfos = this.parseRealtimeData(this.query(this.buildSql(this.totalTemplate, timestamp, scope, this.thirdResponseTime, EventType.thirdparty_call)), scope); Map<String, Integer> thirdInfos = this.parseRealtimeData(this.query(this.buildSql(this.template, timestamp, scope, this.thirdResponseTime, EventType.thirdparty_call)), scope); for (Map.Entry<String, Integer> entry : thirdInfos.entrySet()) { String third = entry.getKey(); int cnt = entry.getValue(); if ((double) cnt / thirdTotalInfos.get(third) > this.thirdThreshold) { // 超过阈值,需要报警 LOGGER.info("{} 需要报警", third); this.rabbitmqService.sendMessage(this.buildMsg(third, timestamp, third), this.mail); } } sw.stop(); LOGGER.info("结束对第三方进行监控, 耗时: {}ms", sw.getTotalTimeMillis()); } /** * 对中间件进行监控报警 */ @Scheduled(cron = "${spring.monitor.es.window}") private void monitorMiddleWare() { LOGGER.info("开始对中间件进行监控"); StopWatch sw = new StopWatch(); sw.start(); long timestamp = System.currentTimeMillis(); String scope = "uniqueName"; Map<String, Integer> middlewareTotalInfos = this.parseRealtimeData(this.query(this.buildSql(this.totalTemplate, timestamp, scope, this.middlewareResponseTime, EventType.middleware_opt)), scope); Map<String, Integer> middlewareInfos = this.parseRealtimeData(this.query(this.buildSql(this.template, timestamp, scope, this.middlewareResponseTime, EventType.middleware_opt)), scope); for (Map.Entry<String, Integer> entry : middlewareInfos.entrySet()) { String middleware = entry.getKey(); int cnt = entry.getValue(); if ((double) cnt / middlewareTotalInfos.get(middleware) > this.middlewareThreshold) { // 超过阈值,需要报警 LOGGER.info("{} 需要报警", middleware); this.rabbitmqService.sendMessage(this.buildMsg(middleware, timestamp, middleware), this.mail); } } sw.stop(); LOGGER.info("结束对中间件进行监控, 耗时: {}ms", sw.getTotalTimeMillis()); } /** * 对api进行监控报警 */ @Scheduled(cron = "${spring.monitor.es.window}") private void monitorApi() { LOGGER.info("开始对api进行监控"); StopWatch sw = new StopWatch(); sw.start(); long timestamp = System.currentTimeMillis(); String scope = "app"; Map<String, Integer> appTotalInfos = this.parseRealtimeData(this.query(this.buildSql(this.totalTemplate, timestamp, scope, this.apiResponseTime, EventType.invoke_interface)), scope); Map<String, Integer> appInfos = this.parseRealtimeData(this.query(this.buildSql(this.template, timestamp, scope, this.apiResponseTime, EventType.invoke_interface)), scope); for (Map.Entry<String, Integer> entry : appInfos.entrySet()) { String app = entry.getKey(); int cnt = entry.getValue(); if ((double) cnt / appTotalInfos.get(app) > this.apiThreshold) { // 超过阈值,需要报警 LOGGER.info("{} 需要报警", app); this.rabbitmqService.sendMessage(this.buildMsg(app, timestamp, Constants.API), this.mail); } } sw.stop(); LOGGER.info("结束对api进行监控, 耗时: {}ms", sw.getTotalTimeMillis()); } /** * 构造dto以及msg * @param app * @param timestamp * @param key * @return */ private String buildMsg(String app, long timestamp, String key) { AlertDto alertDto = new AlertDto(); alertDto.setApp(app); alertDto.setMsg(key + Constants.WECHAT_ALERT_RESPONSE_EXCEED); alertDto.setTime(new DateTime(timestamp).toString(DateUtil.YYYYMMDDHHMMSS)); return alertDto.toString(); } /** * 根据时间、scope和响应时间限制构造sql * @param template * @param timestamp * @param scope * @param responseTime * @return */ private String buildSql(String template, long timestamp, String scope, String responseTime, EventType eventType) { String sql = template.replace(EsSqlTemplate.EVENTTYPE, eventType.symbol()) .replace(EsSqlTemplate.BEGIN, this.getBegin(timestamp)).replace(EsSqlTemplate.END, this.getEnd(timestamp)) .replace(EsSqlTemplate.SCOPE, scope).replace(EsSqlTemplate.COST, responseTime); return sql; } /** * 根据es sql返回的结果进行解析 * @param response * @return */ private Map<String, Integer> parseRealtimeData(String response, String scope) { Map<String , Integer> apps = new HashMap<String, Integer>(); if (null == response) { // 错误 return apps; } else { JSONObject json = JSON.parseObject(response); Iterator<Object> iterator = json.getJSONObject("aggregations").getJSONObject(scope).getJSONArray("buckets").iterator(); while (iterator.hasNext()) { JSONObject jsonObject = ((JSONObject)iterator.next()); String app = jsonObject.getString("key"); int cnt = jsonObject.getIntValue("doc_count"); apps.put(app, cnt); } return apps; } } /** * 根据时间戳获取结束时间 * @param timestamp * @return */ private String getEnd(long timestamp) { DateTime end = new DateTime(timestamp).minusSeconds(this.delay); return end.toString(DateUtil.YYYYMMDDHHMMSS); } /** * 根据时间戳获取开始时间 * @param timestamp * @return */ private String getBegin(long timestamp) { DateTime end = new DateTime(timestamp).minusSeconds(this.delay); DateTime begin = end.minusMinutes(this.interval); return begin.toString(DateUtil.YYYYMMDDHHMMSS); } public String getMail() { return mail; } public void setMail(String mail) { this.mail = mail; } public int getInterval() { return interval; } public void setInterval(int interval) { this.interval = interval; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMiddlewareResponseTime() { return middlewareResponseTime; } public void setMiddlewareResponseTime(String middlewareResponseTime) { this.middlewareResponseTime = middlewareResponseTime; } public double getMiddlewareThreshold() { return middlewareThreshold; } public void setMiddlewareThreshold(double middlewareThreshold) { this.middlewareThreshold = middlewareThreshold; } public String getThirdResponseTime() { return thirdResponseTime; } public void setThirdResponseTime(String thirdResponseTime) { this.thirdResponseTime = thirdResponseTime; } public double getThirdThreshold() { return thirdThreshold; } public void setThirdThreshold(double thirdThreshold) { this.thirdThreshold = thirdThreshold; } public String getTotalTemplate() { return totalTemplate; } public void setTotalTemplate(String totalTemplate) { this.totalTemplate = totalTemplate; } public String getTemplate() { return template; } public void setTemplate(String template) { this.template = template; } public String getApiResponseTime() { return apiResponseTime; } public void setApiResponseTime(String apiResponseTime) { this.apiResponseTime = apiResponseTime; } public double getApiThreshold() { return apiThreshold; } public void setApiThreshold(double apiThreshold) { this.apiThreshold = apiThreshold; } public int getDelay() { return delay; } public void setDelay(int delay) { this.delay = delay; } }