Package com.dianping.cat.report.task.alert.app

Source Code of com.dianping.cat.report.task.alert.app.AppAlert

package com.dianping.cat.report.task.alert.app;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.ArrayUtils;
import org.unidal.helper.Threads.Task;
import org.unidal.lookup.annotation.Inject;
import org.unidal.tuple.Pair;

import com.dianping.cat.Cat;
import com.dianping.cat.config.app.AppConfigManager;
import com.dianping.cat.config.app.AppDataService;
import com.dianping.cat.config.app.QueryEntity;
import com.dianping.cat.configuration.app.entity.Command;
import com.dianping.cat.helper.TimeHelper;
import com.dianping.cat.home.rule.entity.Condition;
import com.dianping.cat.home.rule.entity.Config;
import com.dianping.cat.home.rule.entity.MonitorRules;
import com.dianping.cat.home.rule.entity.Rule;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.report.task.alert.AlertResultEntity;
import com.dianping.cat.report.task.alert.AlertType;
import com.dianping.cat.report.task.alert.DataChecker;
import com.dianping.cat.report.task.alert.sender.AlertEntity;
import com.dianping.cat.report.task.alert.sender.AlertManager;
import com.dianping.cat.system.config.AppRuleConfigManager;

public class AppAlert implements Task {

  @Inject
  private AppDataService m_appDataService;

  @Inject
  private AlertManager m_sendManager;

  @Inject
  private AppRuleConfigManager m_appRuleConfigManager;

  @Inject
  private DataChecker m_dataChecker;

  @Inject
  private AppConfigManager m_appConfigManager;

  private static final long DURATION = TimeHelper.ONE_MINUTE * 5;

  private static final int DATA_AREADY_MINUTE = 10;

  private SimpleDateFormat m_sdf = new SimpleDateFormat("yyyy-MM-dd");

