提交 e7519703 编写于 作者: Y youyong205

Merge branch 'master' of github.com:dianping/cat

......@@ -13,8 +13,8 @@ import org.unidal.lookup.configuration.Component;
import com.dianping.cat.CatHomeModule;
import com.dianping.cat.ServerConfigManager;
import com.dianping.cat.config.app.AppDataService;
import com.dianping.cat.config.app.AppDataCommandTableProvider;
import com.dianping.cat.config.app.AppDataService;
import com.dianping.cat.consumer.dependency.DependencyAnalyzer;
import com.dianping.cat.consumer.metric.MetricAnalyzer;
import com.dianping.cat.consumer.metric.MetricConfigManager;
......@@ -24,6 +24,7 @@ import com.dianping.cat.core.config.ConfigDao;
import com.dianping.cat.core.dal.HostinfoDao;
import com.dianping.cat.core.dal.ProjectDao;
import com.dianping.cat.home.dal.report.AlertDao;
import com.dianping.cat.home.dal.report.AlertSummaryDao;
import com.dianping.cat.home.dal.report.EventDao;
import com.dianping.cat.home.dal.report.TopologyGraphDao;
import com.dianping.cat.report.baseline.BaselineService;
......@@ -65,6 +66,14 @@ import com.dianping.cat.report.task.alert.exception.ExceptionAlert;
import com.dianping.cat.report.task.alert.exception.ExceptionAlertConfig;
import com.dianping.cat.report.task.alert.network.NetworkAlert;
import com.dianping.cat.report.task.alert.network.NetworkAlertConfig;
import com.dianping.cat.report.task.alert.sender.MailSender;
import com.dianping.cat.report.task.alert.sender.SmsSender;
import com.dianping.cat.report.task.alert.sender.WeixinSender;
import com.dianping.cat.report.task.alert.summary.AlertSummaryDecorator;
import com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor;
import com.dianping.cat.report.task.alert.summary.AlertSummaryFTLDecorator;
import com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator;
import com.dianping.cat.report.task.alert.summary.AlertSummaryManager;
import com.dianping.cat.report.task.alert.system.SystemAlert;
import com.dianping.cat.report.task.alert.system.SystemAlertConfig;
import com.dianping.cat.report.task.product.ProjectUpdateTask;
......@@ -87,8 +96,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
public static void main(String[] args) {
generatePlexusComponentsXmlFile(new ComponentsConfigurator());
}
private List<Component> defineAlertComponents() {
List<Component> all = new ArrayList<Component>();
......@@ -121,7 +129,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
return all;
}
private List<Component> defineCommonComponents() {
List<Component> all = new ArrayList<Component>();
......@@ -139,7 +147,6 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(EventCollectManager.class).req(EventDao.class, ServerConfigManager.class));
all.add(C(TopologyGraphItemBuilder.class).req(TopologyGraphConfigManager.class));
all.add(C(TopologyGraphBuilder.class).req(TopologyGraphItemBuilder.class).is(PER_LOOKUP));
......@@ -147,13 +154,11 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(TopologyGraphManager.class).req(TopologyGraphBuilder.class, ServerConfigManager.class) //
.req(ProductLineConfigManager.class, TopologyGraphDao.class, DomainNavManager.class)//
.req(ModelService.class, DependencyAnalyzer.ID));
// update project database
all.add(C(ProjectUpdateTask.class)//
.req(ProjectDao.class, HostinfoDao.class));
return all;
}
......@@ -162,17 +167,17 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
List<Component> all = new ArrayList<Component>();
all.addAll(defineCommonComponents());
all.addAll(defineConfigComponents());
all.addAll(defineMetricComponents());
all.addAll(defineAlertComponents());
all.add(C(Module.class, CatHomeModule.ID, CatHomeModule.class));
all.add(C(ModuleManager.class, DefaultModuleManager.class) //
.config(E("topLevelModules").value(CatHomeModule.ID)));
// report serivce
all.addAll(new ReportServiceComponentConfigurator().defineComponents());
// task
......@@ -181,7 +186,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
// model service
all.addAll(new ServiceComponentConfigurator().defineComponents());
all.add(C(TableProvider.class,"app-data-command",AppDataCommandTableProvider.class));
all.add(C(TableProvider.class, "app-data-command", AppDataCommandTableProvider.class));
// database
all.add(C(JdbcDataSourceDescriptorManager.class) //
.config(E("datasourceFile").value("/data/appdatas/cat/datasources.xml")));
......@@ -197,10 +202,10 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
return all;
}
private List<Component> defineConfigComponents(){
private List<Component> defineConfigComponents() {
List<Component> all = new ArrayList<Component>();
all.add(C(TopologyGraphConfigManager.class).req(ConfigDao.class));
all.add(C(ExceptionConfigManager.class).req(ConfigDao.class));
all.add(C(DomainGroupConfigManager.class).req(ConfigDao.class));
......@@ -211,10 +216,11 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(AlertConfigManager.class).req(ConfigDao.class));
all.add(C(NetGraphConfigManager.class).req(ConfigDao.class));
all.add(C(ConfigReloadTask.class).req(MetricConfigManager.class, ProductLineConfigManager.class));
return all;
}
private List<Component> defineMetricComponents(){
private List<Component> defineMetricComponents() {
List<Component> all = new ArrayList<Component>();
all.add(C(IpService.class));
......@@ -228,7 +234,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
MetricGroupConfigManager.class, AlertInfo.class));
all.add(C(MetricGraphCreator.class).req(CachedMetricReportService.class, DataExtractor.class,
MetricDataFetcher.class).req(BaselineService.class, MetricConfigManager.class,
ProductLineConfigManager.class, MetricGroupConfigManager.class, AlertInfo.class));
ProductLineConfigManager.class, MetricGroupConfigManager.class, AlertInfo.class, ProjectDao.class));
all.add(C(SystemGraphCreator.class).req(CachedMetricReportService.class, DataExtractor.class,
MetricDataFetcher.class).req(BaselineService.class, MetricConfigManager.class,
ProductLineConfigManager.class, MetricGroupConfigManager.class, AlertInfo.class));
......@@ -266,23 +272,48 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(DataChecker.class, DefaultDataChecker.class));
all.add(C(BusinessAlert.class).req(MetricConfigManager.class, ProductLineConfigManager.class,
BaselineService.class, MailSMS.class, BusinessAlertConfig.class, AlertInfo.class, AlertDao.class)//
.req(RemoteMetricReportService.class, BusinessRuleConfigManager.class, DataChecker.class));
all.add(C(MailSender.class).req(MailSMS.class));
all.add(C(NetworkAlert.class).req(MetricConfigManager.class, ProductLineConfigManager.class,
BaselineService.class, MailSMS.class, NetworkAlertConfig.class, AlertInfo.class, AlertDao.class)//
.req(RemoteMetricReportService.class, NetworkRuleConfigManager.class, DataChecker.class));
all.add(C(SmsSender.class).req(MailSMS.class));
all.add(C(SystemAlert.class).req(MetricConfigManager.class, ProductLineConfigManager.class,
BaselineService.class, MailSMS.class, SystemAlertConfig.class, AlertInfo.class, AlertDao.class)//
.req(RemoteMetricReportService.class, SystemRuleConfigManager.class, DataChecker.class));
all.add(C(WeixinSender.class).req(MailSMS.class));
all.add(C(BusinessAlert.class)
.req(MetricConfigManager.class, ProductLineConfigManager.class, BaselineService.class, MailSMS.class,
BusinessAlertConfig.class, AlertInfo.class, AlertDao.class)
//
.req(RemoteMetricReportService.class, BusinessRuleConfigManager.class, DataChecker.class, ProjectDao.class)
.req(MailSender.class, SmsSender.class, WeixinSender.class));
all.add(C(NetworkAlert.class)
.req(MetricConfigManager.class, ProductLineConfigManager.class, BaselineService.class, MailSMS.class,
NetworkAlertConfig.class, AlertInfo.class, AlertDao.class)
//
.req(RemoteMetricReportService.class, NetworkRuleConfigManager.class, DataChecker.class, ProjectDao.class)
.req(MailSender.class, SmsSender.class, WeixinSender.class));
all.add(C(SystemAlert.class)
.req(MetricConfigManager.class, ProductLineConfigManager.class, BaselineService.class, MailSMS.class,
SystemAlertConfig.class, AlertInfo.class, AlertDao.class)
//
.req(RemoteMetricReportService.class, SystemRuleConfigManager.class, DataChecker.class, ProjectDao.class)
.req(MailSender.class, SmsSender.class, WeixinSender.class));
all.add(C(AlertExceptionBuilder.class).req(ExceptionConfigManager.class));
all.add(C(ExceptionAlert.class).req(ProjectDao.class, ExceptionAlertConfig.class, MailSMS.class,
ExceptionConfigManager.class, AlertExceptionBuilder.class, AlertDao.class).req(ModelService.class,
TopAnalyzer.ID));
all.add(C(ExceptionAlert.class)
.req(ProjectDao.class, ExceptionAlertConfig.class, MailSMS.class, ExceptionConfigManager.class,
AlertExceptionBuilder.class, AlertDao.class).req(ModelService.class, TopAnalyzer.ID)
.req(MailSender.class, SmsSender.class, WeixinSender.class));
all.add(C(AlertSummaryExecutor.class).req(AlertSummaryGenerator.class, AlertSummaryManager.class, MailSMS.class)
.req(AlertSummaryDecorator.class, AlertSummaryFTLDecorator.ID));
all.add(C(AlertSummaryDecorator.class, AlertSummaryFTLDecorator.ID, AlertSummaryFTLDecorator.class));
all.add(C(AlertSummaryGenerator.class).req(AlertDao.class, TopologyGraphManager.class));
all.add(C(AlertSummaryManager.class).req(AlertSummaryDao.class));
all.add(C(NetGraphConfigManager.class).req(ConfigDao.class));
......
......@@ -53,7 +53,8 @@ com.dianping.cat.report.page.system.Handler.class,
com.dianping.cat.report.page.cdn.Handler.class,
com.dianping.cat.report.page.app.Handler.class
com.dianping.cat.report.page.app.Handler.class,
})
public class ReportModule extends AbstractModule {
......
......@@ -51,7 +51,9 @@ public enum ReportPage implements Page {
CDN("cdn", "cdn", "Cdn", "Cdn", true),
APP("app", "app", "App", "App", true);
APP("app", "app", "App", "App", true),
SUMMARY("summary", "summary", "Summary", "Summary", true);
private String m_name;
......
......@@ -11,30 +11,73 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.advanced.metric.config.entity.MetricItemConfig;
import com.dianping.cat.consumer.company.model.entity.ProductLine;
import com.dianping.cat.consumer.metric.model.entity.MetricReport;
import com.dianping.cat.core.dal.Project;
import com.dianping.cat.core.dal.ProjectDao;
import com.dianping.cat.core.dal.ProjectEntity;
import com.dianping.cat.helper.Chinese;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.metric.group.entity.MetricKeyConfig;
import com.dianping.cat.report.chart.AbstractGraphCreator;
import com.dianping.cat.report.page.LineChart;
import com.dianping.cat.report.task.alert.AlertInfo.AlertMetric;
import com.dianping.cat.report.task.alert.MetricType;
import com.site.lookup.util.StringUtils;
public class MetricGraphCreator extends AbstractGraphCreator {
@Inject
private ProjectDao m_projectDao;
protected String buildContactInfo(String domainName) {
try {
Project project = m_projectDao.findByDomain(domainName, ProjectEntity.READSET_FULL);
String owners = project.getOwner();
String phones = project.getPhone();
StringBuilder builder = new StringBuilder();
if (!StringUtils.isEmpty(owners)) {
builder.append("[负责人: ").append(owners);
}
if (!StringUtils.isEmpty(phones)) {
builder.append(" 手机: ").append(phones).append(" ]");
}
return builder.toString();
} catch (Exception ex) {
Cat.logError("build contact info error for doamin: " + domainName, ex);
}
return null;
}
private String extractDomain(String metricKey) {
try {
return metricKey.split(":")[0];
} catch (Exception ex) {
Cat.logError("extract domain error:" + metricKey, ex);
return null;
}
}
public Map<String, LineChart> buildChartData(final Map<String, double[]> datas, Date startDate, Date endDate,
final Map<String, double[]> dataWithOutFutures) {
Map<String, LineChart> charts = new LinkedHashMap<String, LineChart>();
List<String> alertKeys = m_alertInfo.queryLastestAlarmKey(5);
List<AlertMetric> alertKeys = m_alertInfo.queryLastestAlarmKey(5);
int step = m_dataExtractor.getStep();
for (Entry<String, double[]> entry : dataWithOutFutures.entrySet()) {
String key = entry.getKey();
String contactInfo = buildContactInfo(extractDomain(key));
double[] value = entry.getValue();
LineChart lineChart = new LineChart();
buildLineChartTitle(alertKeys, lineChart, key);
buildLineChartTitle(alertKeys, lineChart, key, contactInfo);
lineChart.setStart(startDate);
lineChart.setSize(value.length);
lineChart.setStep(step * TimeUtil.ONE_MINUTE);
......@@ -57,7 +100,7 @@ public class MetricGraphCreator extends AbstractGraphCreator {
Map<String, double[]> dataWithOutFutures = removeFutureData(endDate, allCurrentValues);
return buildChartData(oldCurrentValues, startDate, endDate, dataWithOutFutures);
}
private Map<String, double[]> prepareAllData(String productLine, Date startDate, Date endDate) {
long start = startDate.getTime(), end = endDate.getTime();
int totalSize = (int) ((end - start) / TimeUtil.ONE_MINUTE);
......@@ -72,7 +115,6 @@ public class MetricGraphCreator extends AbstractGraphCreator {
}
return oldCurrentValues;
}
private Map<String, double[]> queryMetricValueByDate(String productLine, long start) {
MetricReport metricReport = m_metricReportService.queryMetricReport(productLine, new Date(start));
......@@ -199,7 +241,7 @@ public class MetricGraphCreator extends AbstractGraphCreator {
}
return false;
}
private String queryMetricItemDes(String type) {
String des = "";
......@@ -213,7 +255,7 @@ public class MetricGraphCreator extends AbstractGraphCreator {
return des;
}
private void buildLineChartTitle(List<String> alertKeys, LineChart chart, String key) {
private void buildLineChartTitle(List<AlertMetric> alertKeys, LineChart chart, String key, String contactInfo) {
int index = key.lastIndexOf(":");
String metricId = key.substring(0, index);
String type = key.substring(index + 1);
......@@ -225,14 +267,24 @@ public class MetricGraphCreator extends AbstractGraphCreator {
chart.setTitle(title);
chart.setId(metricId + ":" + type);
if (alertKeys.contains(metricId)) {
chart.setHtmlTitle("<span style='color:red'>" + title + "</span>");
if (containMetric(alertKeys, metricId)) {
chart.setHtmlTitle("<span style='color:red'>" + title + "<br><small>" + contactInfo + "</small></span>");
} else {
chart.setHtmlTitle(title);
chart.setHtmlTitle(title + "<br><small>" + contactInfo + "</small>");
}
}
}
private boolean containMetric(List<AlertMetric> alertKeys, String metricId) {
for (AlertMetric alertMetric : alertKeys) {
if (alertMetric.getMetricId().equals(metricId)) {
return true;
}
}
return false;
}
private Map<String, double[]> buildGraphData(MetricReport metricReport, List<MetricItemConfig> metricConfigs) {
Map<String, double[]> datas = m_pruductDataFetcher.buildGraphData(metricReport);
Map<String, double[]> values = new LinkedHashMap<String, double[]>();
......
......@@ -15,15 +15,16 @@ import com.dianping.cat.consumer.metric.model.entity.MetricReport;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.chart.AbstractGraphCreator;
import com.dianping.cat.report.page.LineChart;
import com.dianping.cat.report.task.alert.AlertInfo.AlertMetric;
import com.dianping.cat.report.task.alert.MetricType;
public class NetworkGraphCreator extends AbstractGraphCreator {
public Map<String, LineChart> buildChartData(final Map<String, double[]> datas, Date startDate, Date endDate,
final Map<String, double[]> dataWithOutFutures) {
public Map<String, LineChart> buildChartData(String productLine, final Map<String, double[]> datas, Date startDate,
Date endDate, final Map<String, double[]> dataWithOutFutures) {
Map<String, List<String>> aggregationKeys = buildLineChartKeys(dataWithOutFutures.keySet());
Map<String, LineChart> charts = new LinkedHashMap<String, LineChart>();
List<String> alertKeys = m_alertInfo.queryLastestAlarmKey(5);
List<AlertMetric> alertKeys = m_alertInfo.queryLastestAlarmKey(5);
int step = m_dataExtractor.getStep();
for (Entry<String, List<String>> keyMapEntry : aggregationKeys.entrySet()) {
......@@ -41,7 +42,7 @@ public class NetworkGraphCreator extends AbstractGraphCreator {
Map<Long, Double> all = convertToMap(datas.get(key), startDate, 1);
Map<Long, Double> current = convertToMap(dataWithOutFutures.get(key), startDate, step);
buildLineChartTitle(lineChart, key, alertKeys);
buildLineChartTitle(productLine, lineChart, key, alertKeys);
addLastMinuteData(current, all, m_lastMinute, endDate);
convertFlowMetric(lineChart, current, buildLineTitle(key));
} else {
......@@ -53,12 +54,12 @@ public class NetworkGraphCreator extends AbstractGraphCreator {
return charts;
}
private void buildLineChartTitle(LineChart lineChart, String key, List<String> alertKeys) {
private void buildLineChartTitle(String productLine, LineChart lineChart, String key, List<AlertMetric> alertKeys) {
String title = lineChart.getHtmlTitle();
String realKey = key.substring(0, key.lastIndexOf(":"));
// alertKeys格式 = [domain:Metric:key]
if (alertKeys.contains(realKey) && !title.startsWith("<span style='color:red'>")) {
if (containsAlert(productLine, realKey, alertKeys) && !title.startsWith("<span style='color:red'>")) {
lineChart.setHtmlTitle("<span style='color:red'>" + title + "</span>");
} else {
lineChart.setHtmlTitle(title);
......@@ -70,7 +71,17 @@ public class NetworkGraphCreator extends AbstractGraphCreator {
Map<String, double[]> allCurrentValues = m_dataExtractor.extract(oldCurrentValues);
Map<String, double[]> dataWithOutFutures = removeFutureData(endDate, allCurrentValues);
return buildChartData(oldCurrentValues, startDate, endDate, dataWithOutFutures);
return buildChartData(productLine, oldCurrentValues, startDate, endDate, dataWithOutFutures);
}
private boolean containsAlert(String productLine, String key, List<AlertMetric> metrics) {
for (AlertMetric metric : metrics) {
if (metric.getGroup().equals(productLine) && metric.getMetricId().equals(key)) {
return true;
}
}
return false;
}
private Map<String, double[]> prepareAllData(String productLine, Date startDate, Date endDate) {
......
......@@ -14,12 +14,14 @@ import com.dianping.cat.home.nettopo.entity.NetGraph;
import com.dianping.cat.home.nettopo.entity.NetGraphSet;
import com.dianping.cat.home.nettopo.entity.NetTopology;
import com.dianping.cat.home.nettopo.entity.Switch;
import com.dianping.cat.report.task.alert.AlertInfo.AlertMetric;
public class NetGraphBuilder {
private static final int ERROR = 3;
public NetGraphSet buildGraphSet(NetGraph netGraphTemplate, Map<String, MetricReport> reports, List<String> alertKeys) {
public NetGraphSet buildGraphSet(NetGraph netGraphTemplate, Map<String, MetricReport> reports,
List<AlertMetric> alertKeys) {
NetGraphSet netGraphSet = new NetGraphSet();
for (int minute = 0; minute <= 59; minute++) {
......@@ -49,7 +51,7 @@ public class NetGraphBuilder {
return netGraphSet;
}
private void buildConnectionInfo(Map<String, MetricReport> reports, List<String> alertKeys, int minute,
private void buildConnectionInfo(Map<String, MetricReport> reports, List<AlertMetric> alertKeys, int minute,
List<String> alertSwitchs, Connection connection) {
double insum = 0, outsum = 0, inDiscardsSum = 0, outDiscardsSum = 0, inErrorsSum = 0, outErrorsSum = 0;
int inState = 0, outState = 0, inDiscardsState = 0, outDiscardsState = 0, inErrorsState = 0, outErrorsState = 0;
......@@ -62,27 +64,27 @@ public class NetGraphBuilder {
updateInterface(inter, report, minute);
if (inAlert(alertKeys, domain, key)) {
if (containsAlert(alertKeys, group, domain, key, "-flow-in")) {
inter.setInstate(ERROR);
inState = ERROR;
}
if (inDiscardsAlert(alertKeys, domain, key)) {
if (containsAlert(alertKeys, group, domain, key, "-discard/error-indiscards")) {
inter.setInDiscardsState(ERROR);
inDiscardsState = ERROR;
}
if (inErrorsAlert(alertKeys, domain, key)) {
if (containsAlert(alertKeys, group, domain, key, "-discard/error-inerrors")) {
inter.setInErrorsState(ERROR);
inErrorsState = ERROR;
}
if (outAlert(alertKeys, domain, key)) {
if (containsAlert(alertKeys, group, domain, key, "-flow-out")) {
inter.setOutstate(ERROR);
outState = ERROR;
}
if (outDiscardsAlert(alertKeys, domain, key)) {
if (containsAlert(alertKeys, group, domain, key, "-discard/error-outdiscards")) {
inter.setOutDiscardsState(ERROR);
outDiscardsState = ERROR;
}
if (outErrorsAlert(alertKeys, domain, key)) {
if (containsAlert(alertKeys, group, domain, key, "-discard/error-outerrors")) {
inter.setOutErrorsState(ERROR);
outErrorsState = ERROR;
}
......@@ -106,35 +108,23 @@ public class NetGraphBuilder {
connection.setOutDiscardsState(outDiscardsState);
connection.setInErrorsState(inErrorsState);
connection.setOutErrorsState(outErrorsState);
if (inState == ERROR || outState == ERROR || inDiscardsState == ERROR || outDiscardsState == ERROR
|| inErrorsState == ERROR || outErrorsState == ERROR) {
alertSwitchs.add(connection.getFrom());
}
}
private boolean inAlert(List<String> alertKeys, String domain, String key) {
return alertKeys.contains(domain + ":Metric:" + key + "-flow-in");
}
private boolean inDiscardsAlert(List<String> alertKeys, String domain, String key) {
return alertKeys.contains(domain + ":Metric:" + key + "-discard/error-indiscards");
}
private boolean inErrorsAlert(List<String> alertKeys, String domain, String key) {
return alertKeys.contains(domain + ":Metric:" + key + "-discard/error-inerrors");
}
private boolean containsAlert(List<AlertMetric> alertKeys, String group, String domain, String key, String suffix) {
String actualKey = domain + ":Metric:" + key + suffix;
private boolean outAlert(List<String> alertKeys, String domain, String key) {
return alertKeys.contains(domain + ":Metric:" + key + "-flow-out");
}
private boolean outDiscardsAlert(List<String> alertKeys, String domain, String key) {
return alertKeys.contains(domain + ":Metric:" + key + "-discard/error-outdiscards");
}
for (AlertMetric metric : alertKeys) {
if (metric.getGroup().equals(group) && metric.getMetricId().equals(actualKey)) {
return true;
}
}
private boolean outErrorsAlert(List<String> alertKeys, String domain, String key) {
return alertKeys.contains(domain + ":Metric:" + key + "-discard/error-outerrors");
return false;
}
private NetGraph copyBaseInfoFromTemplate(NetGraph netGraph) {
......
......@@ -32,6 +32,7 @@ import com.dianping.cat.message.Transaction;
import com.dianping.cat.report.page.JsonBuilder;
import com.dianping.cat.report.service.ReportService;
import com.dianping.cat.report.task.alert.AlertInfo;
import com.dianping.cat.report.task.alert.AlertInfo.AlertMetric;
import com.dianping.cat.report.task.alert.RemoteMetricReportService;
import com.dianping.cat.service.ModelRequest;
import com.dianping.cat.system.config.NetGraphConfigManager;
......@@ -49,13 +50,13 @@ public class NetGraphManager implements Initializable, LogEnabled {
@Inject
private NetGraphBuilder m_netGraphBuilder;
@Inject
private AlertInfo m_alertInfo;
@Inject
private NetGraphConfigManager m_netGraphConfigManager;
private NetGraphSet m_currentNetGraphSet;
private NetGraphSet m_lastNetGraphSet;
......@@ -109,18 +110,17 @@ public class NetGraphManager implements Initializable, LogEnabled {
}
private Set<String> queryAllGroups(NetGraph netGraphTemplate) {
Set<String> groups = new HashSet<String>();
for (NetTopology netTopology : netGraphTemplate.getNetTopologies()) {
for (Connection connection : netTopology.getConnections()) {
for (Interface inter : connection.getInterfaces()) {
groups.add(inter.getGroup());
}
}
}
return groups;
}
Set<String> groups = new HashSet<String>();
for (NetTopology netTopology : netGraphTemplate.getNetTopologies()) {
for (Connection connection : netTopology.getConnections()) {
for (Interface inter : connection.getInterfaces()) {
groups.add(inter.getGroup());
}
}
}
return groups;
}
private Map<String, MetricReport> queryMetricReports(Set<String> groups, Date date) {
Map<String, MetricReport> reports = new HashMap<String, MetricReport>();
......@@ -154,19 +154,21 @@ public class NetGraphManager implements Initializable, LogEnabled {
minuteStr = '0' + minuteStr;
}
Transaction t = Cat.newTransaction("NetGraph", "M" + minuteStr);
try {
NetGraph netGraphTemplate = m_netGraphConfigManager.getConfig().getNetGraphs().get(0);
Set<String> groups = queryAllGroups(netGraphTemplate);
Map<String, MetricReport> currentMetricReports = queryMetricReports(groups, TimeUtil.getCurrentHour());
List<String> alertKeys = m_alertInfo.queryLastestAlarmKey(5);
m_currentNetGraphSet = m_netGraphBuilder.buildGraphSet(netGraphTemplate, currentMetricReports, alertKeys);
List<AlertMetric> alertKeys = m_alertInfo.queryLastestAlarmKey(5);
m_currentNetGraphSet = m_netGraphBuilder
.buildGraphSet(netGraphTemplate, currentMetricReports, alertKeys);
Date lastHour = new Date(TimeUtil.getCurrentHour().getTime() - TimeUtil.ONE_HOUR);
Map<String, MetricReport> lastHourReports = queryMetricReports(groups, lastHour);
m_lastNetGraphSet = m_netGraphBuilder.buildGraphSet(netGraphTemplate, lastHourReports, new ArrayList<String>());
m_lastNetGraphSet = m_netGraphBuilder.buildGraphSet(netGraphTemplate, lastHourReports,
new ArrayList<AlertMetric>());
t.setStatus(Transaction.SUCCESS);
} catch (Exception e) {
t.setStatus(e);
......
......@@ -20,14 +20,16 @@ public enum Action implements org.unidal.web.mvc.Action {
UTILIZATION_REPORT(Constants.REPORT_UTILIZATION),
UTILIZATION_HISTORY_REPORT("historyUtilization"),
ALERT_REPORT(Constants.REPORT_ALERT),
ALERT_REPORT_DETAIL("alertDetail"),
ALERT_HISTORY_REPORT_DETAIL("historyAlertDetail"),
ALERT_HISTORY_REPORT("historyAlert");
ALERT_HISTORY_REPORT("historyAlert"),
ALERT_SUMMARY("summary");
private String m_name;
......
......@@ -47,6 +47,7 @@ import com.dianping.cat.home.utilization.entity.UtilizationReport;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.service.ReportService;
import com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor;
import com.dianping.cat.report.task.heavy.HeavyReportMerger.ServiceComparator;
import com.dianping.cat.report.task.heavy.HeavyReportMerger.UrlComparator;
import com.dianping.cat.system.config.BugConfigManager;
......@@ -67,6 +68,9 @@ public class Handler implements PageHandler<Context> {
@Inject
private PayloadNormalizer m_normalizePayload;
@Inject
private AlertSummaryExecutor m_executor;
private void buildBugInfo(Model model, Payload payload) {
BugReport bugReport = queryBugReport(payload);
BugReportVisitor visitor = new BugReportVisitor();
......@@ -172,7 +176,8 @@ public class Handler implements PageHandler<Context> {
com.dianping.cat.home.alert.report.entity.Domain domain = report.getDomains().get(domainName);
if (domain != null && !domain.getExceptions().isEmpty()) {
exceptions = new ArrayList<com.dianping.cat.home.alert.report.entity.Exception>(domain.getExceptions().values());
exceptions = new ArrayList<com.dianping.cat.home.alert.report.entity.Exception>(domain.getExceptions()
.values());
Comparator<com.dianping.cat.home.alert.report.entity.Exception> exceptionCompator = new Comparator<com.dianping.cat.home.alert.report.entity.Exception>() {
@Override
......@@ -257,6 +262,11 @@ public class Handler implements PageHandler<Context> {
case ALERT_HISTORY_REPORT_DETAIL:
builAlertDetails(model, payload);
break;
case ALERT_SUMMARY:
String summaryContent = m_executor.execute(payload.getSummarydomain(), payload.getSummarytime(),
payload.getSummaryemails());
model.setSummaryContent(summaryContent);
break;
}
model.setPage(ReportPage.STATISTICS);
m_jspViewer.view(ctx, model);
......
......@@ -27,8 +27,10 @@ public enum JspFile {
ALERT_REPORT_DETAIL("/jsp/report/exceptionAlert/exceptionDetail.jsp"),
ALERT_REPORT("/jsp/report/exceptionAlert/alert.jsp");
ALERT_REPORT("/jsp/report/exceptionAlert/alert.jsp"),
ALERT_SUMMARY("/jsp/report/summary/summary.jsp");
private String m_path;
private JspFile(String path) {
......
......@@ -35,6 +35,8 @@ public class JspViewer extends BaseJspViewer<ReportPage, Action, Context, Model>
case ALERT_REPORT_DETAIL:
case ALERT_HISTORY_REPORT_DETAIL:
return JspFile.ALERT_REPORT_DETAIL.getPath();
case ALERT_SUMMARY:
return JspFile.ALERT_SUMMARY.getPath();
}
throw new RuntimeException("Unknown action: " + action);
......
......@@ -24,6 +24,8 @@ public class Model extends AbstractReportModel<Action, Context> {
private String m_browserChart;
private String m_osChart;
private String m_summaryContent;
@EntityMeta
private BugReport m_bugReport;
......@@ -33,13 +35,13 @@ public class Model extends AbstractReportModel<Action, Context> {
@EntityMeta
private HeavyReport m_heavyReport;
@EntityMeta
private AlertReport m_alertReport;
@EntityMeta
private UtilizationReport m_utilizationReport;
private List<Domain> m_serviceList;
private List<Url> m_callUrls;
......@@ -59,14 +61,26 @@ public class Model extends AbstractReportModel<Action, Context> {
private List<com.dianping.cat.home.utilization.entity.Domain> m_utilizationWebList;
private List<com.dianping.cat.home.utilization.entity.Domain> m_utilizationServiceList;
private List<com.dianping.cat.home.alert.report.entity.Domain> m_alertDomains;
private List<com.dianping.cat.home.alert.report.entity.Exception> m_alertExceptions;
private List<com.dianping.cat.home.alert.report.entity.Exception> m_alertExceptions;
public Model(Context ctx) {
super(ctx);
}
public List<com.dianping.cat.home.alert.report.entity.Domain> getAlertDomains() {
return m_alertDomains;
}
public List<com.dianping.cat.home.alert.report.entity.Exception> getAlertExceptions() {
return m_alertExceptions;
}
public AlertReport getAlertReport() {
return m_alertReport;
}
public String getBrowserChart() {
return m_browserChart;
......@@ -110,7 +124,7 @@ public class Model extends AbstractReportModel<Action, Context> {
public Collection<String> getDomains() {
return new ArrayList<String>();
}
public Map<String, ErrorStatis> getErrorStatis() {
return m_errorStatis;
}
......@@ -118,10 +132,6 @@ public class Model extends AbstractReportModel<Action, Context> {
public HeavyReport getHeavyReport() {
return m_heavyReport;
}
public AlertReport getAlertReport() {
return m_alertReport;
}
public String getOsChart() {
return m_osChart;
......@@ -143,6 +153,10 @@ public class Model extends AbstractReportModel<Action, Context> {
return m_sqlUrls;
}
public String getSummaryContent() {
return m_summaryContent;
}
public UtilizationReport getUtilizationReport() {
return m_utilizationReport;
}
......@@ -155,6 +169,18 @@ public class Model extends AbstractReportModel<Action, Context> {
return m_utilizationWebList;
}
public void setAlertDomains(List<com.dianping.cat.home.alert.report.entity.Domain> alertDomains) {
m_alertDomains = alertDomains;
}
public void setAlertExceptions(List<com.dianping.cat.home.alert.report.entity.Exception> alertExceptions) {
m_alertExceptions = alertExceptions;
}
public void setAlertReport(AlertReport alertReport) {
m_alertReport = alertReport;
}
public void setBrowserChart(String browserChart) {
m_browserChart = browserChart;
}
......@@ -170,7 +196,7 @@ public class Model extends AbstractReportModel<Action, Context> {
public void setCacheUrls(List<Url> cacheUrls) {
m_cacheUrls = cacheUrls;
}
public void setCallServices(List<Service> callServices) {
m_callServices = callServices;
}
......@@ -186,10 +212,6 @@ public class Model extends AbstractReportModel<Action, Context> {
public void setHeavyReport(HeavyReport heavyReport) {
m_heavyReport = heavyReport;
}
public void setAlertReport(AlertReport alertReport) {
m_alertReport = alertReport;
}
public void setOsChart(String osChart) {
m_osChart = osChart;
......@@ -211,6 +233,10 @@ public class Model extends AbstractReportModel<Action, Context> {
m_sqlUrls = sqlUrls;
}
public void setSummaryContent(String summaryContent) {
m_summaryContent = summaryContent;
}
public void setUtilizationReport(UtilizationReport utilizationReport) {
m_utilizationReport = utilizationReport;
}
......@@ -223,20 +249,4 @@ public class Model extends AbstractReportModel<Action, Context> {
m_utilizationWebList = utilizationWebList;
}
public List<com.dianping.cat.home.alert.report.entity.Domain> getAlertDomains() {
return m_alertDomains;
}
public void setAlertDomains(List<com.dianping.cat.home.alert.report.entity.Domain> alertDomains) {
m_alertDomains = alertDomains;
}
public List<com.dianping.cat.home.alert.report.entity.Exception> getAlertExceptions() {
return m_alertExceptions;
}
public void setAlertExceptions(List<com.dianping.cat.home.alert.report.entity.Exception> alertExceptions) {
m_alertExceptions = alertExceptions;
}
}
package com.dianping.cat.report.page.statistics;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.unidal.web.mvc.ActionContext;
import org.unidal.web.mvc.payload.annotation.FieldMeta;
......@@ -18,6 +21,17 @@ public class Payload extends AbstractReportPayload<Action> {
@FieldMeta("tab")
private String m_tab = "tab1";
@FieldMeta("summarydomain")
private String m_summarydomain;
@FieldMeta("summarytime")
private String m_summarytime;
@FieldMeta("summaryemails")
private String m_summaryemails;
private SimpleDateFormat m_sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public Payload() {
super(ReportPage.STATISTICS);
}
......@@ -36,6 +50,30 @@ public class Payload extends AbstractReportPayload<Action> {
return m_sortBy;
}
public String getSummarydomain() {
if (m_summarydomain == null || "".equals(m_summarydomain)) {
return null;
} else {
return m_summarydomain;
}
}
public String getSummaryemails() {
if (m_summaryemails == null || "".equals(m_summaryemails)) {
return null;
} else {
return m_summaryemails;
}
}
public Date getSummarytime() {
try {
return m_sdf.parse(m_summarytime);
} catch (Exception ex) {
return new Date();
}
}
public String getTab() {
return m_tab;
}
......@@ -53,6 +91,18 @@ public class Payload extends AbstractReportPayload<Action> {
m_sortBy = sortBy;
}
public void setSummarydomain(String summaryDomain) {
m_summarydomain = summaryDomain;
}
public void setSummaryemails(String summaryEmails) {
m_summaryemails = summaryEmails;
}
public void setSummarytime(String summaryTime) {
m_summarytime = summaryTime;
}
public void setTab(String tab) {
m_tab = tab;
}
......
......@@ -14,24 +14,24 @@ import com.dianping.cat.helper.TimeUtil;
public class AlertInfo implements Initializable {
private ConcurrentHashMap<String, Long> m_alertInfos = new ConcurrentHashMap<String, Long>();
private ConcurrentHashMap<AlertMetric, Long> m_alertInfos = new ConcurrentHashMap<AlertMetric, Long>();
@Inject
protected MetricConfigManager m_manager;
public void addAlertInfo(String metricId, long value) {
m_alertInfos.put(metricId, value);
public void addAlertInfo(String group, String metricId, long value) {
m_alertInfos.put(new AlertMetric(group, metricId), value);
}
@Override
public void initialize() throws InitializationException {
}
public List<String> queryLastestAlarmKey(int minute) {
List<String> keys = new ArrayList<String>();
public List<AlertMetric> queryLastestAlarmKey(int minute) {
List<AlertMetric> keys = new ArrayList<AlertMetric>();
long currentTimeMillis = System.currentTimeMillis();
for (Entry<String, Long> entry : m_alertInfos.entrySet()) {
for (Entry<AlertMetric, Long> entry : m_alertInfos.entrySet()) {
Long value = entry.getValue();
if (currentTimeMillis - value < TimeUtil.ONE_MINUTE * minute) {
......@@ -42,4 +42,25 @@ public class AlertInfo implements Initializable {
return keys;
}
public class AlertMetric {
private String m_group;
private String m_metricId;
public AlertMetric(String group, String metricId) {
this.m_group = group;
this.m_metricId = metricId;
}
public String getGroup() {
return m_group;
}
public String getMetricId() {
return m_metricId;
}
}
}
......@@ -8,17 +8,17 @@ public class AlertResultEntity {
private String m_content;
private String m_alertType;
private Date m_alertTime;
public AlertResultEntity(){
public AlertResultEntity() {
this.m_isTriggered = false;
this.m_content = "";
this.m_alertType = "";
this.m_alertTime = new Date();
}
public AlertResultEntity(boolean result, String content, String alertType){
public AlertResultEntity(boolean result, String content, String alertType) {
this.m_isTriggered = result;
this.m_content = content;
this.m_alertType = alertType;
......@@ -37,6 +37,10 @@ public class AlertResultEntity {
return m_content;
}
public void setContent(String content) {
this.m_content = content;
}
public boolean isTriggered() {
return m_isTriggered;
}
......
......@@ -22,16 +22,25 @@ import com.dianping.cat.consumer.metric.ProductLineConfigManager;
import com.dianping.cat.consumer.metric.model.entity.MetricItem;
import com.dianping.cat.consumer.metric.model.entity.MetricReport;
import com.dianping.cat.consumer.metric.model.entity.Segment;
import com.dianping.cat.core.dal.Project;
import com.dianping.cat.core.dal.ProjectDao;
import com.dianping.cat.core.dal.ProjectEntity;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.dal.report.Alert;
import com.dianping.cat.home.dal.report.AlertDao;
import com.dianping.cat.home.rule.entity.Condition;
import com.dianping.cat.home.rule.entity.Config;
import com.dianping.cat.message.Event;
import com.dianping.cat.report.baseline.BaselineService;
import com.dianping.cat.report.task.alert.sender.BaseSender;
import com.dianping.cat.report.task.alert.sender.MailSender;
import com.dianping.cat.report.task.alert.sender.SmsSender;
import com.dianping.cat.report.task.alert.sender.WeixinSender;
import com.dianping.cat.service.ModelPeriod;
import com.dianping.cat.service.ModelRequest;
import com.dianping.cat.system.config.BaseRuleConfigManager;
import com.dianping.cat.system.tool.MailSMS;
import com.site.lookup.util.StringUtils;
public abstract class BaseAlert {
......@@ -62,6 +71,18 @@ public abstract class BaseAlert {
@Inject
protected RemoteMetricReportService m_service;
@Inject
private ProjectDao m_projectDao;
@Inject
protected MailSender m_mailSender;
@Inject
protected SmsSender m_smsSender;
@Inject
protected WeixinSender m_weixinSender;
protected static final int DATA_AREADY_MINUTE = 1;
protected static final long DURATION = TimeUtil.ONE_MINUTE;
......@@ -96,6 +117,37 @@ public abstract class BaseAlert {
}
}
private String extractDomain(String metricKey) {
try {
return metricKey.split(":")[0];
} catch (Exception ex) {
Cat.logError("extract domain error:" + metricKey, ex);
return null;
}
}
protected String buildContactInfo(String domainName) {
try {
Project project = m_projectDao.findByDomain(domainName, ProjectEntity.READSET_FULL);
String owners = project.getOwner();
String phones = project.getPhone();
StringBuilder builder = new StringBuilder();
if (!StringUtils.isEmpty(owners)) {
builder.append("[业务负责人: ").append(owners).append(" ]");
}
if (!StringUtils.isEmpty(phones)) {
builder.append("[负责人手机号码: ").append(phones).append(" ]");
}
return builder.toString();
} catch (Exception ex) {
Cat.logError("build contact info error for doamin: " + domainName, ex);
}
return null;
}
private Long buildMillsByString(String time) throws Exception {
String[] times = time.split(":");
int hour = Integer.parseInt(times[0]);
......@@ -244,10 +296,16 @@ public abstract class BaseAlert {
if (alertResult != null && alertResult.isTriggered()) {
String metricTitle = buildMetricTitle(metricKey);
String mailTitle = getAlertConfig().buildMailTitle(productLine.getTitle(), metricTitle);
m_alertInfo.addAlertInfo(metricKey, new Date().getTime());
String domain = extractDomain(metricKey);
String contactInfo = buildContactInfo(domain);
alertResult.setContent(alertResult.getContent() + contactInfo);
String content = alertResult.getContent();
m_alertInfo.addAlertInfo(productlineName, metricKey, new Date().getTime());
storeAlert(productlineName, metricTitle, mailTitle, alertResult);
sendAlertInfo(productLine, mailTitle, alertResult.getContent(), alertResult.getAlertType());
String configId = getAlertConfig().getId();
sendAllAlert(productLine, domain, mailTitle, content, alertResult.getAlertType(), configId);
Cat.logEvent(configId, productlineName, Event.SUCCESS, mailTitle + " " + content);
}
}
}
......@@ -267,6 +325,26 @@ public abstract class BaseAlert {
}
}
protected boolean sendAllAlert(ProductLine productLine, String domain, String title, String content,
String alertType, String configId) {
boolean sendResult = true;
BaseSender[] senders = { m_mailSender, m_weixinSender };
List<String> receivers = getAlertConfig().buildMailReceivers(productLine);
for (BaseSender sender : senders) {
if (!sender.sendAlert(receivers, domain, title, content, alertType)) {
sendResult = false;
}
}
receivers = getAlertConfig().buildSMSReceivers(productLine);
if (!m_smsSender.sendAlert(receivers, domain, title, content, alertType)) {
sendResult = false;
}
return sendResult;
}
private double[] queryBaseLine(int start, int end, String baseLineKey, Date date, MetricType type) {
double[] baseline = m_baselineService.queryHourlyBaseline(MetricAnalyzer.ID, baseLineKey + ":" + type, date);
int length = end - start + 1;
......@@ -339,8 +417,6 @@ public abstract class BaseAlert {
}
protected abstract String getName();
protected abstract BaseAlertConfig getAlertConfig();
protected abstract void sendAlertInfo(ProductLine productLine, String mailTitle, String content, String alertType);
protected abstract BaseAlertConfig getAlertConfig();
}
......@@ -55,6 +55,20 @@ public abstract class BaseAlertConfig {
return split(productLine.getPhone());
}
public List<String> buildSMSReceivers(ProductLine productLine, String configId) {
List<String> smsReceivers = new ArrayList<String>();
Receiver receiver = m_manager.queryReceiverById(configId);
if (receiver != null && !receiver.isEnable()) {
return smsReceivers;
} else {
smsReceivers.addAll(buildDefaultSMSReceivers(receiver));
smsReceivers.addAll(buildProductlineSMSReceivers(productLine));
return smsReceivers;
}
}
public List<String> buildSMSReceivers(ProductLine productLine) {
List<String> smsReceivers = new ArrayList<String>();
Receiver receiver = m_manager.queryReceiverById(getId());
......@@ -68,7 +82,7 @@ public abstract class BaseAlertConfig {
return smsReceivers;
}
}
protected abstract String buildMailTitle(String artifactName, String configTitle);
public abstract String getId();
......
......@@ -25,8 +25,6 @@ public class BusinessAlert extends BaseAlert implements Task, LogEnabled {
@Inject
protected BusinessAlertConfig m_alertConfig;
private Logger m_logger;
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
......@@ -36,7 +34,7 @@ public class BusinessAlert extends BaseAlert implements Task, LogEnabled {
public String getName() {
return "business-alert";
}
@Override
public BaseAlertConfig getAlertConfig() {
return m_alertConfig;
......@@ -71,10 +69,16 @@ public class BusinessAlert extends BaseAlert implements Task, LogEnabled {
if (alertResult != null && alertResult.isTriggered()) {
String mailTitle = m_alertConfig.buildMailTitle(productLine.getTitle(), config.getTitle());
m_alertInfo.addAlertInfo(metricKey, new Date().getTime());
String contactInfo = buildContactInfo(domain);
alertResult.setContent(alertResult.getContent() + contactInfo);
String content = alertResult.getContent();
m_alertInfo.addAlertInfo(product, metricKey, new Date().getTime());
storeAlert(domain, metric, mailTitle, alertResult);
sendAlertInfo(productLine, mailTitle, alertResult.getContent(), alertResult.getAlertType());
String configId = getAlertConfig().getId();
sendAllAlert(productLine, domain, mailTitle, content, alertResult.getAlertType(), configId);
Cat.logEvent(configId, product, Event.SUCCESS, mailTitle + " " + content);
}
}
}
......@@ -146,21 +150,6 @@ public class BusinessAlert extends BaseAlert implements Task, LogEnabled {
}
}
@Override
public void sendAlertInfo(ProductLine productLine, String title, String content, String alertType) {
List<String> emails = m_alertConfig.buildMailReceivers(productLine);
m_logger.info(title + " " + content + " " + emails);
m_mailSms.sendEmail(title, content, emails);
if (alertType != null && alertType.equals("error")) {
List<String> phones = m_alertConfig.buildSMSReceivers(productLine);
m_mailSms.sendSms(title + " " + content, content, phones);
}
Cat.logEvent("MetricAlert", productLine.getId(), Event.SUCCESS, title + " " + content);
}
@Override
public void shutdown() {
}
......
......@@ -53,18 +53,18 @@ public class AlertExceptionBuilder {
totalException += value;
if (errorLimit > 0 && value >= errorLimit && needSendSms(domain, exceptionName)) {
alertExceptions.add(new AlertException(exceptionName, AlertException.ERROR_EXCEPTION, value));
if (errorLimit > 0 && value >= errorLimit) {
alertExceptions.add(new AlertException(exceptionName, AlertException.ERROR_EXCEPTION, value,
needSendSms(domain, exceptionName)));
} else if (warnLimit > 0 && value >= warnLimit) {
alertExceptions.add(new AlertException(exceptionName, AlertException.WARN_EXCEPTION, value));
}
}
}
if (totalErrorLimit > 0 && totalException >= totalErrorLimit
&& needSendSms(domain, ExceptionConfigManager.TOTAL_STRING)) {
if (totalErrorLimit > 0 && totalException >= totalErrorLimit) {
alertExceptions.add(new AlertException(ExceptionConfigManager.TOTAL_STRING, AlertException.ERROR_EXCEPTION,
totalException));
totalException, needSendSms(domain, ExceptionConfigManager.TOTAL_STRING)));
} else if (totalWarnLimit > 0 && totalException >= totalWarnLimit) {
alertExceptions.add(new AlertException(ExceptionConfigManager.TOTAL_STRING, AlertException.WARN_EXCEPTION,
totalException));
......@@ -125,20 +125,21 @@ public class AlertExceptionBuilder {
return limits;
}
public String buildMailContent(String exceptions, String domain) {
String content = buildContent(exceptions, domain);
public String buildMailContent(String exceptions, String domain, String contactInfo) {
String content = buildContent(exceptions, domain, contactInfo);
String url = "http://cat.dianpingoa.com/cat/r/p?domain=" + domain;
String mailContent = content + " <a href='" + url + "'>点击此处查看详情</a>";
String mailContent = content + "<br/>" + " <a href='" + url + "'>点击此处查看详情</a>";
return mailContent;
}
public String buildContent(String exceptions, String domain) {
public String buildContent(String exceptions, String domain, String contactInfo) {
StringBuilder sb = new StringBuilder();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
sb.append("[CAT异常告警] [项目: ").append(domain).append("] : ");
sb.append(exceptions).append("[时间: ").append(time).append("]");
sb.append(contactInfo);
return sb.toString();
}
......@@ -154,6 +155,17 @@ public class AlertExceptionBuilder {
return errorExceptions;
}
public List<AlertException> buildErrorAndTriggeredException(List<AlertException> exceptions) {
List<AlertException> errorExceptions = new ArrayList<AlertException>();
for (AlertException alertException : exceptions) {
if (AlertException.ERROR_EXCEPTION.equals(alertException.getType()) && alertException.isTriggered()) {
errorExceptions.add(alertException);
}
}
return errorExceptions;
}
public class AlertException {
private static final String WARN_EXCEPTION = "warn";
......@@ -166,10 +178,24 @@ public class AlertExceptionBuilder {
private double m_count;
private boolean m_isTriggered;
public AlertException(String name, String type, double count) {
m_name = name;
m_type = type;
m_count = count;
m_isTriggered = false;
}
public AlertException(String name, String type, double count, boolean isTriggered) {
m_name = name;
m_type = type;
m_count = count;
m_isTriggered = isTriggered;
}
public boolean isTriggered() {
return m_isTriggered;
}
public String getName() {
......
......@@ -30,10 +30,14 @@ import com.dianping.cat.report.page.model.spi.ModelService;
import com.dianping.cat.report.page.top.TopMetric;
import com.dianping.cat.report.page.top.TopMetric.Item;
import com.dianping.cat.report.task.alert.exception.AlertExceptionBuilder.AlertException;
import com.dianping.cat.report.task.alert.sender.MailSender;
import com.dianping.cat.report.task.alert.sender.SmsSender;
import com.dianping.cat.report.task.alert.sender.WeixinSender;
import com.dianping.cat.service.ModelRequest;
import com.dianping.cat.service.ModelResponse;
import com.dianping.cat.system.config.ExceptionConfigManager;
import com.dianping.cat.system.tool.MailSMS;
import com.site.lookup.util.StringUtils;
public class ExceptionAlert implements Task, LogEnabled {
......@@ -58,6 +62,15 @@ public class ExceptionAlert implements Task, LogEnabled {
@Inject(type = ModelService.class, value = TopAnalyzer.ID)
private ModelService<TopReport> m_topService;
@Inject
protected MailSender m_mailSender;
@Inject
protected SmsSender m_smsSender;
@Inject
protected WeixinSender m_weixinSender;
private static final long DURATION = TimeUtil.ONE_MINUTE;
private static final int ALERT_PERIOD = 1;
......@@ -86,6 +99,28 @@ public class ExceptionAlert implements Task, LogEnabled {
return topMetric;
}
private String buildContactInfo(String domainName) {
try {
Project project = m_projectDao.findByDomain(domainName, ProjectEntity.READSET_FULL);
String owners = project.getOwner();
String phones = project.getPhone();
StringBuilder builder = new StringBuilder();
if (!StringUtils.isEmpty(owners)) {
builder.append("[业务负责人: ").append(owners).append(" ]");
}
if (!StringUtils.isEmpty(phones)) {
builder.append("[负责人手机号码: ").append(phones).append(" ]");
}
return builder.toString();
} catch (Exception ex) {
Cat.logError("build contact info error for doamin: " + domainName, ex);
}
return null;
}
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
......@@ -179,21 +214,26 @@ public class ExceptionAlert implements Task, LogEnabled {
List<String> phones = m_alertConfig.buildSMSReceivers(project);
String weixins = m_alertConfig.buildWeiXinReceivers(project);
String mailTitle = m_alertConfig.buildMailTitle(domain, null);
String mailContent = m_alertBuilder.buildMailContent(exceptions.toString(), domain);
m_mailSms.sendEmail(mailTitle, mailContent, emails);
m_logger.info(mailTitle + " " + mailContent + " " + emails);
Cat.logEvent("ExceptionAlert", domain, Event.SUCCESS, "[邮件告警] " + mailTitle + " " + mailContent);
String contactInfo = buildContactInfo(domain);
String mailContent = m_alertBuilder.buildMailContent(exceptions.toString(), domain, contactInfo);
storeAlerts(domain, exceptions, mailTitle + "<br/>" + mailContent);
List<AlertException> errorExceptions = m_alertBuilder.buildErrorException(exceptions);
m_mailSender.sendAlert(emails, domain, mailTitle, mailContent, "warning");
Cat.logEvent("ExceptionAlert", domain, Event.SUCCESS, "[邮件告警] " + mailTitle + " " + mailContent);
List<AlertException> errorExceptions = m_alertBuilder.buildErrorException(exceptions);
if (!errorExceptions.isEmpty()) {
String smsContent = m_alertBuilder.buildContent(errorExceptions.toString(), domain);
String weixinContent = m_alertBuilder.buildContent(errorExceptions.toString(), domain, contactInfo);
m_weixinSender.sendAlert(emails, domain, mailTitle, weixinContent, "error");
Cat.logEvent("ExceptionAlert", domain, Event.SUCCESS, "[微信告警] " + mailTitle + " " + weixinContent + " "
+ domain + " " + weixins);
}
m_mailSms.sendSms(smsContent, smsContent, phones);
m_logger.info(smsContent + " " + phones);
List<AlertException> errorAndTriggeredExceptions = m_alertBuilder.buildErrorAndTriggeredException(exceptions);
if (!errorAndTriggeredExceptions.isEmpty()) {
String smsContent = m_alertBuilder.buildContent(errorAndTriggeredExceptions.toString(), domain, contactInfo);
m_smsSender.sendAlert(phones, domain, smsContent, smsContent, "error");
Cat.logEvent("ExceptionAlert", domain, Event.SUCCESS, "[短信告警] " + smsContent);
m_mailSms.sendWeiXin(mailTitle, mailContent, domain, weixins);
......
package com.dianping.cat.report.task.alert.network;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import org.codehaus.plexus.logging.LogEnabled;
......@@ -11,7 +10,6 @@ import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.consumer.company.model.entity.ProductLine;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.report.task.alert.BaseAlert;
import com.dianping.cat.report.task.alert.BaseAlertConfig;
......@@ -30,7 +28,7 @@ public class NetworkAlert extends BaseAlert implements Task, LogEnabled {
public String getName() {
return "network-alert";
}
@Override
public BaseAlertConfig getAlertConfig() {
return m_alertConfig;
......@@ -87,21 +85,6 @@ public class NetworkAlert extends BaseAlert implements Task, LogEnabled {
}
}
@Override
protected void sendAlertInfo(ProductLine productLine, String title, String content, String alertType) {
List<String> emails = m_alertConfig.buildMailReceivers(productLine);
m_logger.info(title + " " + content + " " + emails);
m_mailSms.sendEmail(title, content, emails);
if (alertType != null && alertType.equals("error")) {
List<String> phones = m_alertConfig.buildSMSReceivers(productLine);
m_mailSms.sendSms(title + " " + content, content, phones);
}
Cat.logEvent("NetworkAlert", productLine.getId(), Event.SUCCESS, title + " " + content);
}
@Override
public void shutdown() {
}
......
package com.dianping.cat.report.task.alert.sender;
import java.util.List;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.system.tool.MailSMS;
public abstract class BaseSender implements LogEnabled {
protected Logger m_logger;
@Inject
protected MailSMS m_mailSms;
protected abstract void sendLog(String title, String content, List<String> receivers);
public abstract boolean sendAlert(List<String> receivers, String domain, String title, String content,
String alertType);
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
}
}
package com.dianping.cat.report.task.alert.sender;
import java.util.List;
import com.dianping.cat.Cat;
public class MailSender extends BaseSender {
@Override
protected void sendLog(String title, String content, List<String> receivers) {
StringBuilder builder = new StringBuilder();
builder.append(title).append(",").append(content).append(",");
for (String receiver : receivers) {
builder.append(receiver).append(" ");
}
Cat.logEvent("SendMail", builder.toString());
m_logger.info("SendMail" + builder.toString());
}
@Override
public boolean sendAlert(List<String> receivers, String domain, String title, String content, String alertType) {
try {
m_mailSms.sendEmail(title, content, receivers);
sendLog(title, content, receivers);
return true;
} catch (Exception ex) {
Cat.logError("send mail error" + " " + title + " " + content, ex);
return false;
}
}
}
package com.dianping.cat.report.task.alert.sender;
import java.util.List;
import com.dianping.cat.Cat;
public class SmsSender extends BaseSender {
@Override
protected void sendLog(String title, String content, List<String> receivers) {
StringBuilder builder = new StringBuilder();
builder.append(title).append(" ").append(content).append(" ");
for (String receiver : receivers) {
builder.append(receiver).append(" ");
}
Cat.logEvent("SendSms", builder.toString());
m_logger.info("SendSms" + builder.toString());
}
@Override
public boolean sendAlert(List<String> receivers, String domain, String title, String content, String alertType) {
if (alertType == null || !alertType.equals("error")) {
return true;
}
try {
m_mailSms.sendSms(title, content, receivers);
sendLog(title, content, receivers);
return true;
} catch (Exception ex) {
Cat.logError("send sms error" + " " + title + " " + content, ex);
return false;
}
}
}
package com.dianping.cat.report.task.alert.sender;
import java.util.List;
import com.dianping.cat.Cat;
public class WeixinSender extends BaseSender {
@Override
protected void sendLog(String title, String content, List<String> receivers) {
StringBuilder builder = new StringBuilder();
builder.append(title).append(" ").append(content).append(" ");
for (String receiver : receivers) {
builder.append(receiver).append(" ");
}
Cat.logEvent("SendWeixin", builder.toString());
m_logger.info("SendWeixin" + builder.toString());
}
@Override
public boolean sendAlert(List<String> receivers, String domain, String title, String content, String alertType) {
if (alertType == null || !alertType.equals("error")) {
return true;
}
try {
content = content.replaceAll("<br/>", "\n");
m_mailSms.sendWeiXin(title, content, domain, mergeList(receivers));
sendLog(title, content, receivers);
return true;
} catch (Exception ex) {
Cat.logError("send weixin error" + " " + title + " " + content, ex);
return false;
}
}
private String mergeList(List<String> receivers) {
StringBuilder builder = new StringBuilder();
for (String receiver : receivers) {
builder.append(receiver).append(",");
}
String tmpResult = builder.toString();
if (tmpResult.endsWith(",")) {
return tmpResult.substring(0, tmpResult.length() - 1);
} else {
return tmpResult;
}
}
}
......@@ -2,10 +2,6 @@ package com.dianping.cat.report.task.alert.summary;
import com.dianping.cat.home.alert.summary.entity.AlertSummary;
public class AlertSummaryDecorator {
public String generateHtml(AlertSummary alertSummary) {
return null;
}
public interface AlertSummaryDecorator {
public String generateHtml(AlertSummary alertSummary);
}
package com.dianping.cat.report.task.alert.summary;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
......@@ -7,27 +9,55 @@ import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.home.alert.summary.entity.AlertSummary;
import com.dianping.cat.system.tool.MailSMS;
import com.site.helper.Splitters;
import com.site.lookup.util.StringUtils;
public class AlertSummaryExecutor {
@Inject
AlertSummaryGenerator m_alertSummaryGenerator;
private AlertSummaryGenerator m_alertSummaryGenerator;
@Inject
AlertSummaryManager m_alertSummaryManager;
private AlertSummaryManager m_alertSummaryManager;
@Inject
AlertSummaryDecorator m_alertSummaryDecorator;
@Inject(type = AlertSummaryDecorator.class, value = AlertSummaryFTLDecorator.ID)
private AlertSummaryDecorator m_alertSummaryDecorator;
@Inject
AlertSummarySender m_alertSummarySender;
protected MailSMS m_mailSms;
private String buildMailTitle(String domain, Date date) {
StringBuilder builder = new StringBuilder();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
builder.append("[统一告警] [项目 ").append(domain).append("]");
builder.append("[时间 ").append(dateFormat.format(date)).append("]");
return builder.toString();
}
private List<String> builderReceivers(String str) {
List<String> result = new ArrayList<String>();
if (str != null) {
result.addAll(Splitters.by(",").noEmptyItem().split(str));
}
return result;
}
public String execute(String domain, Date date, String receiverStr) {
if (StringUtils.isEmpty(domain) || date == null) {
return null;
}
public String execute(String domain, Date date, List<String> receivers) {
try {
AlertSummary alertSummary = m_alertSummaryGenerator.generateAlertSummary(domain, date);
m_alertSummaryManager.insert(alertSummary);
String title = buildMailTitle(domain, date);
String content = m_alertSummaryDecorator.generateHtml(alertSummary);
m_alertSummarySender.send(content, receivers);
List<String> receivers = builderReceivers(receiverStr);
m_mailSms.sendEmail(title, content, receivers);
return content;
} catch (Exception e) {
......
package com.dianping.cat.report.task.alert.summary;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import com.dianping.cat.Cat;
import com.dianping.cat.home.alert.summary.entity.AlertSummary;
import com.dianping.cat.system.notify.ReportRenderImpl;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class AlertSummaryFTLDecorator implements AlertSummaryDecorator, Initializable {
public Configuration m_configuration;
public static final String ID = "AlertSummaryFTLDecorator";
@Override
public String generateHtml(AlertSummary alertSummary) {
AlertSummaryVisitor visitor = new AlertSummaryVisitor();
visitor.visitAlertSummary(alertSummary);
Map<Object, Object> dataMap = convertDataMap(visitor.getResult());
StringWriter sw = new StringWriter(5000);
try {
Template t = m_configuration.getTemplate("summary.ftl");
t.process(dataMap, sw);
} catch (Exception e) {
Cat.logError(e);
}
return sw.toString();
}
private Map<Object, Object> convertDataMap(Map<Object, Object> map) {
return gatherDomainsForDependBusiness(map);
}
@SuppressWarnings("unchecked")
private Map<Object, Object> gatherDomainsForDependBusiness(Map<Object, Object> map) {
try {
Map<Object, Object> categories = (Map<Object, Object>) map.get("categories");
List<Map<Object, Object>> alerts = (List<Map<Object, Object>>) categories.get("dependency_business");
Map<String, List<Map<Object, Object>>> dependBusiMap = new TreeMap<String, List<Map<Object, Object>>>();
for (Map<Object, Object> alert : alerts) {
String domain = (String) alert.get("domain");
List<Map<Object, Object>> tmpAlerts = dependBusiMap.get(domain);
if (tmpAlerts == null) {
tmpAlerts = new ArrayList<Map<Object, Object>>();
dependBusiMap.put(domain, tmpAlerts);
}
tmpAlerts.add(alert);
}
categories.put("dependency_business_length", alerts.size());
categories.put("dependency_business", dependBusiMap);
} catch (Exception ex) {
ex.printStackTrace();
}
return map;
}
@Override
public void initialize() throws InitializationException {
m_configuration = new Configuration();
m_configuration.setDefaultEncoding("UTF-8");
try {
m_configuration.setClassForTemplateLoading(ReportRenderImpl.class, "/freemaker");
} catch (Exception e) {
Cat.logError(e);
}
}
}
......@@ -13,6 +13,7 @@ import com.dianping.cat.home.alert.summary.entity.Category;
import com.dianping.cat.home.dal.report.Alert;
import com.dianping.cat.home.dal.report.AlertDao;
import com.dianping.cat.home.dal.report.AlertEntity;
import com.dianping.cat.home.dependency.graph.entity.TopologyEdge;
import com.dianping.cat.home.dependency.graph.entity.TopologyGraph;
import com.dianping.cat.report.page.dependency.graph.TopologyGraphManager;
......@@ -24,8 +25,20 @@ public class AlertSummaryGenerator {
@Inject
private TopologyGraphManager m_topologyManager;
// fetch alerts during this period, time unit is ms, default value is 1 hour
private final long DURATION = 60 * 60 * 1000L;
// fetch alerts during this period, time unit is ms, default value is 5 minnutes
private final long DURATION = 5 * 60 * 1000L;
private com.dianping.cat.home.alert.summary.entity.Alert convertToAlert(TopologyEdge edge, Date date) {
com.dianping.cat.home.alert.summary.entity.Alert alert = new com.dianping.cat.home.alert.summary.entity.Alert();
alert.setAlertTime(date);
alert.setContext(edge.getDes());
alert.setMetric(edge.getKey());
alert.setType("long call");
alert.setDomain(edge.getSelf());
return alert;
}
private com.dianping.cat.home.alert.summary.entity.Alert convertToAlert(Alert dbAlert) {
com.dianping.cat.home.alert.summary.entity.Alert alert = new com.dianping.cat.home.alert.summary.entity.Alert();
......@@ -38,13 +51,14 @@ public class AlertSummaryGenerator {
return alert;
}
private com.dianping.cat.home.alert.summary.entity.Alert convertToDependAlert(String domain, Alert dbAlert) {
private com.dianping.cat.home.alert.summary.entity.Alert convertToAlertWithDomain(Alert dbAlert) {
com.dianping.cat.home.alert.summary.entity.Alert alert = new com.dianping.cat.home.alert.summary.entity.Alert();
alert.setAlertTime(dbAlert.getAlertTime());
alert.setContext(dbAlert.getContent());
alert.setMetric(domain + ":" + dbAlert.getMetric());
alert.setMetric(dbAlert.getMetric());
alert.setType(dbAlert.getType());
alert.setDomain(dbAlert.getDomain());
return alert;
}
......@@ -60,59 +74,60 @@ public class AlertSummaryGenerator {
alertSummary.addCategory(generateCategoryByTimeCateDomain(date, "exception", domain));
alertSummary.addCategory(generateCategoryByTimeCateDomain(date, "system", domain));
List<String> dependencyDomains = queryDependencyDomains(date, domain);
alertSummary.addCategory(generateDependCategoryByTimeCateDomain(date, "business", dependencyDomains));
TopologyGraph topology = m_topologyManager.buildTopologyGraph(domain, date.getTime());
int statusThreshold = 2;
alertSummary.addCategory(generateDependCategoryByTopology(date, "business", topology, statusThreshold));
List<String> dependencyDomains = queryDependencyDomains(topology, date, domain);
alertSummary.addCategory(generateDependCategoryByTimeCateDomain(date, "exception", dependencyDomains));
return alertSummary;
}
private Category generateCategoryByTimeCateDomain(Date date, String cate, String domain) {
private Category generateCategoryByTimeCategory(Date date, String cate) {
Category category = new Category(cate);
String dbCategoryName = cate + "-alert";
Date startTime = new Date(date.getTime() - DURATION / 2);
Date endTime = new Date(date.getTime() + DURATION / 2);
Date startTime = new Date(date.getTime() - DURATION);
try {
List<Alert> dbAlerts = m_alertDao.queryAlertsByTimeCategoryDomain(startTime, endTime, dbCategoryName, domain,
List<Alert> dbAlerts = m_alertDao.queryAlertsByTimeCategory(startTime, date, dbCategoryName,
AlertEntity.READSET_FULL);
setDBAlertsToCategory(category, dbAlerts);
setDBAlertsToCategoryWithDomain(category, dbAlerts);
} catch (DalException e) {
Cat.logError("find alerts error for category:" + cate + " domain:" + domain + " date:" + date, e);
Cat.logError("find alerts error for category:" + cate + " date:" + date, e);
}
return category;
}
private Category generateCategoryByTimeCategory(Date date, String cate) {
private Category generateCategoryByTimeCateDomain(Date date, String cate, String domain) {
Category category = new Category(cate);
String dbCategoryName = cate + "-alert";
Date startTime = new Date(date.getTime() - DURATION / 2);
Date endTime = new Date(date.getTime() + DURATION / 2);
Date startTime = new Date(date.getTime() - DURATION);
try {
List<Alert> dbAlerts = m_alertDao.queryAlertsByTimeCategory(startTime, endTime, dbCategoryName,
List<Alert> dbAlerts = m_alertDao.queryAlertsByTimeCategoryDomain(startTime, date, dbCategoryName, domain,
AlertEntity.READSET_FULL);
setDBAlertsToCategory(category, dbAlerts);
} catch (DalException e) {
Cat.logError("find alerts error for category:" + cate + " date:" + date, e);
Cat.logError("find alerts error for category:" + cate + " domain:" + domain + " date:" + date, e);
}
return category;
}
private Category generateDependCategoryByTimeCateDomain(Date date, String cate, List<String> dependencyDomains) {
String categoryName = "dependency-" + cate;
String categoryName = "dependency_" + cate;
String dbCategoryName = cate + "-alert";
Category category = new Category(categoryName);
Date startTime = new Date(date.getTime() - DURATION / 2);
Date endTime = new Date(date.getTime() + DURATION / 2);
Date startTime = new Date(date.getTime() - DURATION);
for (String domain : dependencyDomains) {
try {
List<Alert> dbAlerts = m_alertDao.queryAlertsByTimeCategoryDomain(startTime, endTime, dbCategoryName,
domain, AlertEntity.READSET_FULL);
setDBAlertsToDependCategory(category, domain, dbAlerts);
List<Alert> dbAlerts = m_alertDao.queryAlertsByTimeCategoryDomain(startTime, date, dbCategoryName, domain,
AlertEntity.READSET_FULL);
setDBAlertsToCategoryWithDomain(category, dbAlerts);
} catch (DalException e) {
Cat.logError("find dependency alerts error for category:" + cate + " domain:" + domain + " date:" + date, e);
}
......@@ -121,9 +136,21 @@ public class AlertSummaryGenerator {
return category;
}
private List<String> queryDependencyDomains(Date date, String domain) {
private Category generateDependCategoryByTopology(Date date, String cate, TopologyGraph topology, int statusThreshold) {
String categoryName = "dependency_" + cate;
Category category = new Category(categoryName);
for (TopologyEdge edge : topology.getEdges().values()) {
if (edge.getStatus() >= statusThreshold) {
category.addAlert(convertToAlert(edge, date));
}
}
return category;
}
private List<String> queryDependencyDomains(TopologyGraph topology, Date date, String domain) {
List<String> domains = new ArrayList<String>();
TopologyGraph topology = m_topologyManager.buildTopologyGraph(domain, date.getTime());
for (String dependencyDomain : topology.getNodes().keySet()) {
domains.add(dependencyDomain);
......@@ -138,9 +165,9 @@ public class AlertSummaryGenerator {
}
}
private void setDBAlertsToDependCategory(Category category, String domain, List<Alert> dbAlerts) {
private void setDBAlertsToCategoryWithDomain(Category category, List<Alert> dbAlerts) {
for (Alert dbAlert : dbAlerts) {
category.addAlert(convertToDependAlert(domain, dbAlert));
category.addAlert(convertToAlertWithDomain(dbAlert));
}
}
......
package com.dianping.cat.report.task.alert.summary;
import java.util.List;
public class AlertSummarySender {
public void send(String content, List<String> receivers) {
}
}
package com.dianping.cat.report.task.alert.summary;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import com.dianping.cat.home.alert.summary.entity.Alert;
import com.dianping.cat.home.alert.summary.entity.AlertSummary;
import com.dianping.cat.home.alert.summary.entity.Category;
import com.site.lookup.util.StringUtils;
public class AlertSummaryStringDecorator implements AlertSummaryDecorator {
public static final String ID = "AlertSummaryDecorator";
private static final String css = "<style> th, .alert-content { white-space: nowrap; } </style>";
private static final String tableHead = " <table class=\"table table-bordered table-striped table-hover\"> <thead> <tr> <th>告警类型&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th> <th colspan=\"5\">详细警告信息</th> </tr> </thead> <tbody>";
private static final String tableTail = " </tbody></table>";
private static final String[] networkHeaders = { "告警设备", "告警指标", "告警时间", "告警级别", "告警内容" };
private static final String[] businessHeaders = { "告警指标", "告警时间", "告警级别", "告警内容" };
private static final String[] exceptionHeaders = { "异常名称", "告警时间", "告警级别", "告警内容" };
private static final String[] systemHeaders = { "告警参数-机器", "告警时间", "告警级别", "告警内容" };
private static final String[] dependencyEdgeHeaders = { "依赖项目", "告警指标", "告警时间", "告警级别", "告警内容" };
private static final String[] dependencyExceptionHeaders = { "依赖项目", "异常名称", "告警时间", "告警级别", "告警内容" };
public String generateHtml(AlertSummary alertSummary) {
StringBuilder builder = new StringBuilder();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String domain = alertSummary.getDomain();
Date date = alertSummary.getAlertDate();
String dateStr = dateFormat.format(date);
builder.append(css);
builder.append(generateTitle(domain, dateStr));
builder.append(tableHead);
builder.append(generateCategoryHtml(alertSummary.findCategory("network"), "网络告警", networkHeaders));
builder.append(generateCategoryHtml(alertSummary.findCategory("business"), "业务告警", businessHeaders));
builder.append(generateCategoryHtml(alertSummary.findCategory("exception"), "异常告警", exceptionHeaders));
builder.append(generateCategoryHtml(alertSummary.findCategory("dependency-business"), "超时依赖调用",
dependencyEdgeHeaders));
builder.append(generateCategoryHtml(alertSummary.findCategory("dependency-exception"), "依赖异常告警",
dependencyExceptionHeaders));
builder.append(generateCategoryHtml(alertSummary.findCategory("system"), "系统告警", systemHeaders));
builder.append(tableTail);
return builder.toString();
}
private String generateTitle(String domain, String dateStr) {
return "<h4> 项目名:&nbsp;" + domain + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;告警时间:&nbsp;" + dateStr
+ " </h4>";
}
private String generateCategoryHtml(Category category, String categoryName, String[] headers) {
List<Alert> alerts = category.getAlerts();
int rowspan = alerts.size() + 1;
StringBuilder builder = new StringBuilder();
builder.append(generateTitleRow(categoryName, headers, rowspan));
for (Alert alert : alerts) {
builder.append(generateDataRow(alert));
}
return builder.toString();
}
private String generateTitleRow(String categoryName, String[] headers, int rowspan) {
StringBuilder builder = new StringBuilder();
builder.append("<tr> <td class=\"text-success\" rowspan=\"").append(rowspan).append("\"");
builder.append("<strong>").append(categoryName).append("</strong></td>");
int length = headers.length;
if (length == 5) {
builder.append("<th>").append(headers[0]).append("</th>");
} else if (length == 4) {
builder.append("<th colspan=\"2\">").append(headers[0]).append("</th>");
}
for (int i = 1; i < length; i++) {
builder.append("<th>").append(headers[i]).append("</th>");
}
builder.append("</tr>");
return builder.toString();
}
private String generateDataRow(Alert alert) {
StringBuilder builder = new StringBuilder();
String domain = alert.getDomain();
builder.append("<tr>");
if (StringUtils.isEmpty(domain)) {
builder.append(generateTd(alert.getMetric(), null, 2));
} else {
builder.append(generateTd(domain, null, 1));
builder.append(generateTd(alert.getMetric(), null, 1));
}
builder.append(generateTd(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(alert.getAlertTime()), null, 1));
builder.append(generateTd(alert.getType(), null, 1));
builder.append(generateTd(alert.getContext(), "alert-content", 1));
builder.append("</tr>");
return builder.toString();
}
private String generateTd(String content, String className, int colspan) {
StringBuilder builder = new StringBuilder();
builder.append("<td");
if (!StringUtils.isEmpty(className)) {
builder.append(" class=\"").append(className).append("\"");
}
if (colspan > 1) {
builder.append(" colspan=\"").append(colspan).append("\"");
}
builder.append(">").append(content).append("</td>");
return builder.toString();
}
}
package com.dianping.cat.report.task.alert.summary;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.dianping.cat.home.alert.summary.entity.Alert;
import com.dianping.cat.home.alert.summary.entity.AlertSummary;
import com.dianping.cat.home.alert.summary.entity.Category;
import com.dianping.cat.home.alert.summary.transform.BaseVisitor;
public class AlertSummaryVisitor extends BaseVisitor {
private Map<Object, Object> m_result = new HashMap<Object, Object>();
private Map<Object, Object> m_categoryMap = new HashMap<Object, Object>();
private List<Map<Object, Object>> m_alertList;
private DateFormat m_fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
public Map<Object, Object> getResult() {
return m_result;
}
@Override
public void visitAlert(Alert alert) {
Map<Object, Object> tmpALertMap = new HashMap<Object, Object>();
tmpALertMap.put("dateStr", m_fmt.format(alert.getAlertTime()));
tmpALertMap.put("domain", alert.getDomain());
tmpALertMap.put("metric", alert.getMetric());
tmpALertMap.put("type", alert.getType());
tmpALertMap.put("context", alert.getContext());
m_alertList.add(tmpALertMap);
}
@Override
public void visitAlertSummary(AlertSummary alertSummary) {
Date date = alertSummary.getAlertDate();
m_result.put("domain", alertSummary.getDomain());
m_result.put("dateStr", m_fmt.format(date));
m_result.put("categories", m_categoryMap);
for (Category category : alertSummary.getCategories().values()) {
visitCategory(category);
}
}
@Override
public void visitCategory(Category category) {
m_alertList = new ArrayList<Map<Object, Object>>();
for (Alert alert : category.getAlerts()) {
visitAlert(alert);
}
m_categoryMap.put(category.getName(), m_alertList);
}
}
package com.dianping.cat.report.task.alert.system;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import org.codehaus.plexus.logging.LogEnabled;
......@@ -11,7 +10,6 @@ import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.consumer.company.model.entity.ProductLine;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.report.task.alert.BaseAlert;
import com.dianping.cat.report.task.alert.BaseAlertConfig;
......@@ -30,7 +28,7 @@ public class SystemAlert extends BaseAlert implements Task, LogEnabled {
public String getName() {
return "system-alert";
}
@Override
public BaseAlertConfig getAlertConfig() {
return m_alertConfig;
......@@ -87,21 +85,6 @@ public class SystemAlert extends BaseAlert implements Task, LogEnabled {
}
}
@Override
protected void sendAlertInfo(ProductLine productLine, String title, String content, String alertType) {
List<String> emails = m_alertConfig.buildMailReceivers(productLine);
m_logger.info(title + " " + content + " " + emails);
m_mailSms.sendEmail(title, content, emails);
if (alertType != null && alertType.equals("error")) {
List<String> phones = m_alertConfig.buildSMSReceivers(productLine);
m_mailSms.sendSms(title + " " + content, content, phones);
}
Cat.logEvent("SystemAlert", productLine.getId(), Event.SUCCESS, title + " " + content);
}
@Override
public void shutdown() {
}
......
......@@ -21,6 +21,7 @@ import com.dianping.cat.home.nettopo.entity.NetTopology;
import com.dianping.cat.home.nettopo.transform.DefaultNativeBuilder;
import com.dianping.cat.report.page.network.nettopology.NetGraphBuilder;
import com.dianping.cat.report.service.ReportService;
import com.dianping.cat.report.task.alert.AlertInfo.AlertMetric;
import com.dianping.cat.report.task.spi.ReportTaskBuilder;
import com.dianping.cat.system.config.NetGraphConfigManager;
......@@ -31,7 +32,7 @@ public class NetTopologyReportBuilder implements ReportTaskBuilder {
@Inject
private NetGraphBuilder m_netGraphBuilder;
@Inject
private NetGraphConfigManager m_netGraphConfigManager;
......@@ -52,7 +53,7 @@ public class NetTopologyReportBuilder implements ReportTaskBuilder {
}
}
}
Map<String, MetricReport> reports = new HashMap<String, MetricReport>();
for (String group : groups) {
......@@ -61,8 +62,9 @@ public class NetTopologyReportBuilder implements ReportTaskBuilder {
reports.put(group, report);
}
NetGraphSet netGraphSet = m_netGraphBuilder.buildGraphSet(netGraphTemplate, reports, new ArrayList<String>());
NetGraphSet netGraphSet = m_netGraphBuilder
.buildGraphSet(netGraphTemplate, reports, new ArrayList<AlertMetric>());
HourlyReport hourlyReport = new HourlyReport();
hourlyReport.setType(1);
......
......@@ -22,7 +22,7 @@ public class NavigationBar {
return new Page[] {
ReportPage.METRIC,
ReportPage.USERMONITOR,
ReportPage.APP,
......@@ -44,9 +44,9 @@ public class NavigationBar {
ReportPage.DEPENDENCY,
ReportPage.NETWORK,
ReportPage.CDN,
ReportPage.SYSTEM,
ReportPage.ALTERATION,
......@@ -54,9 +54,8 @@ public class NavigationBar {
ReportPage.STATE,
ReportPage.STATISTICS,
ReportPage.LOGVIEW,
ReportPage.LOGVIEW,
};
}
}
......@@ -15,15 +15,15 @@
<statement><![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='alert_time'/> >= ${start-time}
AND <FIELD name='alert_time'/> <= ${end-time}
WHERE <FIELD name='alert-time'/> >= ${start-time}
AND <FIELD name='alert-time'/> <= ${end-time}
<IF type='NOT_NULL' field='category'>
AND <FIELD name='category'/> = ${category}
</IF>
<IF type='NOT_NULL' field='domain'>
AND <FIELD name='domain'/> = ${domain}
</IF>
ORDER BY <FIELD name='alert_time'/> asc
ORDER BY <FIELD name='alert-time'/> asc
]]></statement>
</query>
<query name="query-alerts-by-time-category" type="SELECT"
......@@ -34,16 +34,19 @@
<statement><![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='alert_time'/> >= ${start-time}
AND <FIELD name='alert_time'/> <= ${end-time}
WHERE <FIELD name='alert-time'/> >= ${start-time}
AND <FIELD name='alert-time'/> <= ${end-time}
<IF type='NOT_NULL' field='category'>
AND <FIELD name='category'/> = ${category}
</IF>
ORDER BY <FIELD name='alert_time'/> asc
ORDER BY <FIELD name='alert-time'/> asc
]]></statement>
</query>
</query-defs>
</entity>
<entity name="alert-summary" table="alert_summary" alias="as">
<member name="creation-date" insert-expr="NOW()" />
</entity>
<entity name="alteration" table="alteration" alias="a">
<member name="creation-date" insert-expr="NOW()" />
<var name="start-time" value-type="Date" />
......
......@@ -14,6 +14,7 @@
<attribute name="type" value-type="String" />
<attribute name="metric" value-type="String" />
<attribute name="context" value-type="String" />
<attribute name="domain" value-type="String" />
</entity>
</model>
<?xml version="1.0" encoding="UTF-8"?>
<model model-package="com.dianping.cat.home.alert.summary"
enable-sax-parser="true" enable-xml-parser="true" enable-xml-builder="true">
enable-sax-parser="true" enable-xml-parser="true" enable-xml-builder="true" enable-base-visitor="true" >
</model>
\ No newline at end of file
......@@ -300,6 +300,9 @@
<requirement>
<role>com.dianping.cat.report.task.alert.AlertInfo</role>
</requirement>
<requirement>
<role>com.dianping.cat.core.dal.ProjectDao</role>
</requirement>
</requirements>
</component>
<component>
......@@ -1834,6 +1837,33 @@
<role>com.dianping.cat.report.task.alert.DataChecker</role>
<implementation>com.dianping.cat.report.task.alert.DefaultDataChecker</implementation>
</component>
<component>
<role>com.dianping.cat.report.task.alert.sender.MailSender</role>
<implementation>com.dianping.cat.report.task.alert.sender.MailSender</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.system.tool.MailSMS</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.sender.SmsSender</role>
<implementation>com.dianping.cat.report.task.alert.sender.SmsSender</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.system.tool.MailSMS</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.sender.WeixinSender</role>
<implementation>com.dianping.cat.report.task.alert.sender.WeixinSender</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.system.tool.MailSMS</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.business.BusinessAlert</role>
<implementation>com.dianping.cat.report.task.alert.business.BusinessAlert</implementation>
......@@ -1868,6 +1898,18 @@
<requirement>
<role>com.dianping.cat.report.task.alert.DataChecker</role>
</requirement>
<requirement>
<role>com.dianping.cat.core.dal.ProjectDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.MailSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.SmsSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.WeixinSender</role>
</requirement>
</requirements>
</component>
<component>
......@@ -1904,6 +1946,18 @@
<requirement>
<role>com.dianping.cat.report.task.alert.DataChecker</role>
</requirement>
<requirement>
<role>com.dianping.cat.core.dal.ProjectDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.MailSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.SmsSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.WeixinSender</role>
</requirement>
</requirements>
</component>
<component>
......@@ -1940,6 +1994,18 @@
<requirement>
<role>com.dianping.cat.report.task.alert.DataChecker</role>
</requirement>
<requirement>
<role>com.dianping.cat.core.dal.ProjectDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.MailSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.SmsSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.WeixinSender</role>
</requirement>
</requirements>
</component>
<component>
......@@ -1977,6 +2043,60 @@
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>top</role-hint>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.MailSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.SmsSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.sender.WeixinSender</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.system.tool.MailSMS</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryDecorator</role>
<role-hint>AlertSummaryFTLDecorator</role-hint>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryDecorator</role>
<role-hint>AlertSummaryFTLDecorator</role-hint>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryFTLDecorator</implementation>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.AlertDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.dependency.graph.TopologyGraphManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.AlertSummaryDao</role>
</requirement>
</requirements>
</component>
<component>
......@@ -3114,6 +3234,9 @@
<role>com.dianping.cat.report.page.metric.graph.MetricGraphCreator</role>
<implementation>com.dianping.cat.report.page.metric.graph.MetricGraphCreator</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.core.dal.ProjectDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.baseline.BaselineService</role>
</requirement>
......@@ -3338,6 +3461,9 @@
<requirement>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</role>
</requirement>
</requirements>
</component>
<component>
......@@ -3358,6 +3484,65 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryDecorator</role>
<role-hint>AlertSummaryFTLDecorator</role-hint>
<field-name>m_alertSummaryDecorator</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.system.tool.MailSMS</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.AlertDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.dependency.graph.TopologyGraphManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.AlertDao</role>
<implementation>com.dianping.cat.home.dal.report.AlertDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.AlertSummaryDao</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.AlertSummaryDao</role>
<implementation>com.dianping.cat.home.dal.report.AlertSummaryDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.alteration.Handler</role>
<implementation>com.dianping.cat.report.page.alteration.Handler</implementation>
......@@ -6800,6 +6985,9 @@
<role>com.dianping.cat.report.page.metric.graph.MetricGraphCreator</role>
<implementation>com.dianping.cat.report.page.metric.graph.MetricGraphCreator</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.core.dal.ProjectDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.baseline.BaselineService</role>
</requirement>
......@@ -7024,6 +7212,9 @@
<requirement>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</role>
</requirement>
</requirements>
</component>
<component>
......@@ -7044,6 +7235,65 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryExecutor</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryDecorator</role>
<role-hint>AlertSummaryFTLDecorator</role-hint>
<field-name>m_alertSummaryDecorator</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.system.tool.MailSMS</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryGenerator</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.AlertDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.dependency.graph.TopologyGraphManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.AlertDao</role>
<implementation>com.dianping.cat.home.dal.report.AlertDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</role>
<implementation>com.dianping.cat.report.task.alert.summary.AlertSummaryManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.AlertSummaryDao</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.AlertSummaryDao</role>
<implementation>com.dianping.cat.home.dal.report.AlertSummaryDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.alteration.Handler</role>
<implementation>com.dianping.cat.report.page.alteration.Handler</implementation>
......
<div id="summaryContent">
<style>
th, .alert-content {
white-space: nowrap;
}
</style>
<h4>
项目名:&nbsp;${domain}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;告警时间:&nbsp;${dateStr}
</h4>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>告警类型&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
<th colspan="5">详细警告信息</th>
</tr>
</thead>
<tbody>
<#assign length = categories.network?size />
<#if length == 0>
<tr>
<td class="text-success"><strong>网络告警</strong></td>
<td class="text-success" colspan="5"><strong>网络状况正常</strong></td>
</tr>
<#else>
<tr>
<td class="text-success" rowspan="${length + 1}"><strong>网络告警</strong></td>
<th>告警设备</th>
<th>告警指标</th>
<th>告警时间</th>
<th>告警级别</th>
<th>告警内容</th>
</tr>
<#list categories.network as item>
<tr>
<td>${item.domain}</td>
<td>${item.metric}</td>
<td>${item.dateStr}</td>
<td>${item.type}</td>
<td class="alert-content">${item.context}</td>
</tr>
</#list>
</#if>
<#assign length = categories.business?size />
<#if length == 0>
<tr>
<td class="text-success"><strong>业务告警</strong></td>
<td class="text-success" colspan="5"><strong>业务状况正常</strong></td>
</tr>
<#else>
<tr>
<td class="text-success" rowspan="${length + 1}"><strong>业务告警</strong></td>
<th colspan="2">告警指标</th>
<th>告警时间</th>
<th>告警级别</th>
<th>告警内容</th>
</tr>
<#list categories.business as item>
<tr>
<td colspan="2">${item.metric}</td>
<td>${item.dateStr}</td>
<td>${item.type}</td>
<td class="alert-content">${item.context}</td>
</tr>
</#list>
</#if>
<#assign length = categories.exception?size />
<#if length == 0>
<tr>
<td class="text-success"><strong>异常告警</strong></td>
<td class="text-success" colspan="5"><strong>异常告警正常</strong></td>
</tr>
<#else>
<tr>
<td class="text-success" rowspan="${length + 1}"><strong>异常告警</strong></td>
<th colspan="2">异常名称</th>
<th>告警时间</th>
<th>告警级别</th>
<th>告警内容</th>
</tr>
<#list categories.exception as item>
<tr>
<td colspan="2">${item.metric}</td>
<td>${item.dateStr}</td>
<td>${item.type}</td>
<td class="alert-content">${item.context}</td>
</tr>
</#list>
</#if>
<#if categories.dependency_business_length == 0>
<tr>
<td class="text-success"><strong>超时依赖调用</strong></td>
<td class="text-success" colspan="5"><strong>无超时依赖调用</strong></td>
</tr>
<#else>
<tr>
<td class="text-success" rowspan="${categories.dependency_business_length + 1}"><strong>超时依赖调用</strong></td>
<th>依赖项目</th>
<th>告警指标</th>
<th>告警时间</th>
<th>告警级别</th>
<th>告警内容</th>
</tr>
<#list categories.dependency_business?keys as key>
<#list categories.dependency_business[key] as value>
<tr>
<#if value_index == 0>
<td rowspan="${categories.dependency_business[key]?size}">${key}</td>
</#if>
<td>${value.metric}</td>
<td>${value.dateStr}</td>
<td>${value.type}</td>
<td class="alert-content">${value.context}</td>
</tr>
</#list>
</#list>
</#if>
<#assign length = categories.dependency_exception?size />
<#if length == 0>
<tr>
<td class="text-success"><strong>依赖异常告警</strong></td>
<td class="text-success" colspan="5"><strong>依赖项目正常</strong></td>
</tr>
<#else>
<tr>
<td class="text-success" rowspan="${length + 1}"><strong>依赖异常告警</strong></td>
<th>依赖项目</th>
<th>异常名称</th>
<th>告警时间</th>
<th>告警级别</th>
<th>告警内容</th>
</tr>
<#list categories.dependency_exception as item>
<tr>
<td>${item.domain}</td>
<td>${item.metric}</td>
<td>${item.dateStr}</td>
<td>${item.type}</td>
<td class="alert-content">${item.context}</td>
</tr>
</#list>
</#if>
<#assign length = categories.system?size />
<#if length == 0>
<tr>
<td class="text-success"><strong>系统告警</strong></td>
<td class="text-success" colspan="5"><strong>系统状态正常</strong></td>
</tr>
<#else>
<tr>
<td class="text-success" rowspan="${length + 1}"><strong>系统告警</strong></td>
<th colspan="2">告警参数-机器</th>
<th>告警时间</th>
<th>告警级别</th>
<th>告警内容</th>
</tr>
<#list categories.system as item>
<tr>
<td colspan="2">${item.metric}</td>
<td>${item.dateStr}</td>
<td>${item.type}</td>
<td class="alert-content">${item.context}</td>
</tr>
</#list>
</#if>
</tbody>
</table>
</div>
\ No newline at end of file
......@@ -4,6 +4,7 @@
<ul class="nav nav-list">
<li class='nav-header text-center'><h4>报表中心</h4></li>
<li id="bug" class="text-right" id="bug"><a href="?domain=${model.domain}&ip=${model.ipAddress}&date=${model.date}&op=view"><strong>项目异常</strong></a></li>
<li id="summary" class="text-right" id="summary"><a href="?domain=${model.domain}&ip=${model.ipAddress}&date=${model.date}&op=summary"><strong>统一告警</strong></a></li>
<li id="alert" class="text-right" id="alert"><a href="?domain=${model.domain}&ip=${model.ipAddress}&date=${model.date}&op=alert"><strong>异常告警</strong></a></li>
<li id="utilization" class="text-right" id="service"><a href="?domain=${model.domain}&ip=${model.ipAddress}&date=${model.date}&op=utilization"><strong>容量规划</strong></a></li>
<li id="service" class="text-right" id="service"><a href="?domain=${model.domain}&ip=${model.ipAddress}&date=${model.date}&op=service"><strong>服务可用性</strong></a></li>
......
<%@ page session="false" language="java" pageEncoding="UTF-8" %>
<div class="span10">
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
</div>
</div>
</div>
</div>
<br>
<table class="table table-striped table-bordered table-condensed table-hover" id="contents" width="100%">
<thead>
<tr class="odd">
<th width="40%">域名</th>
<th width="20%">Warning警告</th>
<th width="20%">Error警告</th>
<th width="20%">Detail</th>
</tr>
</thead>
<tbody>
<table class="table table-striped table-bordered table-condensed table-hover" id="contents" width="100%">
<thead>
<tr class="odd">
<th width="40%">域名</th>
<th width="20%">Warning警告</th>
<th width="20%">Error警告</th>
<th width="20%">Detail</th>
</tr>
</thead>
<tbody>
<c:forEach var="domain" items="${model.alertDomains}">
<tr>
<td>${domain.name}</td>
<td>${domain.warnNumber}</td>
<td>${domain.errorNumber}</td>
<td><a class='detail btn btn-primary btn-small' href="?op=alertDetail&domain=${domain.name}&date=${model.date}">Detail</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</tr>
</c:forEach>
</tbody>
</table>
</div>
\ No newline at end of file
<%@ page session="false" language="java" pageEncoding="UTF-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<div class="span10">
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
</div>
</div>
</div>
</div>
<br>
<form id="form" method="post" action="?op=summary">
警告时间
<input type="text" name="summarytime" id="summarytime" value="<fmt:formatDate value="${payload.summarytime}" pattern="yyyy-MM-dd HH:mm:ss"/>" style="height:auto" class="input-medium" placeholder="格式如:2014-07-01 00:00:00">
应用名
<input type="text" name="summarydomain" id="summarydomain" value="${payload.summarydomain}" style="height:auto" class="input-small">
发送邮箱
<input type="text" name="summaryemails" id="summaryemails" value="${payload.summaryemails}" style="height:auto;width:200px" class="input-small" placeholder="用半角逗号分割,可为空">
<input class="btn btn-primary btn-small" value="查询" type="submit">
</form>
${model.summaryContent}
</div>
\ No newline at end of file
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="a" uri="/WEB-INF/app.tld"%>
<%@ taglib prefix="w" uri="http://www.unidal.org/web/core"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="res" uri="http://www.unidal.org/webres"%>
<jsp:useBean id="ctx" type="com.dianping.cat.report.page.statistics.Context" scope="request"/>
<jsp:useBean id="payload" type="com.dianping.cat.report.page.statistics.Payload" scope="request"/>
<jsp:useBean id="model" type="com.dianping.cat.report.page.statistics.Model" scope="request"/>
<a:body>
<res:useCss value='${res.css.local.table_css}' target="head-css" />
<res:useJs value="${res.js.local['bootstrap.min.js']}" target="head-js"/>
<script type="text/javascript">
$(document).ready(function() {
$('#summary').addClass('active');
$(document).delegate('.detail', 'click', function(e){
var anchor = this,
el = $(anchor);
if(e.ctrlKey || e.metaKey){
return true;
}else{
e.preventDefault();
}
$.ajax({
type: "get",
url: anchor.href,
success : function(response, textStatus) {
$('#myModal .modal-body').html(response);
$('#myModal').modal().css({
width: 'auto',
'margin-left': function () {
return -($(this).width() / 2);
}
});
}
});
});
});
</script>
<div class="report">
<table class="header">
<tr>
<td class="title"><span class="text-success"><span class="text-error">【报表时间】</span><span class="text-success">&nbsp;&nbsp;From ${w:format(payload.historyStartDate,'yyyy-MM-dd HH:mm:ss')} to ${w:format(payload.historyDisplayEndDate,'yyyy-MM-dd HH:mm:ss')}</span></td>
</td>
<td class="nav" >
<a href="?domain=${model.domain}&op=summary" class="switch"><span class="text-error">【切到历史模式】</span></a>
<c:forEach var="nav" items="${model.navs}">
&nbsp;[ <a href="${model.baseUri}?op=summary&date=${model.date}&step=${nav.hours}&${navUrlPrefix}">${nav.title}</a> ]&nbsp;
</c:forEach>
&nbsp;[ <a href="${model.baseUri}?${navUrlPrefix}&op=alert">now</a> ]&nbsp;
</td>
</tr>
</table>
</div>
<div class="row-fluid">
<div class="span2">
<%@include file="../bugTree.jsp"%>
</div>
<div class="span10">
<div class="report">
<%@ include file="detail.jsp"%>
</div>
</div>
</div>
</a:body>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册