  @Override
  public void run() {
    boolean active = true;
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      active = false;
    }
    while (active) {
      Transaction t = Cat.newTransaction("AlertApp", TimeHelper.getMinuteStr());
      long current = System.currentTimeMillis();

      try {
        MonitorRules monitorRules = m_appRuleConfigManager.getMonitorRules();
        Map<String, Rule> rules = monitorRules.getRules();

        for (Entry<String, Rule> entry : rules.entrySet()) {
          try {
            processRule(entry.getValue());
          } catch (Exception e) {
            Cat.logError(e);
          }
        }
        t.setStatus(Transaction.SUCCESS);
      } catch (Exception e) {
        t.setStatus(e);
        Cat.logError(e);
      } finally {
        t.complete();
      }
      long duration = System.currentTimeMillis() - current;

      try {
        if (duration < DURATION) {
          Thread.sleep(DURATION - duration);
        }
      } catch (InterruptedException e) {
        active = false;
      }
    }
  }

  @Override
  public String getName() {
    return AlertType.App.getName();
  }

  @Override
  public void shutdown() {
  }

  private void processRule(Rule rule) {
    String id = rule.getId();
    int index1 = id.indexOf(":");
    int index2 = id.indexOf(":", index1 + 1);
    String conditions = id.substring(0, index1);
    String type = id.substring(index1 + 1, index2);
    String name = id.substring(index2 + 1);
    int command = Integer.valueOf(conditions.split(";")[0]);
    Pair<Integer, List<Condition>> pair = queryCheckMinuteAndConditions(rule.getConfigs());
    double[] datas = fetchDatas(conditions, type, pair.getKey());

    if (datas != null && datas.length > 0) {
      List<Condition> checkedConditions = pair.getValue();
      List<AlertResultEntity> alertResults = m_dataChecker.checkData(datas, checkedConditions);

      for (AlertResultEntity alertResult : alertResults) {
        Map<String, Object> par = new HashMap<String, Object>();
        par.put("name", name);
        AlertEntity entity = new AlertEntity();

        entity.setDate(alertResult.getAlertTime()).setContent(alertResult.getContent())
              .setLevel(alertResult.getAlertLevel());
        entity.setMetric(queryType(type)).setType(getName()).setGroup(queryCommand(command)).setParas(par);
        m_sendManager.addAlert(entity);
      }
    }
  }

  private Calendar queryDayPeriod(int day) {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DATE, day);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal;
  }

  private double[] fetchDatas(String conditions, String type, int minute) {
    long time = (System.currentTimeMillis()) / 1000 / 60;
    int endMinute = (int) (time % (60)) - DATA_AREADY_MINUTE;
    int startMinute = endMinute - minute;
    double[] datas = null;

    if (startMinute < 0 && endMinute < 0) {
      String period = m_sdf.format(queryDayPeriod(-1).getTime());
      QueryEntity queryEntity = new QueryEntity(period + ";" + conditions + ";;");
      datas = ArrayUtils.toPrimitive(m_appDataService.queryValue(queryEntity, type), 0);
    } else if (startMinute < 0 && endMinute >= 0) {
      String last = m_sdf.format(queryDayPeriod(-1).getTime());
      String current = m_sdf.format(queryDayPeriod(0).getTime());
      QueryEntity lastQueryEntity = new QueryEntity(last + ";" + conditions + ";;");
      QueryEntity currentQueryEntity = new QueryEntity(current + ";" + conditions + ";;");
      double[] lastDatas = ArrayUtils.toPrimitive(m_appDataService.queryValue(lastQueryEntity, type), 0);
      double[] currentDatas = ArrayUtils.toPrimitive(m_appDataService.queryValue(currentQueryEntity, type), 0);
      datas = mergerArray(lastDatas, currentDatas);
    } else if (startMinute >= 0) {
      String period = m_sdf.format(queryDayPeriod(0).getTime());
      QueryEntity queryEntity = new QueryEntity(period + ";" + conditions + ";;");
      datas = ArrayUtils.toPrimitive(m_appDataService.queryValue(queryEntity, type), 0);
    }
    return datas;
  }

  protected double[] mergerArray(double[] from, double[] to) {
    int fromLength = from.length;
    int toLength = to.length;
    double[] result = new double[fromLength + toLength];
    int index = 0;

    for (int i = 0; i < fromLength; i++) {
      result[i] = from[i];
      index++;
    }
    for (int i = 0; i < toLength; i++) {
      result[i + index] = to[i];
    }
    return result;
  }

  private String queryType(String type) {
    String title = "";

    if (AppDataService.SUCCESS.equals(type)) {
      title = "成功率(%/分钟)";
    } else if (AppDataService.REQUEST.equals(type)) {
      title = "请求数(个/分钟)";
    } else if (AppDataService.DELAY.equals(type)) {
      title = "延时平均值(毫秒/分钟)";
    }
    return title;
  }

  private String queryCommand(int command) {
    Map<Integer, Command> commands = m_appConfigManager.getRawCommands();
    Command value = commands.get(command);

    if (value != null) {
      return value.getName();
    } else {
      throw new RuntimeException("Error config in command code: " + command);
    }
  }

  private Pair<Integer, List<Condition>> queryCheckMinuteAndConditions(List<Config> configs) {
    int maxMinute = 0;
    List<Condition> conditions = new ArrayList<Condition>();
    Iterator<Config> iterator = configs.iterator();

    while (iterator.hasNext()) {
      Config config = iterator.next();

      if (judgeCurrentInConfigRange(config)) {
        List<Condition> tmpConditions = config.getConditions();
        conditions.addAll(tmpConditions);

        for (Condition con : tmpConditions) {
          int tmpMinute = con.getMinute();

          if (tmpMinute > maxMinute) {
            maxMinute = tmpMinute;
          }
        }
      }
    }
    return new Pair<Integer, List<Condition>>(maxMinute, conditions);
  }

  private boolean judgeCurrentInConfigRange(Config config) {
    long ruleStartTime;
    long ruleEndTime;
    Calendar cal = Calendar.getInstance();
    int hour = cal.get(Calendar.HOUR_OF_DAY);
    int minute = cal.get(Calendar.MINUTE);
    int nowTime = hour * 60 * 60 * 1000 + minute * 60 * 1000;

    try {
      ruleStartTime = buildMillsByString(config.getStarttime());
      ruleEndTime = buildMillsByString(config.getEndtime());
    } catch (Exception ex) {
      ruleStartTime = 0L;
      ruleEndTime = 86400000L;
    }

    if (nowTime < ruleStartTime || nowTime > ruleEndTime) {
      return false;
    }

    return true;
  }

  private Long buildMillsByString(String time) throws Exception {
    String[] times = time.split(":");
    int hour = Integer.parseInt(times[0]);
    int minute = Integer.parseInt(times[1]);
    long result = hour * 60 * 60 * 1000 + minute * 60 * 1000;

    return result;
  }
}
TOP

Related Classes of com.dianping.cat.report.task.alert.app.AppAlert

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.