提交 f04844ca 编写于 作者: F Frankie Wu

Merge pull request #58 from youyong205/biz

Biz
......@@ -33,6 +33,11 @@
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.unidal.webres</groupId>
<artifactId>WebResServer</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
......@@ -58,14 +63,13 @@
<goal>dal-model</goal>
</goals>
<configuration>
<manifest>
${basedir}/src/main/resources/META-INF/dal/model/sql-report-manifest.xml,
<manifest>${basedir}/src/main/resources/META-INF/dal/model/sql-report-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/database-report-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/cross-report-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/matrix-report-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/metric-report-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/health-report-manifest.xml,
</manifest>
${basedir}/src/main/resources/META-INF/dal/model/dependency-report-manifest.xml,</manifest>
</configuration>
</execution>
<execution>
......@@ -86,9 +90,17 @@
<goal>dal-jdbc</goal>
</goals>
<configuration>
<manifest><![CDATA[
${basedir}/src/main/resources/META-INF/dal/jdbc/report-manifest.xml,
]]></manifest>
<manifest><![CDATA[${basedir}/src/main/resources/META-INF/dal/jdbc/report-manifest.xml,]]></manifest>
</configuration>
</execution>
<execution>
<id>generate dal model files</id>
<phase>generate-sources</phase>
<goals>
<goal>dal-model</goal>
</goals>
<configuration>
<manifest><![CDATA[${basedir}/src/main/resources/META-INF/dal/model/dependency-report-manifest.xml,]]></manifest>
</configuration>
</execution>
</executions>
......
package com.dianping.cat.report.page.cross;
package com.dianping.cat.consumer;
import java.io.InputStream;
import java.net.HttpURLConnection;
......
......@@ -302,7 +302,6 @@ public class CrossAnalyzer extends AbstractMessageAnalyzer<CrossReport> implemen
String remoteIp = info.getRemoteAddress();
String role = info.getRemoteRole();
String transactionName = t.getName();
Local client = report.findOrCreateLocal(localIp);
Remote server = client.findOrCreateRemote(remoteIp);
......@@ -315,6 +314,7 @@ public class CrossAnalyzer extends AbstractMessageAnalyzer<CrossReport> implemen
type.setId(info.getDetailType());
server.setType(type);
}
Name name = type.findOrCreateName(transactionName);
type.incTotalCount();
......
......@@ -64,7 +64,7 @@ public class DatabaseAnalyzer extends AbstractMessageAnalyzer<DatabaseReport> im
if (connection != null && method != null) {
DatabaseItem item = new DatabaseItem();
String tables = m_sqlParseManeger.getTableNames(sqlName, sqlStatement, domain);
String database = getDatabaseName(connection);
String database = DatabaseParseUtil.parseDatabaseName(connection);
if (database == null) {
database = "Unknown";
......@@ -85,33 +85,6 @@ public class DatabaseAnalyzer extends AbstractMessageAnalyzer<DatabaseReport> im
m_logger = logger;
}
String getDatabaseName(String url) {
if (url != null) {
if (url.indexOf("mysql") > -1) {
try {
int index = url.indexOf("://");
String temp = url.substring(index + 3);
index = temp.indexOf("/");
int index2 = temp.indexOf("?");
String schema = temp.substring(index + 1, index2 != -1 ? index2 : temp.length());
return schema;
} catch (Exception e) {
}
} else if (url.indexOf("sqlserver") > -1) {
String temp = url.substring(url.indexOf("databaseName"));
int first = temp.indexOf("=");
int end = temp.indexOf(";");
if (first > -1 && end > -1) {
return temp.substring(first + 1, end);
}
}
}
return null;
}
@Override
public Set<String> getDomains() {
return m_reports.keySet();
......
package com.dianping.cat.consumer.advanced;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DatabaseParseUtil {
public static Map<String, String> m_connections = new ConcurrentHashMap<String, String>();
public static String parseDatabaseName(String connectionUrl) {
String database = m_connections.get(connectionUrl);
if (database != null) {
return database;
} else {
if (connectionUrl.indexOf("mysql") > -1) {
try {
int index = connectionUrl.indexOf("://");
String temp = connectionUrl.substring(index + 3);
index = temp.indexOf("/");
int index2 = temp.indexOf("?");
database = temp.substring(index + 1, index2 != -1 ? index2 : temp.length());
} catch (Exception e) {
}
} else if (connectionUrl.indexOf("sqlserver") > -1) {
String temp = connectionUrl.substring(connectionUrl.indexOf("databaseName"));
int first = temp.indexOf("=");
int end = temp.indexOf(";");
if (first > -1 && end > -1) {
database = temp.substring(first + 1, end);
}
}
}
if (database != null) {
m_connections.put(connectionUrl, database);
}
return database;
}
}
package com.dianping.cat.consumer.advanced;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.unidal.lookup.annotation.Inject;
import com.dainping.cat.consumer.core.dal.Report;
import com.dainping.cat.consumer.core.dal.ReportDao;
import com.dianping.cat.Cat;
import com.dianping.cat.configuration.NetworkInterfaceManager;
import com.dianping.cat.consumer.AbstractMessageAnalyzer;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.dependency.model.entity.Dependency;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.entity.Index;
import com.dianping.cat.consumer.dependency.model.entity.Segment;
import com.dianping.cat.consumer.dependency.model.transform.DefaultSaxParser;
import com.dianping.cat.consumer.dependency.model.transform.DefaultXmlBuilder;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.message.internal.MessageId;
import com.dianping.cat.message.spi.MessageTree;
import com.dianping.cat.storage.Bucket;
import com.dianping.cat.storage.BucketManager;
public class DependencyAnalyzer extends AbstractMessageAnalyzer<DependencyReport> implements LogEnabled {
public static final String ID = "dependency";
@Inject
private BucketManager m_bucketManager;
@Inject
private ReportDao m_reportDao;
@Inject
private DomainManager m_domainManager;
private Map<String, DependencyReport> m_reports = new HashMap<String, DependencyReport>();
private Set<String> m_types = new HashSet<String>(Arrays.asList("URL", "SQL", "Call", "PigeonCall", "Service",
"PigeonService"));
private Set<String> m_exceptions = new HashSet<String>(Arrays.asList("Exception", "RuntimeException", "Error"));
private static final String UNKNOWN = "UnknownIp";
@Override
public void doCheckpoint(boolean atEnd) {
storeReports(atEnd);
}
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
}
@Override
public Set<String> getDomains() {
return m_reports.keySet();
}
@Override
public DependencyReport getReport(String domain) {
DependencyReport report = m_reports.get(domain);
if (report == null) {
report = new DependencyReport(domain);
report.setStartTime(new Date(m_startTime));
report.setEndTime(new Date(m_startTime + MINUTE * 60 - 1));
}
report.getDomainNames().addAll(m_reports.keySet());
return report;
}
public boolean isIp(String ip) {
boolean result = false;
try {
char first = ip.charAt(0);
char next = ip.charAt(1);
if (first >= '0' && first <= '9') {
if (next >= '0' && next <= '9') {
return true;
}
}
} catch (Exception e) {
}
return result;
}
@Override
protected void loadReports() {
Bucket<String> reportBucket = null;
try {
reportBucket = m_bucketManager.getReportBucket(m_startTime, "dependency");
for (String id : reportBucket.getIds()) {
String xml = reportBucket.findById(id);
DependencyReport report = DefaultSaxParser.parse(xml);
m_reports.put(report.getDomain(), report);
}
} catch (Exception e) {
m_logger.error(String.format("Error when loading dependency reports of %s!", new Date(m_startTime)), e);
} finally {
if (reportBucket != null) {
m_bucketManager.closeBucket(reportBucket);
}
}
}
private String parseDatabase(Transaction t) {
List<Message> messages = t.getChildren();
for (Message message : messages) {
if (message instanceof Event) {
String type = message.getType();
if (type.equals("SQL.Database")) {
return DatabaseParseUtil.parseDatabaseName(message.getName());
}
}
}
return null;
}
private String parseIpFromPigeonClientTransaction(Transaction t, MessageTree tree) {
List<Message> messages = t.getChildren();
for (Message message : messages) {
if (message instanceof Event) {
if (message.getType().equals("PigeonCall.server")) {
String name =message.getName();
int index = name.indexOf(":");
if (index > 0) {
name = name.substring(0, index);
}
return name;
}
}
}
return UNKNOWN;
}
private String parseIpFromPigeonServerTransaction(Transaction t, MessageTree tree) {
String clientIp = UNKNOWN;
List<Message> messages = t.getChildren();
for (Message message : messages) {
if (message instanceof Event) {
if (message.getType().equals("PigeonService.client")) {
String name = message.getName();
int index = name.indexOf(":");
if (index > 0) {
name = name.substring(0, index);
}
if (isIp(name)) {
clientIp = name;
}
break;
}
}
}
if (clientIp.equals(UNKNOWN)) {
MessageId id = MessageId.parse(tree.getMessageId());
String remoteIp = id.getIpAddress();
clientIp = remoteIp;
}
return clientIp;
}
@Override
public void process(MessageTree tree) {
String domain = tree.getDomain();
DependencyReport report = m_reports.get(domain);
if (report == null) {
report = new DependencyReport(domain);
report.setStartTime(new Date(m_startTime));
report.setEndTime(new Date(m_startTime + MINUTE * 60 - 1));
m_reports.put(domain, report);
}
Message message = tree.getMessage();
if (message instanceof Transaction) {
processTransaction(report, tree, (Transaction) message);
} else if (message instanceof Event) {
processEvent(report, tree, (Event) message);
}
}
private void processEvent(DependencyReport report, MessageTree tree, Event event) {
String type = event.getType();
if (m_exceptions.contains(type)) {
long current = event.getTimestamp() / 1000 / 60;
int min = (int) (current % (60));
Segment segment = report.findOrCreateSegment(min);
segment.incExceptionCount();
}
}
private void processPigeonTransaction(DependencyReport report, MessageTree tree, Transaction t) {
String type = t.getType();
if ("PigeonCall".equals(type) || "Call".equals(type)) {
String ip = parseIpFromPigeonClientTransaction(t, tree);
String domain = m_domainManager.getDomainByIp(ip);
String callType = "PigeonClient";
updateDependencyInfo(report, t, domain, callType);
} else if ("PigeonService".equals(type) || "Service".equals(type)) {
String ip = parseIpFromPigeonServerTransaction(t, tree);
String domain = m_domainManager.getDomainByIp(ip);
String callType = "PigeonServer";
updateDependencyInfo(report, t, domain, callType);
}
}
private void processSqlTransaction(DependencyReport report, Transaction t) {
String type = t.getType();
if ("SQL".equals(type)) {
String database = parseDatabase(t);
if (database != null) {
updateDependencyInfo(report, t, database, "Database");
}
}
}
private void processTransaction(DependencyReport report, MessageTree tree, Transaction t) {
if (shouldDiscard(t)) {
return;
}
processTransactionType(report, t);
processSqlTransaction(report, t);
processPigeonTransaction(report, tree, t);
List<Message> children = t.getChildren();
for (Message child : children) {
if (child instanceof Transaction) {
processTransaction(report, tree, (Transaction) child);
} else if (child instanceof Event) {
processEvent(report, tree, (Event) child);
}
}
}
private void processTransactionType(DependencyReport report, Transaction t) {
String type = t.getType();
if (m_types.contains(type) || type.startsWith("Cache.")) {
long current = t.getTimestamp() / 1000 / 60;
int min = (int) (current % (60));
Segment segment = report.findOrCreateSegment(min);
Index index = segment.findOrCreateIndex(type);
if (!t.getStatus().equals(Transaction.SUCCESS)) {
index.incErrorCount();
}
index.incTotalCount();
index.setSum(index.getSum() + t.getDurationInMillis());
index.setAvg(index.getSum() / index.getTotalCount());
}
}
private void storeReports(boolean atEnd) {
DefaultXmlBuilder builder = new DefaultXmlBuilder(true);
Bucket<String> reportBucket = null;
Transaction t = Cat.getProducer().newTransaction("Checkpoint", getClass().getSimpleName());
t.setStatus(Message.SUCCESS);
try {
reportBucket = m_bucketManager.getReportBucket(m_startTime, "dependency");
for (DependencyReport report : m_reports.values()) {
try {
Set<String> domainNames = report.getDomainNames();
domainNames.clear();
domainNames.addAll(getDomains());
String xml = builder.buildXml(report);
String domain = report.getDomain();
reportBucket.storeById(domain, xml);
} catch (Exception e) {
t.setStatus(e);
Cat.logError(e);
}
}
if (atEnd && !isLocalMode()) {
Date period = new Date(m_startTime);
String ip = NetworkInterfaceManager.INSTANCE.getLocalHostAddress();
for (DependencyReport report : m_reports.values()) {
try {
Report r = m_reportDao.createLocal();
String xml = builder.buildXml(report);
String domain = report.getDomain();
r.setName("dependency");
r.setDomain(domain);
r.setPeriod(period);
r.setIp(ip);
r.setType(1);
r.setContent(xml);
m_reportDao.insert(r);
} catch (Throwable e) {
t.setStatus(e);
Cat.getProducer().logError(e);
}
}
}
} catch (Exception e) {
Cat.getProducer().logError(e);
t.setStatus(e);
m_logger.error(String.format("Error when storing dependency reports of %s!", new Date(m_startTime)), e);
} finally {
t.complete();
if (reportBucket != null) {
m_bucketManager.closeBucket(reportBucket);
}
}
}
private void updateDependencyInfo(DependencyReport report, Transaction t, String target, String type) {
long current = t.getTimestamp() / 1000 / 60;
int min = (int) (current % (60));
Segment segment = report.findOrCreateSegment(min);
Dependency dependency = segment.findOrCreateDependency(type + ":" + target);
dependency.setType(type);
dependency.setTarget(target);
if (!t.getStatus().equals(Transaction.SUCCESS)) {
dependency.incErrorCount();
}
dependency.incTotalCount();
dependency.setSum(dependency.getSum() + t.getDurationInMillis());
dependency.setAvg(dependency.getSum() / dependency.getTotalCount());
}
}
......@@ -67,7 +67,7 @@ public class SqlAnalyzer extends AbstractMessageAnalyzer<SqlReport> implements L
if (connection != null && method != null) {
DatabaseItem item = new DatabaseItem();
String tables = m_sqlParseManager.getTableNames(sqlName, sqlStatement, domain);
String database = getDataBaseName(connection);
String database = DatabaseParseUtil.parseDatabaseName(connection);
if (database == null) {
m_errorConnectionUrls.add(domain + ":" + connection);
......@@ -93,33 +93,6 @@ public class SqlAnalyzer extends AbstractMessageAnalyzer<SqlReport> implements L
m_logger = logger;
}
private String getDataBaseName(String url) {
if (url != null) {
if (url.indexOf("mysql") > -1) {
try {
int index = url.indexOf("://");
String temp = url.substring(index + 3);
index = temp.indexOf("/");
int index2 = temp.indexOf("?");
String schema = temp.substring(index + 1, index2 != -1 ? index2 : temp.length());
return schema;
} catch (Exception e) {
}
} else if (url.indexOf("sqlserver") > -1) {
String temp = url.substring(url.indexOf("databaseName"));
int first = temp.indexOf("=");
int end = temp.indexOf(";");
if (first > -1 && end > -1) {
return temp.substring(first + 1, end);
}
}
}
return null;
}
@Override
public Set<String> getDomains() {
return m_reports.keySet();
......
......@@ -10,11 +10,15 @@ import org.unidal.lookup.configuration.Component;
import com.dainping.cat.consumer.advanced.dal.BusinessReportDao;
import com.dainping.cat.consumer.advanced.dal.SqltableDao;
import com.dainping.cat.consumer.core.dal.HostinfoDao;
import com.dainping.cat.consumer.core.dal.ReportDao;
import com.dianping.cat.configuration.ServerConfigManager;
import com.dianping.cat.consumer.CatConsumerAdvancedModule;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.MessageAnalyzer;
import com.dianping.cat.consumer.advanced.CrossAnalyzer;
import com.dianping.cat.consumer.advanced.DatabaseAnalyzer;
import com.dianping.cat.consumer.advanced.DependencyAnalyzer;
import com.dianping.cat.consumer.advanced.MatrixAnalyzer;
import com.dianping.cat.consumer.advanced.MetricAnalyzer;
import com.dianping.cat.consumer.advanced.SqlAnalyzer;
......@@ -26,8 +30,9 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
public List<Component> defineComponents() {
List<Component> all = new ArrayList<Component>();
all.add(C(SqlParseManager.class)//
.req(SqltableDao.class));
all.add(C(DomainManager.class, DomainManager.class).req(ServerConfigManager.class, HostinfoDao.class));
all.add(C(SqlParseManager.class).req(SqltableDao.class));
all.add(C(MessageAnalyzer.class, CrossAnalyzer.ID, CrossAnalyzer.class).is(PER_LOOKUP) //
.req(BucketManager.class, ReportDao.class));
......@@ -41,6 +46,9 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(MessageAnalyzer.class, MatrixAnalyzer.ID, MatrixAnalyzer.class).is(PER_LOOKUP) //
.req(BucketManager.class, ReportDao.class));
all.add(C(MessageAnalyzer.class, DependencyAnalyzer.ID, DependencyAnalyzer.class).is(PER_LOOKUP) //
.req(BucketManager.class, ReportDao.class, DomainManager.class));
all.add(C(MessageAnalyzer.class, MetricAnalyzer.ID, MetricAnalyzer.class).is(PER_LOOKUP) //
.req(BucketManager.class, BusinessReportDao.class));
......
<?xml version="1.0" encoding="UTF-8"?>
<model>
<entity name="dependency-report" root="true">
<attribute name="domain" value-type="String" />
<attribute name="startTime" value-type="Date" format="yyyy-MM-dd HH:mm:ss" />
<attribute name="endTime" value-type="Date" format="yyyy-MM-dd HH:mm:ss" />
<entity-ref name="segment" type="list" names="segments" />
</entity>
<entity name="segment">
<attribute name="id" value-type="int" />
<attribute name="exception-count" value-type="int" />
<entity-ref name="index" type="list" names="indexs" />
<entity-ref name="dependency" type="list" names="dependencies" />
</entity>
<entity name="index">
<attribute name="name" value-type="String" />
<attribute name="total-count" value-type="int" />
<attribute name="error-count" value-type="int" />
<attribute name="sum" value-type="double" />
<attribute name="avg" value-type="double" />
</entity>
<entity name="dependency">
<attribute name="type" value-type="String" />
<attribute name="target" value-type="String" />
<attribute name="total-count" value-type="int" />
<attribute name="avg" value-type="double" />
<attribute name="error-count" value-type="int" />
</entity>
</model>
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<file path="dependency-report-codegen.xml" />
<file path="dependency-report-model.xml" />
</manifest>
<?xml version="1.0" encoding="UTF-8"?>
<model model-package="com.dianping.cat.consumer.dependency.model"
enable-merger="true" enable-sax-parser="true" enable-base-visitor="true">
<entity name="dependency-report" root="true">
<attribute name="domain" value-type="String" key="true" />
<attribute name="startTime" value-type="Date" format="yyyy-MM-dd HH:mm:ss" />
<attribute name="endTime" value-type="Date" format="yyyy-MM-dd HH:mm:ss" />
<element name="domainName" value-type="String" type="set"
names="domain-names" />
<entity-ref name="segment" type="map" names="segments" method-find-or-create="true" />
</entity>
<entity name="segment">
<attribute name="id" value-type="int" key="true"/>
<attribute name="exception-count" value-type="int" method-inc="true" primitive="true"/>
<entity-ref name="index" type="map" names="indexs" method-find-or-create="true"/>
<entity-ref name="dependency" type="map" names="dependencies" method-find-or-create="true"/>
</entity>
<entity name="index">
<attribute name="name" value-type="String" key="true"/>
<attribute name="total-count" value-type="int" method-inc="true" primitive="true"/>
<attribute name="error-count" value-type="int" method-inc="true" primitive="true"/>
<attribute name="sum" value-type="double" primitive="true" format="0.00"/>
<attribute name="avg" value-type="double" primitive="true" format="0.00"/>
</entity>
<entity name="dependency">
<attribute name="key" value-type="String" key="true"/>
<attribute name="target" value-type="String"/>
<attribute name="type" value-type="String"/>
<attribute name="total-count" value-type="int" method-inc="true" primitive="true"/>
<attribute name="error-count" value-type="int" method-inc="true" primitive="true"/>
<attribute name="avg" value-type="double" primitive="true" format="0.00"/>
<attribute name="sum" value-type="double" primitive="true" format="0.00"/>
</entity>
</model>
\ No newline at end of file
<plexus>
<components>
<component>
<role>com.dianping.cat.consumer.DomainManager</role>
<implementation>com.dianping.cat.consumer.DomainManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
<requirement>
<role>com.dainping.cat.consumer.core.dal.HostinfoDao</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.consumer.sql.SqlParseManager</role>
<implementation>com.dianping.cat.consumer.sql.SqlParseManager</implementation>
......@@ -71,6 +83,23 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.consumer.MessageAnalyzer</role>
<role-hint>dependency</role-hint>
<implementation>com.dianping.cat.consumer.advanced.DependencyAnalyzer</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
<requirements>
<requirement>
<role>com.dianping.cat.storage.BucketManager</role>
</requirement>
<requirement>
<role>com.dainping.cat.consumer.core.dal.ReportDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.consumer.DomainManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.consumer.MessageAnalyzer</role>
<role-hint>metric</role-hint>
......
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<file path="wizard.xml" />
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<wizard package="com.dianping.cat.advanced">
<model package="com.dianping.cat.advanced.dependency-report" name="dependency-report">
<sample-model>/Users/youyong/Documents/workspace/cat/cat-consumer-advanced/src/test/resources/com/dianping/cat/consumer/advanced/dependency-report.xml</sample-model>
</model>
</wizard>
......@@ -6,15 +6,17 @@ import org.junit.Test;
public class DatabaseAnalyzerTest {
@Test
public void testParseDatabaseName(){
DatabaseAnalyzer analyzer = new DatabaseAnalyzer();
String mysql="jdbc:mysql://127.0.0.1:3306/cat";
String net ="jdbc:sqlserver://10.1.1.241:1433;xopenStates=false;sendTimeAsDatetime=true;trustServerCertificate=false;sendStringParametersAsUnicode=true;selectMethod=direct;responseBuffering=adaptive;packetSize=8000;loginTimeout=15;lockTimeout=-1;lastUpdateCount=true;encrypt=false;disableStatementPooling=true;databaseName=zSurvey_NET;applicationName=Microsoft SQL Server JDBC Driver;";
String mysqlResult =analyzer.getDatabaseName(mysql);
String netResult = analyzer.getDatabaseName(net);
Assert.assertEquals("cat", mysqlResult);
Assert.assertEquals("zSurvey_NET", netResult);
public void testParseDatabaseName() {
String mysql = "jdbc:mysql://127.0.0.1:3306/cat";
String net = "jdbc:sqlserver://10.1.1.241:1433;xopenStates=false;sendTimeAsDatetime=true;trustServerCertificate=false;sendStringParametersAsUnicode=true;selectMethod=direct;responseBuffering=adaptive;packetSize=8000;loginTimeout=15;lockTimeout=-1;lastUpdateCount=true;encrypt=false;disableStatementPooling=true;databaseName=zSurvey_NET;applicationName=Microsoft SQL Server JDBC Driver;";
for (int i = 0; i < 100; i++) {
String mysqlResult = DatabaseParseUtil.parseDatabaseName(mysql);
String netResult = DatabaseParseUtil.parseDatabaseName(net);
Assert.assertEquals("cat", mysqlResult);
Assert.assertEquals("zSurvey_NET", netResult);
}
}
}
package com.dianping.cat.consumer.performance;
import org.junit.Test;
import org.unidal.lookup.ComponentTestCase;
import com.dianping.cat.consumer.advanced.DependencyAnalyzer;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.internal.MockMessageBuilder;
import com.dianping.cat.message.spi.MessageTree;
import com.dianping.cat.message.spi.internal.DefaultMessageTree;
public class DependencyPerformanceTest extends ComponentTestCase {
@Test
public void test() throws Exception {
DependencyAnalyzer analyzer = lookup(DependencyAnalyzer.class);
MessageTree tree = buildMessage();
long current = System.currentTimeMillis();
int size = 10000000;
for (int i = 0; i < size; i++) {
analyzer.process(tree);
}
System.out.println(analyzer.getReport("cat"));
System.out.println("Cost " + (System.currentTimeMillis() - current) / 1000);
// cost 26
}
public MessageTree buildMessage() {
Message message = new MockMessageBuilder() {
@Override
public MessageHolder define() {
TransactionHolder t = t("URL", "GET", 112819)
.child(
t("PigeonCall",
"groupService:groupNoteService_1.0.0:updateNoteDraft(Integer,Integer,String,String)", "",
100).child(e("PigeonCall.server", "10.1.2.99:2011", "Execute[34796272]")))
.child(
t("PigeonCall",
"groupService:groupNoteService_1.0.1:updateNoteDraft1(Integer,Integer,String,String)",
"", 100).child(e("PigeonCall.server", "10.1.2.199:2011", "Execute[34796272]")))
.child(
t("PigeonCall",
"groupService:groupNoteService_1.0.1:updateNoteDraft2(Integer,Integer,String,String)",
"", 100).child(e("PigeonCall.server", "10.1.2.199:2011", "Execute[34796272]")))
.child(
t("PigeonCall",
"groupService:groupNoteService_1.0.1:updateNoteDraft3(Integer,Integer,String,String)",
"", 100).child(e("PigeonCall.server", "10.1.2.199:2011", "Execute[34796272]")))
.child(
t("PigeonCall",
"groupService:groupNoteService_1.0.1:updateNoteDraft4(Integer,Integer,String,String)",
"", 100).child(e("PigeonCall.server", "10.1.2.199:2011", "Execute[34796272]")))
.child(
t("PigeonService",
"groupService:groupNoteService_1.0.1:updateNoteDraft5(Integer,Integer,String,String)",
"", 100).child(e("PigeonService.client", "10.1.7.127:37897", "Execute[34796272]")))
.child(
t("PigeonService",
"groupService:groupNoteService_1.0.1:updateNoteDraft7(Integer,Integer,String,String)",
"", 100).child(e("PigeonService.client", "10.1.7.127:37897", "Execute[34796272]")))
.child(
t("PigeonService",
"groupService:groupNoteService_1.0.1:updateNoteD1aft6(Integer,Integer,String,String)",
"", 100).child(e("PigeonService1.client", "10.1.7.128:37897", "Execute[34796272]")));
return t;
}
}.build();
MessageTree tree = new DefaultMessageTree();
tree.setDomain("cat");
tree.setHostName("test");
tree.setIpAddress("test");
tree.setThreadGroupName("test");
tree.setThreadId("test");
tree.setThreadName("test");
tree.setMessage(message);
tree.setMessageId("MobileApi-0a01077f-379304-1362256");
return tree;
}
}
{
"domain": "Review",
"startTime": "2012-01-25 13:00:00",
"endTime": "2012-01-25 13:59:00",
"periods": {
"0": {
"minute": 0,
"ips": {
"127.0.0.1": {
"address": "127.0.0.1",
"count": 19
},
"192.168.63.30": {
"address": "192.168.63.30",
"count": 11
}
}
},
"1": {
"minute": 1
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<ip-report domain="Review" startTime="2012-01-25 13:00:00" endTime="2012-01-25 13:59:00">
<period minute="0">
<ip address="127.0.0.1" count="19"/>
<ip address="192.168.63.30" count="11"/>
</period>
<period minute="1">
</period>
</ip-report>
<dependency-report domain="Cat" startTime="2012-05-16 16:00:00"
endTime="2012-05-16 16:59:59">
<segment id="1" exception-count="0">
<index name="URL" total-count="1234" error-count="123" sum="123.0" avg="123.0"></index>
<index name="Cache" total-count="1234" error-count="123" sum="123.0" avg="123.0"></index>
<dependency type="PigeonService" target="UserService"
total-count="1" avg="1.0" error-count="1" />
<dependency type="PigeonCall" target="UserService" total-count="1"
avg="1.0" error-count="1" />
<dependency type="Database" target="UserService" total-count="1"
avg="1.0" error-count="1" />
<dependency type="MemoryCache" target="UserService" total-count="1"
avg="1.0" error-count="1" />
<dependency type="HttpCall" target="UserService" total-count="1"
avg="1.0" error-count="1" />
</segment>
<segment></segment>
</dependency-report>
......@@ -26,7 +26,7 @@ public class DefaultMessageAnalyzerManager extends ContainerHolder implements Me
public MessageAnalyzer getAnalyzer(String name, long startTime) {
// remove last two hour analyzer
try {
Map<String, MessageAnalyzer> temp = m_map.remove(startTime - m_duration * 2);
Map<String, MessageAnalyzer> temp = m_map.remove(startTime - m_duration * 3);
if (temp != null) {
for (MessageAnalyzer anlyzer : temp.values()) {
......
......@@ -2,6 +2,7 @@ package com.dianping.cat.consumer.core;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
......@@ -57,6 +58,8 @@ public class StateAnalyzer extends AbstractMessageAnalyzer<StateReport> implemen
@Inject
private ProjectDao m_projectDao;
private Set<String> m_domains = new HashSet<String>();
private Map<String, StateReport> m_reports = new HashMap<String, StateReport>();
private void buildStateInfo(Machine machine) {
......@@ -240,6 +243,10 @@ public class StateAnalyzer extends AbstractMessageAnalyzer<StateReport> implemen
Machine machine = report.findOrCreateMachine(NetworkInterfaceManager.INSTANCE.getLocalHostAddress());
ProcessDomain processDomains = machine.findOrCreateProcessDomain(domain);
if (!m_domains.contains(domain)) {
insertDomainInfo(domain);
m_domains.add(domain);
}
processDomains.addIp(ip);
}
......
......@@ -184,10 +184,12 @@ public class TopAnalyzer extends AbstractMessageAnalyzer<TopReport> implements L
@Override
public void apply(Range2 range2, com.dianping.cat.consumer.top.model.entity.Segment detail) {
long count = range2.getCount();
long errorCount = range2.getFails();
double sum = range2.getSum();
detail.setUrl(count + detail.getUrl());
detail.setUrlSum(sum + detail.getUrlSum());
detail.setUrlError(errorCount+detail.getUrlError());
detail.setUrlDuration(detail.getUrlSum() / detail.getUrl());
}
},
......@@ -196,9 +198,12 @@ public class TopAnalyzer extends AbstractMessageAnalyzer<TopReport> implements L
@Override
public void apply(Range2 range2, com.dianping.cat.consumer.top.model.entity.Segment detail) {
long count = range2.getCount();
long errorCount = range2.getFails();
double sum = range2.getSum();
detail.setService(count + detail.getService());
detail.setServiceSum(sum + detail.getServiceSum());
detail.setServiceError(errorCount+detail.getServiceError());
detail.setServiceDuration(detail.getServiceSum() / detail.getService());
}
},
......@@ -207,8 +212,11 @@ public class TopAnalyzer extends AbstractMessageAnalyzer<TopReport> implements L
@Override
public void apply(Range2 range2, com.dianping.cat.consumer.top.model.entity.Segment detail) {
long count = range2.getCount();
long errorCount = range2.getFails();
double sum = range2.getSum();
detail.setService(count + detail.getService());
detail.setServiceError(errorCount+detail.getServiceError());
detail.setServiceSum(sum + detail.getServiceSum());
detail.setServiceDuration(detail.getServiceSum() / detail.getService());
}
......@@ -218,8 +226,11 @@ public class TopAnalyzer extends AbstractMessageAnalyzer<TopReport> implements L
@Override
public void apply(Range2 range2, com.dianping.cat.consumer.top.model.entity.Segment detail) {
long count = range2.getCount();
long errorCount = range2.getFails();
double sum = range2.getSum();
detail.setCall(count + detail.getCall());
detail.setCallError(errorCount+detail.getCallError());
detail.setCallSum(sum + detail.getCallSum());
detail.setCallDuration(detail.getCallSum() / detail.getCall());
......@@ -230,8 +241,11 @@ public class TopAnalyzer extends AbstractMessageAnalyzer<TopReport> implements L
@Override
public void apply(Range2 range2, com.dianping.cat.consumer.top.model.entity.Segment detail) {
long count = range2.getCount();
long errorCount = range2.getFails();
double sum = range2.getSum();
detail.setCall(count + detail.getCall());
detail.setCallError(errorCount+detail.getCallError());
detail.setCallSum(sum + detail.getCallSum());
detail.setCallDuration(detail.getCallSum() / detail.getCall());
}
......@@ -241,8 +255,11 @@ public class TopAnalyzer extends AbstractMessageAnalyzer<TopReport> implements L
@Override
public void apply(Range2 range2, com.dianping.cat.consumer.top.model.entity.Segment detail) {
long count = range2.getCount();
long errorCount = range2.getFails();
double sum = range2.getSum();
detail.setSql(count + detail.getSql());
detail.setSqlError(errorCount+detail.getSqlError());
detail.setSqlSum(sum + detail.getSqlSum());
detail.setSqlDuration(detail.getSqlSum() / detail.getSql());
}
......
......@@ -242,7 +242,7 @@ public class TransactionAnalyzer extends AbstractMessageAnalyzer<TransactionRepo
// update statistics
double duration = t.getDurationInMicros() / 1000d;
// make all duration numbers less
Integer allDuration = new Integer(((int) duration) / 4 * 4);
Integer allDuration = new Integer(((int) duration) / 5 * 5);
name.setMax(Math.max(name.getMax(), duration));
name.setMin(Math.min(name.getMin(), duration));
......
......@@ -14,20 +14,24 @@
<entity name="segment">
<attribute name="id" value-type="int" key="true" />
<attribute name="error" value-type="long" primitive="true" />
<attribute name="call-error" value-type="long" primitive="true" />
<attribute name="url" value-type="long" primitive="true" />
<attribute name="url-error" value-type="long" primitive="true" />
<attribute name="url-duration" value-type="double" primitive="true" format="0.00" />
<attribute name="url-sum" value-type="double" primitive="true" format="0.00" />
<attribute name="service" value-type="long" primitive="true" />
<attribute name="service-error" value-type="long" primitive="true" />
<attribute name="service-duration" value-type="double" primitive="true" format="0.00" />
<attribute name="service-sum" value-type="double" primitive="true" format="0.00" />
<attribute name="sql" value-type="long" primitive="true" />
<attribute name="sql-error" value-type="long" primitive="true" />
<attribute name="sql-duration" value-type="double" primitive="true" format="0.00" />
<attribute name="sql-sum" value-type="double" primitive="true" format="0.00" />
<attribute name="call" value-type="long" primitive="true" />
<attribute name="call-error" value-type="long" primitive="true" />
<attribute name="call-duration" value-type="double" primitive="true" format="0.00" />
<attribute name="call-sum" value-type="double" primitive="true" format="0.00" />
<attribute name="cache" value-type="long" primitive="true" />
<attribute name="cache-error" value-type="long" primitive="true" />
<attribute name="cache-duration" value-type="double" primitive="true" format="0.00" />
<attribute name="cache-sum" value-type="double" primitive="true" format="0.00" />
</entity>
......
......@@ -39,10 +39,6 @@ public class HtmlMessageCodec implements MessageCodec, Initializable {
private DateHelper m_dateHelper = new DateHelper();
protected String buildLink(Message message) {
return message.getData().toString();
}
@Override
public MessageTree decode(ChannelBuffer buf) {
throw new UnsupportedOperationException("HtmlMessageCodec only supports one-way encoding!");
......@@ -185,8 +181,7 @@ public class HtmlMessageCodec implements MessageCodec, Initializable {
} else {
count += helper.tr1(buf, null);
}
String link = buildLink(message);
String link = message.getData().toString();
count += helper.td1(buf);
......@@ -203,6 +198,33 @@ public class HtmlMessageCodec implements MessageCodec, Initializable {
return count;
}
protected int encodeRemoteLink(MessageTree tree, Message message, ChannelBuffer buf, int level, LineCounter counter) {
BufferHelper helper = m_bufferHelper;
int count = 0;
if (counter != null) {
counter.inc();
count += helper.tr1(buf, "link");
} else {
count += helper.tr1(buf, null);
}
String link = message.getData().toString();
String name = message.getName();
count += helper.td1(buf);
count += helper.nbsp(buf, level * 2); // 2 spaces per level
count += helper.write(buf, String.format("<a href=\"%s\" target=\"_blank\">%s</a>",
link, name));
count += helper.td2(buf);
count += helper.tr2(buf);
count += helper.crlf(buf);
return count;
}
protected int encodeMessage(MessageTree tree, Message message, ChannelBuffer buf, int level, LineCounter counter) {
if (message instanceof Transaction) {
Transaction transaction = (Transaction) message;
......@@ -232,6 +254,8 @@ public class HtmlMessageCodec implements MessageCodec, Initializable {
if ("RemoteCall".equals(type)) {
return encodeLogViewLink(tree, message, buf, level, counter);
} else if ("RemoteLink".equals(type)) {
return encodeRemoteLink(tree, message, buf, level, counter);
} else {
return encodeLine(tree, message, buf, 'E', Policy.DEFAULT, level, counter);
}
......
......@@ -11,8 +11,10 @@ import com.dianping.cat.home.dal.alarm.AlarmRuleDao;
import com.dianping.cat.home.dal.alarm.AlarmTemplateDao;
import com.dianping.cat.home.dal.alarm.MailRecordDao;
import com.dianping.cat.home.dal.alarm.ScheduledReportDao;
import com.dianping.cat.report.page.externalError.EventCollectManager;
import com.dianping.cat.report.page.model.spi.ModelService;
import com.dianping.cat.report.service.DailyReportService;
import com.dianping.cat.system.alarm.AlarmContentBuilder;
import com.dianping.cat.system.alarm.AlarmRuleCreator;
import com.dianping.cat.system.alarm.AlarmTask;
import com.dianping.cat.system.alarm.alert.AlertManager;
......@@ -39,6 +41,8 @@ class AlarmComponentConfigurator extends AbstractResourceConfigurator {
public List<Component> defineComponents() {
List<Component> all = new ArrayList<Component>();
all.add(C(AlarmContentBuilder.class));
all.add(C(AlarmRuleCreator.class)//
.req(AlarmRuleDao.class, AlarmTemplateDao.class, ScheduledReportDao.class)//
.req(ModelService.class, "event"));
......@@ -66,13 +70,13 @@ class AlarmComponentConfigurator extends AbstractResourceConfigurator {
req(AlarmTemplateDao.class, AlarmRuleDao.class, ServerConfigManager.class));
all.add(C(ExceptionDataListener.class).//
req(EventDispatcher.class, ThresholdRuleManager.class));
req(EventDispatcher.class, ThresholdRuleManager.class, EventCollectManager.class, AlarmContentBuilder.class));
all.add(C(ServiceDataListener.class).//
req(EventDispatcher.class, ThresholdRuleManager.class));
req(EventDispatcher.class, ThresholdRuleManager.class, EventCollectManager.class, AlarmContentBuilder.class));
all.add(C(ThresholdAlertListener.class).//
req(AlertManager.class, RuleManager.class));
req(AlertManager.class, RuleManager.class, AlarmContentBuilder.class));
all.add(C(AlarmTask.class).//
req(EventDispatcher.class, Connector.class, ThresholdRuleManager.class));
......
......@@ -11,15 +11,16 @@ import org.unidal.lookup.configuration.AbstractResourceConfigurator;
import org.unidal.lookup.configuration.Component;
import com.dainping.cat.consumer.advanced.dal.BusinessReportDao;
import com.dainping.cat.consumer.core.dal.HostinfoDao;
import com.dainping.cat.consumer.core.dal.ProjectDao;
import com.dainping.cat.consumer.core.dal.ReportDao;
import com.dainping.cat.consumer.core.dal.TaskDao;
import com.dianping.cat.CatHomeModule;
import com.dianping.cat.configuration.ServerConfigManager;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.RealtimeConsumer;
import com.dianping.cat.home.dal.report.DailygraphDao;
import com.dianping.cat.home.dal.report.DailyreportDao;
import com.dianping.cat.home.dal.report.EventDao;
import com.dianping.cat.home.dal.report.GraphDao;
import com.dianping.cat.home.dal.report.MonthreportDao;
import com.dianping.cat.home.dal.report.WeeklyreportDao;
......@@ -30,8 +31,8 @@ import com.dianping.cat.report.graph.DefaultGraphBuilder;
import com.dianping.cat.report.graph.DefaultValueTranslater;
import com.dianping.cat.report.graph.GraphBuilder;
import com.dianping.cat.report.graph.ValueTranslater;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.cross.DomainManager;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.externalError.EventCollectManager;
import com.dianping.cat.report.page.health.HistoryGraphs;
import com.dianping.cat.report.page.state.StateGraphs;
import com.dianping.cat.report.service.DailyReportService;
......@@ -160,9 +161,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
DatabaseReportBuilder.class, SqlReportBuilder.class, HealthReportBuilder.class,//
StateReportBuilder.class));
all.add(C(NormalizePayload.class).req(ServerConfigManager.class));
all.add(C(DomainManager.class, DomainManager.class).req(ServerConfigManager.class, HostinfoDao.class));
all.add(C(PayloadNormalizer.class).req(ServerConfigManager.class));
all.add(C(HealthServiceCollector.class).req(DomainManager.class, ReportDao.class));
......@@ -201,6 +200,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
MonthReportService.class)//
.req(WeeklyReportCache.class, MonthReportCache.class));
all.add(C(EventCollectManager.class).req(EventDao.class, ServerConfigManager.class));
// model service
all.addAll(new ServiceComponentConfigurator().defineComponents());
......
......@@ -17,6 +17,9 @@ import com.dianping.cat.report.page.model.cross.LocalCrossService;
import com.dianping.cat.report.page.model.database.CompositeDatabaseService;
import com.dianping.cat.report.page.model.database.HistoricalDatabaseService;
import com.dianping.cat.report.page.model.database.LocalDatabaseService;
import com.dianping.cat.report.page.model.dependency.CompositeDependencyService;
import com.dianping.cat.report.page.model.dependency.HistoricalDependencyService;
import com.dianping.cat.report.page.model.dependency.LocalDependencyService;
import com.dianping.cat.report.page.model.event.CompositeEventService;
import com.dianping.cat.report.page.model.event.HistoricalEventService;
import com.dianping.cat.report.page.model.event.LocalEventService;
......@@ -157,6 +160,16 @@ class ServiceComponentConfigurator extends AbstractResourceConfigurator {
.req(ServerConfigManager.class) //
.req(ModelService.class, new String[] { "top-historical" }, "m_services"));
all.add(C(ModelService.class, "dependency-local", LocalDependencyService.class) //
.req(BucketManager.class) //
.req(MessageConsumer.class, RealtimeConsumer.ID));
all.add(C(ModelService.class, "dependency-historical", HistoricalDependencyService.class) //
.req(BucketManager.class, ReportService.class));
all.add(C(ModelService.class, "dependency", CompositeDependencyService.class) //
.req(ServerConfigManager.class) //
.req(ModelService.class, new String[] { "dependency-historical" }, "m_services"));
all.add(C(ModelService.class, "metric-local", LocalMetricService.class) //
.req(BucketManager.class) //
.req(MessageConsumer.class, "realtime"));
......
......@@ -3,12 +3,12 @@ package com.dianping.cat.build;
import java.util.ArrayList;
import java.util.List;
import org.unidal.lookup.configuration.Component;
import org.unidal.web.configuration.AbstractWebComponentsConfigurator;
import com.dianping.cat.report.ReportModule;
import com.dianping.cat.system.SystemModule;
import org.unidal.lookup.configuration.Component;
import org.unidal.web.configuration.AbstractWebComponentsConfigurator;
class WebComponentConfigurator extends AbstractWebComponentsConfigurator {
@SuppressWarnings("unchecked")
@Override
......
......@@ -12,5 +12,9 @@ public class CatString {
public static final String EXCEPTION = " CAT异常过多告警";
public static final String EXCEPTION_MANY = " 异常过多";
public static final String SERVICE_MANY = " 服务调用失败过多";
public static final String SERVICE = " CAT服务调用告警";
}
......@@ -43,7 +43,11 @@ com.dianping.cat.report.page.top.Handler.class,
com.dianping.cat.report.page.metric.Handler.class,
com.dianping.cat.report.page.jsError.Handler.class
com.dianping.cat.report.page.jsError.Handler.class,
com.dianping.cat.report.page.dependency.Handler.class,
com.dianping.cat.report.page.externalError.Handler.class
})
public class ReportModule extends AbstractModule {
......
......@@ -41,7 +41,11 @@ public enum ReportPage implements Page {
METRIC("metric", "metric", "Metric", "Metric", true),
JSERROR("jsError", "jsError", "JsError", "jsError", true);
JSERROR("jsError", "jsError", "JsError", "jsError", true),
DEPENDENCY("dependency", "dependency", "Dependency", "Dependency", true),
EXTERNALERROR("externalError", "externalError", "externalError", "ExternalError", true);
private String m_name;
......
package com.dianping.cat.report.page;
import org.unidal.lookup.annotation.Inject;
import org.unidal.lookup.util.StringUtils;
import com.dianping.cat.configuration.ServerConfigManager;
import com.dianping.cat.helper.CatString;
public class NormalizePayload {
public class PayloadNormalizer {
@Inject
private ServerConfigManager m_manager;
@SuppressWarnings({ "unchecked", "rawtypes" })
......
......@@ -25,7 +25,7 @@ import com.dianping.cat.consumer.transaction.model.entity.TransactionType;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.event.EventMergeManager;
import com.dianping.cat.report.page.model.event.EventReportMerger;
import com.dianping.cat.report.page.model.spi.ModelRequest;
......@@ -55,12 +55,12 @@ public class Handler implements PageHandler<Context> {
private EventMergeManager m_eventMergerMergeManager;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
@Inject(type = ModelService.class, value = "transaction")
private ModelService<TransactionReport> m_transactionService;
private Set<String> m_cacheType = new HashSet<String>(Arrays.asList("Cache.web", "Cache.memcached", "Cache.kvdb",
private Set<String> m_cacheTypes = new HashSet<String>(Arrays.asList("Cache.web", "Cache.memcached", "Cache.kvdb",
"Cache.memcached-tuangou"));
private CacheReport buildCacheReport(TransactionReport transactionReport, EventReport eventReport, String type,
......@@ -176,8 +176,8 @@ public class Handler implements PageHandler<Context> {
if (StringUtils.isEmpty(type)) {
EventReportMerger merger = new EventReportMerger(new EventReport(domain));
for (String temp : m_cacheType) {
request.setProperty("type", temp);
for (String cacheType : m_cacheTypes) {
request.setProperty("type", cacheType);
ModelResponse<EventReport> response = m_eventService.invoke(request);
EventReport eventReport = response.getModel();
......@@ -211,7 +211,7 @@ public class Handler implements PageHandler<Context> {
if (StringUtils.isEmpty(type)) {
TransactionReportMerger merger = new TransactionReportMerger(new TransactionReport(domain));
for (String temp : m_cacheType) {
for (String temp : m_cacheTypes) {
request.setProperty("type", temp);
ModelResponse<TransactionReport> response = m_transactionService.invoke(request);
TransactionReport transactionReport = response.getModel();
......
package com.dianping.cat.report.page.cross;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.cross.model.entity.Local;
import com.dianping.cat.consumer.cross.model.entity.Name;
......
......@@ -14,11 +14,12 @@ import org.unidal.web.mvc.annotation.InboundActionMeta;
import org.unidal.web.mvc.annotation.OutboundActionMeta;
import org.unidal.web.mvc.annotation.PayloadMeta;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.cross.display.HostInfo;
import com.dianping.cat.report.page.cross.display.MethodInfo;
import com.dianping.cat.report.page.cross.display.ProjectInfo;
......@@ -37,7 +38,7 @@ public class Handler implements PageHandler<Context> {
private ReportService m_reportService;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
@Inject
private DomainManager m_domainManager;
......
......@@ -7,12 +7,12 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.cross.model.entity.Local;
import com.dianping.cat.consumer.cross.model.entity.Remote;
import com.dianping.cat.consumer.cross.model.entity.Type;
import com.dianping.cat.consumer.cross.model.transform.BaseVisitor;
import com.dianping.cat.report.page.cross.DomainManager;
public class HostInfo extends BaseVisitor {
......
......@@ -9,13 +9,13 @@ import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.cross.model.entity.Local;
import com.dianping.cat.consumer.cross.model.entity.Name;
import com.dianping.cat.consumer.cross.model.entity.Remote;
import com.dianping.cat.consumer.cross.model.entity.Type;
import com.dianping.cat.consumer.cross.model.transform.BaseVisitor;
import com.dianping.cat.report.page.cross.DomainManager;
public class MethodInfo extends BaseVisitor {
......
......@@ -9,12 +9,12 @@ import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.cross.model.entity.Local;
import com.dianping.cat.consumer.cross.model.entity.Remote;
import com.dianping.cat.consumer.cross.model.entity.Type;
import com.dianping.cat.consumer.cross.model.transform.BaseVisitor;
import com.dianping.cat.report.page.cross.DomainManager;
public class ProjectInfo extends BaseVisitor {
......@@ -144,7 +144,7 @@ public class ProjectInfo extends BaseVisitor {
addCallProject(remoteIp, remote.getType());
}
}
public void setDomainManager(DomainManager domainManager) {
m_domainManager = domainManager;
}
......
......@@ -17,7 +17,7 @@ import com.dianping.cat.consumer.database.model.entity.DatabaseReport;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelPeriod;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
......@@ -39,7 +39,7 @@ public class Handler implements PageHandler<Context> {
private ModelService<DatabaseReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private DatabaseReport getHourlyReport(Payload payload) {
String domain = payload.getDomain();
......@@ -113,11 +113,11 @@ public class Handler implements PageHandler<Context> {
if (StringUtils.isEmpty(payload.getDatabase())) {
payload.setDatabase("cat");
}
if (!CatString.ALL.equalsIgnoreCase(payload.getDomain())) {
model.setDisplayDomain(payload.getDomain());
model.setDomain(payload.getDomain());
if(StringUtils.isEmpty(payload.getDomain())){
payload.setDomain(CatString.ALL);
}
model.setDatabase(payload.getDatabase());
model.setDomain(payload.getDomain());
model.setPage(ReportPage.DATABASE);
m_normalizePayload.normalize(model, payload);
}
......
package com.dianping.cat.report.page.dependency;
public enum Action implements org.unidal.web.mvc.Action {
VIEW("view");
private String m_name;
private Action(String name) {
m_name = name;
}
public static Action getByName(String name, Action defaultAction) {
for (Action action : Action.values()) {
if (action.getName().equals(name)) {
return action;
}
}
return defaultAction;
}
@Override
public String getName() {
return m_name;
}
}
package com.dianping.cat.report.page.dependency;
import com.dianping.cat.report.ReportContext;
public class Context extends ReportContext<Payload> {
}
package com.dianping.cat.report.page.dependency;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import javax.servlet.ServletException;
import org.codehaus.plexus.util.StringUtils;
import org.unidal.lookup.annotation.Inject;
import org.unidal.web.mvc.PageHandler;
import org.unidal.web.mvc.annotation.InboundActionMeta;
import org.unidal.web.mvc.annotation.OutboundActionMeta;
import org.unidal.web.mvc.annotation.PayloadMeta;
import com.dianping.cat.consumer.dependency.model.entity.Dependency;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.entity.Segment;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.dal.report.Event;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.externalError.EventCollectManager;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
import com.dianping.cat.report.page.model.spi.ModelService;
public class Handler implements PageHandler<Context> {
@Inject
private JspViewer m_jspViewer;
@Inject
private EventCollectManager m_manager;
@Inject(type = ModelService.class, value = "dependency")
private ModelService<DependencyReport> m_service;
@Inject
private PayloadNormalizer m_normalizePayload;
private DependencyReport getReport(Payload payload) {
String domain = payload.getDomain();
String date = String.valueOf(payload.getDate());
ModelRequest request = new ModelRequest(domain, payload.getPeriod()) //
.setProperty("date", date);
if (m_service.isEligable(request)) {
ModelResponse<DependencyReport> response = m_service.invoke(request);
DependencyReport report = response.getModel();
return report;
} else {
throw new RuntimeException("Internal error: no eligable dependency service registered for " + request + "!");
}
}
@Override
@PayloadMeta(Payload.class)
@InboundActionMeta(name = "dependency")
public void handleInbound(Context ctx) throws ServletException, IOException {
}
@Override
@OutboundActionMeta(name = "dependency")
public void handleOutbound(Context ctx) throws ServletException, IOException {
Model model = new Model(ctx);
Payload payload = ctx.getPayload();
normalize(model, payload);
DependencyReport report = getReport(payload);
String min = payload.getMinute();
int minute = 0;
Set<Integer> keys = report.getSegments().keySet();
List<Integer> minutes = new ArrayList<Integer>(keys);
Collections.sort(minutes);
if (StringUtils.isEmpty(min)) {
if (minutes.size() > 0) {
min = String.valueOf(minutes.get(minutes.size() - 1));
minute = Integer.parseInt(min);
}
} else {
minute = Integer.parseInt(min);
}
Date time = new Date(payload.getDate() + TimeUtil.ONE_MINUTE * minute);
Segment segment = report.findSegment(minute);
model.setMinute(minute);
model.setMinutes(minutes);
model.setReport(report);
model.setSegment(segment);
model.setEvents(queryDependencyEvent(segment, payload.getDomain(), time));
m_jspViewer.view(ctx, model);
}
private Map<String, List<Event>> queryDependencyEvent(Segment segment, String domain, Date date) {
Map<String, List<Event>> result = new LinkedHashMap<String, List<Event>>();
Map<String, List<String>> dependencies = parseDependencies(segment);
List<Event> domainEvents = m_manager.queryEvents(domain, date);
if (domainEvents != null && domainEvents.size() > 0) {
result.put(domain, domainEvents);
}
for (Entry<String, List<String>> entry : dependencies.entrySet()) {
String key = entry.getKey();
List<String> targets = entry.getValue();
for (String temp : targets) {
List<Event> queryEvents = m_manager.queryEvents(temp, date);
if (queryEvents != null && queryEvents.size() > 0) {
List<Event> events = result.get(key);
if (events == null) {
events = new ArrayList<Event>();
result.put(key, events);
}
events.addAll(queryEvents);
}
}
}
return result;
}
private Map<String, List<String>> parseDependencies(Segment segment) {
Map<String, List<String>> results = new TreeMap<String, List<String>>();
if (segment != null) {
Map<String, Dependency> dependencies = segment.getDependencies();
for (Dependency temp : dependencies.values()) {
String type = temp.getType();
String target = temp.getTarget();
List<String> targets = results.get(type);
if (targets == null) {
targets = new ArrayList<String>();
results.put(type, targets);
}
targets.add(target);
}
}
return results;
}
private void normalize(Model model, Payload payload) {
model.setPage(ReportPage.DEPENDENCY);
model.setAction(Action.VIEW);
m_normalizePayload.normalize(model, payload);
}
}
package com.dianping.cat.report.page.dependency;
public enum JspFile {
VIEW("/jsp/report/dependency.jsp"),
;
private String m_path;
private JspFile(String path) {
m_path = path;
}
public String getPath() {
return m_path;
}
}
package com.dianping.cat.report.page.dependency;
import com.dianping.cat.report.ReportPage;
import org.unidal.web.mvc.view.BaseJspViewer;
public class JspViewer extends BaseJspViewer<ReportPage, Action, Context, Model> {
@Override
protected String getJspFilePath(Context ctx, Model model) {
Action action = model.getAction();
switch (action) {
case VIEW:
return JspFile.VIEW.getPath();
}
throw new RuntimeException("Unknown action: " + action);
}
}
package com.dianping.cat.report.page.dependency;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.entity.Segment;
import com.dianping.cat.home.dal.report.Event;
import com.dianping.cat.report.page.AbstractReportModel;
import com.dianping.cat.report.view.StringSortHelper;
public class Model extends AbstractReportModel<Action, Context> {
private DependencyReport m_report;
private Segment m_segment;
private int m_minute;
private List<Integer> m_minutes;
private Map<String, List<Event>> m_events;
public Map<String, List<Event>> getEvents() {
return m_events;
}
public void setEvents(Map<String, List<Event>> events) {
m_events = events;
}
public List<Integer> getMinutes() {
return m_minutes;
}
public void setMinutes(List<Integer> minutes) {
m_minutes = minutes;
}
public Model(Context ctx) {
super(ctx);
}
@Override
public Action getDefaultAction() {
return Action.VIEW;
}
@Override
public String getDomain() {
return getDisplayDomain();
}
@Override
public Collection<String> getDomains() {
if (m_report == null) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add(getDomain());
return arrayList;
} else {
Set<String> domainNames = m_report.getDomainNames();
return StringSortHelper.sortDomain(domainNames);
}
}
public DependencyReport getReport() {
return m_report;
}
public Segment getSegment() {
return m_segment;
}
public void setReport(DependencyReport report) {
m_report = report;
}
public void setSegment(Segment segment) {
m_segment = segment;
}
public int getMinute() {
return m_minute;
}
public void setMinute(int minute) {
m_minute = minute;
}
}
package com.dianping.cat.report.page.dependency;
import org.unidal.web.mvc.ActionContext;
import org.unidal.web.mvc.payload.annotation.FieldMeta;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.AbstractReportPayload;
public class Payload extends AbstractReportPayload<Action> {
@FieldMeta("minute")
private String minute;
private ReportPage m_page;
@FieldMeta("op")
private Action m_action;
public Payload() {
super(ReportPage.DEPENDENCY);
}
@Override
public Action getAction() {
return m_action;
}
public String getMinute() {
return minute;
}
@Override
public ReportPage getPage() {
return m_page;
}
public void setAction(String action) {
m_action = Action.getByName(action, Action.VIEW);
}
public void setMinute(String minute) {
this.minute = minute;
}
@Override
public void setPage(String page) {
m_page = ReportPage.getByName(page, ReportPage.DEPENDENCY);
}
@Override
public void validate(ActionContext<?> ctx) {
if (m_action == null) {
m_action = Action.VIEW;
}
}
}
......@@ -26,7 +26,7 @@ import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.graph.GraphBuilder;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.PieChart;
import com.dianping.cat.report.page.PieChart.Item;
import com.dianping.cat.report.page.model.spi.ModelRequest;
......@@ -56,7 +56,7 @@ public class Handler implements PageHandler<Context> {
private ModelService<EventReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private EventStatisticsComputer m_computer = new EventStatisticsComputer();
......
package com.dianping.cat.report.page.externalError;
public enum Action implements org.unidal.web.mvc.Action {
VIEW("view");
public static Action getByName(String name, Action defaultAction) {
for (Action action : Action.values()) {
if (action.getName().equals(name)) {
return action;
}
}
return defaultAction;
}
private String m_name;
private Action(String name) {
m_name = name;
}
@Override
public String getName() {
return m_name;
}
}
package com.dianping.cat.report.page.externalError;
import com.dianping.cat.report.ReportContext;
public class Context extends ReportContext<Payload> {
}
package com.dianping.cat.report.page.externalError;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.unidal.dal.jdbc.DalException;
import org.unidal.helper.Threads;
import org.unidal.helper.Threads.Task;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.configuration.ServerConfigManager;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.dal.report.Event;
import com.dianping.cat.home.dal.report.EventDao;
import com.dianping.cat.home.dal.report.EventEntity;
public class EventCollectManager implements Initializable, LogEnabled {
public static int ZABBIX_ERROR = 1;
public static int DB_ERROR = 2;
public static int CAT_ERROR = 3;
@Inject
private EventDao m_eventDao;
@Inject
private ServerConfigManager m_manager;
private BlockingQueue<Event> m_errors = new LinkedBlockingQueue<Event>(1000);
private Logger m_logger;
public List<Event> queryEvents(String domain, Date date) {
Date start = new Date(date.getTime() - TimeUtil.ONE_MINUTE * 3);
Date end = new Date(date.getTime() + TimeUtil.ONE_MINUTE);
try {
return m_eventDao.findByDomainTime(domain, start, end, EventEntity.READSET_FULL);
} catch (DalException e) {
Cat.logError(e);
}
return new ArrayList<Event>();
}
public boolean addEvent(Event error) {
try {
return m_errors.offer(error, 10, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Cat.logError(e);
}
return false;
}
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
}
@Override
public void initialize() throws InitializationException {
if (!m_manager.isLocalMode()) {
Threads.forGroup("Cat").start(new Job());
}
}
public class Job implements Task {
@Override
public String getName() {
return "Event-Write-Thread";
}
@Override
public void run() {
boolean active = true;
while (active) {
try {
Event error = m_errors.poll(5, TimeUnit.MILLISECONDS);
if (error != null) {
m_eventDao.insert(error);
}
} catch (InterruptedException e) {
active = false;
} catch (DalException e) {
m_logger.error(e.getMessage(), e);
Cat.logError(e);
}
}
}
@Override
public void shutdown() {
}
}
}
package com.dianping.cat.report.page.externalError;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import org.codehaus.plexus.util.StringUtils;
import org.unidal.lookup.annotation.Inject;
import org.unidal.web.mvc.PageHandler;
import org.unidal.web.mvc.annotation.InboundActionMeta;
import org.unidal.web.mvc.annotation.OutboundActionMeta;
import org.unidal.web.mvc.annotation.PayloadMeta;
import com.dianping.cat.Cat;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.home.dal.report.Event;
import com.dianping.cat.report.ReportPage;
public class Handler implements PageHandler<Context> {
@Inject
private JspViewer m_jspViewer;
@Inject
private EventCollectManager m_errorCollectManager;
@Inject
private DomainManager m_domainManager;
private SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMddHHmmss");
@Override
@PayloadMeta(Payload.class)
@InboundActionMeta(name = "externalError")
public void handleInbound(Context ctx) throws ServletException, IOException {
// display only, no action here
}
@Override
@OutboundActionMeta(name = "externalError")
public void handleOutbound(Context ctx) throws ServletException, IOException {
Model model = new Model(ctx);
Payload payload = ctx.getPayload();
int type = payload.getType();
String ip = payload.getIp();
String subject = payload.getTitle();
String content = payload.getContent();
String time = payload.getTime();
Event event = new Event();
if (StringUtils.isEmpty(subject)) {
subject = content;
}
if (type == EventCollectManager.DB_ERROR) {
event.setDomain(payload.getDatabase());
} else {
String domain = m_domainManager.getDomainByIp(ip);
event.setDomain(domain);
}
event.setIp(ip);
event.setType(type);
event.setContent(content);
event.setSubject(subject);
event.setLink(payload.getLink());
try {
event.setDate(m_sdf.parse(time));
} catch (ParseException e) {
event.setDate(new Date());
try {
event.setDate(new Date(Integer.parseInt(time)));
} catch (Exception e1) {
event.setDate(new Date());
Cat.logError(e1);
}
}
m_errorCollectManager.addEvent(event);
model.setAction(Action.VIEW);
model.setPage(ReportPage.EXTERNALERROR);
m_jspViewer.view(ctx, model);
}
}
package com.dianping.cat.report.page.externalError;
public enum JspFile {
VIEW("/jsp/report/externalError.jsp"),
;
private String m_path;
private JspFile(String path) {
m_path = path;
}
public String getPath() {
return m_path;
}
}
package com.dianping.cat.report.page.externalError;
import com.dianping.cat.report.ReportPage;
import org.unidal.web.mvc.view.BaseJspViewer;
public class JspViewer extends BaseJspViewer<ReportPage, Action, Context, Model> {
@Override
protected String getJspFilePath(Context ctx, Model model) {
Action action = model.getAction();
switch (action) {
case VIEW:
return JspFile.VIEW.getPath();
}
throw new RuntimeException("Unknown action: " + action);
}
}
package com.dianping.cat.report.page.externalError;
import com.dianping.cat.report.ReportPage;
import org.unidal.web.mvc.ViewModel;
public class Model extends ViewModel<ReportPage, Action, Context> {
public Model(Context ctx) {
super(ctx);
}
@Override
public Action getDefaultAction() {
return Action.VIEW;
}
}
package com.dianping.cat.report.page.externalError;
import org.unidal.web.mvc.ActionContext;
import org.unidal.web.mvc.ActionPayload;
import org.unidal.web.mvc.payload.annotation.FieldMeta;
import com.dianping.cat.report.ReportPage;
public class Payload implements ActionPayload<ReportPage, Action> {
private ReportPage m_page;
@FieldMeta("op")
private Action m_action;
@FieldMeta("type")
private int m_type;
@FieldMeta("ip")
private String m_ip;
@FieldMeta("recevice")
private String m_recevice;
@FieldMeta("database")
private String m_database;
@FieldMeta("name")
private String m_name;
@FieldMeta("title")
private String m_title;
@FieldMeta("content")
private String m_content;
@FieldMeta("time")
private String m_time;
@FieldMeta("link")
private String m_link;
public String getLink() {
return m_link;
}
public void setLink(String link) {
m_link = link;
}
@Override
public Action getAction() {
return m_action;
}
public String getContent() {
return m_content;
}
public String getDatabase() {
return m_database;
}
public String getIp() {
return m_ip;
}
public String getName() {
return m_name;
}
@Override
public ReportPage getPage() {
return m_page;
}
public String getRecevice() {
return m_recevice;
}
public String getTime() {
return m_time;
}
public String getTitle() {
return m_title;
}
public int getType() {
return m_type;
}
public void setAction(String action) {
m_action = Action.getByName(action, Action.VIEW);
}
public void setContent(String content) {
m_content = content;
}
public void setDatabase(String database) {
m_database = database;
}
public void setIp(String ip) {
m_ip = ip;
}
public void setName(String name) {
m_name = name;
}
@Override
public void setPage(String page) {
m_page = ReportPage.getByName(page, ReportPage.EXTERNALERROR);
}
public void setRecevice(String recevice) {
m_recevice = recevice;
}
public void setTime(String time) {
m_time = time;
}
public void setTitle(String title) {
m_title = title;
}
public void setType(int type) {
m_type = type;
}
@Override
public void validate(ActionContext<?> ctx) {
if (m_action == null) {
m_action = Action.VIEW;
}
}
}
......@@ -17,7 +17,7 @@ import com.dianping.cat.consumer.health.model.entity.HealthReport;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.HistoryGraphItem;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.service.ReportService;
import com.google.gson.Gson;
......@@ -27,7 +27,7 @@ public class Handler implements PageHandler<Context> {
private JspViewer m_jspViewer;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
@Inject
private ReportService m_reportService;
......
......@@ -19,7 +19,7 @@ import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.graph.GraphBuilder;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelPeriod;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
......@@ -45,7 +45,7 @@ public class Handler implements PageHandler<Context> {
private ModelService<HeartbeatReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private void buildHeartbeatGraphInfo(Model model, DisplayHeartbeat displayHeartbeat) {
if (displayHeartbeat == null) {
......
......@@ -15,7 +15,7 @@ import org.unidal.web.mvc.annotation.PayloadMeta;
import com.dianping.cat.consumer.matrix.model.entity.MatrixReport;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
import com.dianping.cat.report.page.model.spi.ModelService;
......@@ -30,7 +30,7 @@ public class Handler implements PageHandler<Context> {
private JspViewer m_jspViewer;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
@Inject(type = ModelService.class, value = "matrix")
private ModelService<MatrixReport> m_service;
......
......@@ -13,7 +13,7 @@ import org.unidal.web.mvc.annotation.PayloadMeta;
import com.dianping.cat.consumer.metric.model.entity.MetricReport;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.metric.MetricConfig.MetricFlag;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
......@@ -27,7 +27,7 @@ public class Handler implements PageHandler<Context> {
private ModelService<MetricReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private static final String TUAN = "TuanGou";
......
......@@ -13,8 +13,6 @@ public class Model extends AbstractReportModel<Action, Context> {
private MetricDisplay m_display;
private String m_domain;
private String m_group;
private String m_channel;
......@@ -44,7 +42,7 @@ public class Model extends AbstractReportModel<Action, Context> {
@Override
public String getDomain() {
return m_domain;
return getDisplayDomain();
}
@Override
......@@ -72,10 +70,6 @@ public class Model extends AbstractReportModel<Action, Context> {
m_display = display;
}
public void setDomain(String domain) {
m_domain = domain;
}
public void setGroup(String group) {
m_group = group;
}
......
......@@ -34,6 +34,7 @@ import com.dianping.cat.message.internal.MessageId;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.model.cross.LocalCrossService;
import com.dianping.cat.report.page.model.database.LocalDatabaseService;
import com.dianping.cat.report.page.model.dependency.LocalDependencyService;
import com.dianping.cat.report.page.model.event.LocalEventService;
import com.dianping.cat.report.page.model.heartbeat.LocalHeartbeatService;
import com.dianping.cat.report.page.model.logview.LocalMessageService;
......@@ -88,6 +89,9 @@ public class Handler extends ContainerHolder implements PageHandler<Context> {
@Inject(type = ModelService.class, value = "metric-local")
private LocalMetricService m_metricService;
@Inject(type = ModelService.class, value = "dependency-local")
private LocalDependencyService m_dependencyService;
private String doFilter(Payload payload, Object dataModel) {
String report = payload.getReport();
......@@ -196,6 +200,8 @@ public class Handler extends ContainerHolder implements PageHandler<Context> {
response = m_topService.invoke(request);
} else if ("metric".equals(report)) {
response = m_metricService.invoke(request);
} else if ("dependency".equals(report)) {
response = m_dependencyService.invoke(request);
} else {
throw new RuntimeException("Unsupported report: " + report + "!");
}
......
......@@ -31,7 +31,6 @@ public class DatabaseReportMerger extends DefaultMerger {
old.setFailPercent(old.getFailCount() / (double) old.getTotalCount());
old.setSum(old.getSum() + method.getSum());
old.setAvg(old.getSum() / (double) old.getTotalCount());
old.getSqlNames().addAll(method.getSqlNames());
}
......@@ -77,7 +76,6 @@ public class DatabaseReportMerger extends DefaultMerger {
if (m_allDomain) {
old.getDomainNames().remove(CatString.ALL);
}
}
@Override
......
......@@ -27,7 +27,6 @@ public class HistoricalDatabaseService extends BaseHistoricalModelService<Databa
@Override
protected DatabaseReport buildModel(ModelRequest request) throws Exception {
String database = request.getProperty("database");
long date = Long.parseLong(request.getProperty("date"));
DatabaseReport report;
......@@ -36,7 +35,6 @@ public class HistoricalDatabaseService extends BaseHistoricalModelService<Databa
} else {
report = getReportFromDatabase(date, database);
}
return report;
}
......
package com.dianping.cat.report.page.model.dependency;
import java.util.List;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
import com.dianping.cat.report.page.model.spi.internal.BaseCompositeModelService;
import com.dianping.cat.report.page.model.spi.internal.BaseRemoteModelService;
public class CompositeDependencyService extends BaseCompositeModelService<DependencyReport> {
public CompositeDependencyService() {
super("dependency");
}
@Override
protected BaseRemoteModelService<DependencyReport> createRemoteService() {
return new RemoteDependencyService();
}
@Override
protected DependencyReport merge(ModelRequest request, List<ModelResponse<DependencyReport>> responses) {
if (responses.size() == 0) {
return null;
}
DependencyReportMerger merger = new DependencyReportMerger(new DependencyReport(request.getDomain()));
for (ModelResponse<DependencyReport> response : responses) {
DependencyReport model = response.getModel();
if (model != null) {
model.accept(merger);
}
}
return merger.getDependencyReport();
}
}
package com.dianping.cat.report.page.model.dependency;
import com.dianping.cat.consumer.dependency.model.entity.Dependency;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.entity.Index;
import com.dianping.cat.consumer.dependency.model.entity.Segment;
import com.dianping.cat.consumer.dependency.model.transform.DefaultMerger;
public class DependencyReportMerger extends DefaultMerger {
public DependencyReportMerger(DependencyReport dependencyReport) {
super(dependencyReport);
}
@Override
protected void mergeDependency(Dependency old, Dependency dependency) {
old.setType(dependency.getType());
old.setTarget(dependency.getTarget());
old.setTotalCount(old.getTotalCount() + dependency.getTotalCount());
old.setErrorCount(old.getErrorCount() + dependency.getErrorCount());
old.setSum(old.getSum() + dependency.getSum());
if (old.getTotalCount() > 0) {
old.setAvg(old.getSum() / old.getTotalCount());
}
}
@Override
protected void mergeIndex(Index old, Index index) {
old.setTotalCount(old.getTotalCount() + index.getTotalCount());
old.setErrorCount(old.getErrorCount() + index.getErrorCount());
old.setSum(old.getSum() + index.getSum());
if (old.getTotalCount() > 0) {
old.setAvg(old.getSum() / old.getTotalCount());
}
}
@Override
protected void mergeSegment(Segment old, Segment segment) {
old.setExceptionCount(old.getExceptionCount() + segment.getExceptionCount());
}
@Override
public void visitDependencyReport(DependencyReport dependencyReport) {
super.visitDependencyReport(dependencyReport);
DependencyReport report = getDependencyReport();
report.getDomainNames().addAll(dependencyReport.getDomainNames());
report.setStartTime(dependencyReport.getStartTime());
report.setEndTime(dependencyReport.getEndTime());
}
}
package com.dianping.cat.report.page.model.dependency;
import java.util.Date;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.transform.DefaultSaxParser;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.internal.BaseHistoricalModelService;
import com.dianping.cat.report.service.ReportService;
import com.dianping.cat.storage.Bucket;
import com.dianping.cat.storage.BucketManager;
public class HistoricalDependencyService extends BaseHistoricalModelService<DependencyReport> {
@Inject
private BucketManager m_bucketManager;
@Inject
private ReportService m_reportSerivce;
public HistoricalDependencyService() {
super("dependency");
}
@Override
protected DependencyReport buildModel(ModelRequest request) throws Exception {
String domain = request.getDomain();
long date = Long.parseLong(request.getProperty("date"));
DependencyReport report;
if (isLocalMode()) {
report = getReportFromLocalDisk(date, domain);
} else {
report = getReportFromDatabase(date, domain);
}
return report;
}
private DependencyReport getReportFromDatabase(long timestamp, String domain) throws Exception {
return m_reportSerivce.queryDependencyReport(domain, new Date(timestamp), new Date(timestamp + TimeUtil.ONE_HOUR));
}
private DependencyReport getReportFromLocalDisk(long timestamp, String domain) throws Exception {
Bucket<String> bucket = m_bucketManager.getReportBucket(timestamp, "dependency");
String xml = bucket.findById(domain);
return xml == null ? null : DefaultSaxParser.parse(xml);
}
}
package com.dianping.cat.report.page.model.dependency;
import java.util.Date;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.transform.DefaultSaxParser;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.page.model.spi.ModelPeriod;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.internal.BaseLocalModelService;
import com.dianping.cat.storage.Bucket;
import com.dianping.cat.storage.BucketManager;
public class LocalDependencyService extends BaseLocalModelService<DependencyReport> {
@Inject
private BucketManager m_bucketManager;
public LocalDependencyService() {
super("dependency");
}
private DependencyReport getLocalReport(long timestamp, String domain) throws Exception {
Bucket<String> bucket = m_bucketManager.getReportBucket(timestamp, "dependency");
String xml = bucket.findById(domain);
return xml == null ? null : DefaultSaxParser.parse(xml);
}
@Override
protected DependencyReport getReport(ModelRequest request, ModelPeriod period, String domain) throws Exception {
DependencyReport report = super.getReport(request, period, domain);
if (report == null && period.isLast()) {
long current = System.currentTimeMillis();
long hour = 60 * 60 * 1000;
long date = current - current % (hour) - hour;
report = getLocalReport(date, domain);
if (report == null) {
Date start = new Date(date);
Date end = new Date(date + TimeUtil.ONE_HOUR);
report = new DependencyReport(domain);
report.setStartTime(start);
report.setEndTime(end);
}
}
return report;
}
}
package com.dianping.cat.report.page.model.dependency;
import java.io.IOException;
import org.xml.sax.SAXException;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.dependency.model.transform.DefaultSaxParser;
import com.dianping.cat.report.page.model.spi.internal.BaseRemoteModelService;
public class RemoteDependencyService extends BaseRemoteModelService<DependencyReport> {
public RemoteDependencyService() {
super("dependency");
}
@Override
protected DependencyReport buildModel(String xml) throws SAXException, IOException {
return DefaultSaxParser.parse(xml);
}
}
......@@ -19,30 +19,40 @@ public class TopReportMerger extends DefaultMerger {
@Override
protected void mergeSegment(Segment old, Segment segment) {
old.setError(old.getError() + segment.getError());
old.setCallError(old.getCallError() + segment.getCallError());
old.setCache(old.getCache() + segment.getCache());
old.setCacheSum(old.getCacheSum() + segment.getCacheSum());
old.setCacheError(old.getCacheError() + segment.getCacheError());
if (old.getCache() > 0) {
old.setCacheDuration(old.getCacheSum() / old.getCache());
}
old.setUrl(old.getUrl() + segment.getUrl());
old.setUrlSum(old.getUrlSum() + segment.getUrlSum());
old.setUrlError(old.getUrlError() + segment.getUrlError());
if (old.getUrl() > 0) {
old.setUrlDuration(old.getUrlSum() / old.getUrl());
}
old.setSql(old.getSql() + segment.getSql());
old.setSqlError(old.getSqlError() + segment.getSqlError());
old.setSqlSum(old.getSqlSum() + segment.getSqlSum());
if (old.getSql() > 0) {
old.setSqlDuration(old.getSqlSum() / old.getSql());
}
old.setCall(old.getCall() + segment.getCall());
old.setCallError(old.getCallError() + segment.getCallError());
old.setCallSum(old.getCallSum() + segment.getCallSum());
if (old.getCall() > 0) {
old.setCallDuration(old.getCallSum() / old.getCall());
}
old.setService(old.getService() + segment.getService());
old.setServiceError(old.getServiceError() + segment.getServiceError());
old.setServiceSum(old.getServiceSum() + segment.getServiceSum());
if (old.getService() > 0) {
old.setServiceDuration(old.getServiceSum() / old.getService());
}
......
......@@ -25,7 +25,7 @@ import com.dianping.cat.consumer.problem.model.entity.ProblemReport;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelPeriod;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
......@@ -55,7 +55,7 @@ public class Handler implements PageHandler<Context> {
private ModelService<ProblemReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private Gson m_gson = new Gson();
......
......@@ -17,7 +17,7 @@ import com.dianping.cat.consumer.sql.model.entity.SqlReport;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelPeriod;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
......@@ -36,7 +36,7 @@ public class Handler implements PageHandler<Context> {
private JspViewer m_jspViewer;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
@Inject(type = ModelService.class, value = "sql")
private ModelService<SqlReport> m_service;
......
......@@ -16,7 +16,7 @@ import com.dianping.cat.consumer.state.model.entity.StateReport;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.HistoryGraphItem;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
import com.dianping.cat.report.page.model.spi.ModelService;
......@@ -37,7 +37,7 @@ public class Handler implements PageHandler<Context> {
private ModelService<StateReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private static final String CAT = "Cat";
......
......@@ -26,7 +26,7 @@ public class Model extends AbstractReportModel<Action, Context> {
@Override
public String getDomain() {
return "Cat";
return getDisplayDomain();
}
@Override
......
......@@ -12,9 +12,10 @@ import org.unidal.web.mvc.annotation.OutboundActionMeta;
import org.unidal.web.mvc.annotation.PayloadMeta;
import com.dianping.cat.consumer.top.model.entity.TopReport;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.model.spi.ModelPeriod;
import com.dianping.cat.report.page.model.spi.ModelRequest;
import com.dianping.cat.report.page.model.spi.ModelResponse;
......@@ -32,10 +33,10 @@ public class Handler implements PageHandler<Context> {
private ModelService<TopReport> m_service;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
private TopReport getReport(Payload payload) {
String domain = payload.getDomain();
String domain = CatString.CAT;
String date = String.valueOf(payload.getDate());
ModelRequest request = new ModelRequest(domain, payload.getPeriod()) //
.setProperty("date", date);
......@@ -65,12 +66,13 @@ public class Handler implements PageHandler<Context> {
public void handleOutbound(Context ctx) throws ServletException, IOException {
Model model = new Model(ctx);
Payload payload = ctx.getPayload();
normalize(model, payload);
TopReport report = getReport(payload);
ModelPeriod period = payload.getPeriod();
int count = payload.getCount();
Metric metrix = new Metric();
int count = payload.getCount();
if (!period.isCurrent()) {
metrix = new Metric(60);
......
......@@ -25,7 +25,7 @@ import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.graph.GraphBuilder;
import com.dianping.cat.report.page.NormalizePayload;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.PieChart;
import com.dianping.cat.report.page.PieChart.Item;
import com.dianping.cat.report.page.model.spi.ModelRequest;
......@@ -60,7 +60,7 @@ public class Handler implements PageHandler<Context> {
private TransactionMergeManager m_mergeManager;
@Inject
private NormalizePayload m_normalizePayload;
private PayloadNormalizer m_normalizePayload;
@Inject(type = ModelService.class, value = "transaction")
private ModelService<TransactionReport> m_service;
......
......@@ -5,6 +5,7 @@ import java.util.Set;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.database.model.entity.DatabaseReport;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.event.model.entity.EventReport;
import com.dianping.cat.consumer.health.model.entity.HealthReport;
import com.dianping.cat.consumer.heartbeat.model.entity.HeartbeatReport;
......@@ -44,4 +45,6 @@ public interface HourlyReportService {
public TopReport queryTopReport(String domain,Date start,Date end);
public TransactionReport queryTransactionReport(String domain, Date start, Date end);
public DependencyReport queryDependencyReport(String domain, Date start, Date end);
}
......@@ -5,6 +5,7 @@ import java.util.Set;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.database.model.entity.DatabaseReport;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.event.model.entity.EventReport;
import com.dianping.cat.consumer.health.model.entity.HealthReport;
import com.dianping.cat.consumer.heartbeat.model.entity.HeartbeatReport;
......@@ -43,6 +44,8 @@ public interface ReportService {
public StateReport queryStateReport(String domain,Date start,Date end);
public TopReport queryTopReport(String domain,Date start,Date end);
public DependencyReport queryDependencyReport(String domain,Date start,Date end);
public TransactionReport queryTransactionReport(String domain, Date start, Date end);
}
......@@ -17,6 +17,7 @@ import com.dainping.cat.consumer.core.dal.ReportEntity;
import com.dianping.cat.Cat;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.database.model.entity.DatabaseReport;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.event.model.entity.EventReport;
import com.dianping.cat.consumer.health.model.entity.HealthReport;
import com.dianping.cat.consumer.heartbeat.model.entity.HeartbeatReport;
......@@ -32,6 +33,7 @@ import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.message.Event;
import com.dianping.cat.report.page.model.cross.CrossReportMerger;
import com.dianping.cat.report.page.model.database.DatabaseReportMerger;
import com.dianping.cat.report.page.model.dependency.DependencyReportMerger;
import com.dianping.cat.report.page.model.event.EventReportMerger;
import com.dianping.cat.report.page.model.heartbeat.HeartbeatReportMerger;
import com.dianping.cat.report.page.model.matrix.MatrixReportMerger;
......@@ -152,7 +154,9 @@ public class HourlyReportServiceImpl implements HourlyReportService {
databaseReport.setStartTime(start);
databaseReport.setEndTime(end);
Set<String> domains = queryAllDomainNames(start, end, "database");
Set<String> domains = queryAllDatabaseNames(start, end, "database");
System.out.println(domains);
databaseReport.getDomainNames().addAll(domains);
return databaseReport;
}
......@@ -442,6 +446,35 @@ public class HourlyReportServiceImpl implements HourlyReportService {
return topReport;
}
@Override
public DependencyReport queryDependencyReport(String domain, Date start, Date end) {
DependencyReportMerger merger = new DependencyReportMerger(new DependencyReport(domain));
try {
List<Report> reports = m_reportDao.findAllByDomainNameDuration(start, end, domain, "dependency",
ReportEntity.READSET_FULL);
for (Report report : reports) {
String xml = report.getContent();
try {
DependencyReport reportModel = com.dianping.cat.consumer.dependency.model.transform.DefaultSaxParser.parse(xml);
reportModel.accept(merger);
} catch (Exception e) {
Cat.logError(e);
Cat.getProducer().logEvent("ErrorXML", "dependency", Event.SUCCESS,
report.getDomain() + " " + report.getPeriod() + " " + report.getId());
}
}
} catch (Exception e) {
Cat.logError(e);
}
DependencyReport dependencyReport = merger.getDependencyReport();
dependencyReport.setStartTime(start);
dependencyReport.setEndTime(end);
return dependencyReport;
}
@Override
public TransactionReport queryTransactionReport(String domain, Date start, Date end) {
TransactionReportMerger merger = new TransactionReportMerger(new TransactionReport(domain));
......
......@@ -8,6 +8,7 @@ import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.database.model.entity.DatabaseReport;
import com.dianping.cat.consumer.dependency.model.entity.DependencyReport;
import com.dianping.cat.consumer.event.model.entity.EventReport;
import com.dianping.cat.consumer.health.model.entity.HealthReport;
import com.dianping.cat.consumer.heartbeat.model.entity.HeartbeatReport;
......@@ -395,6 +396,17 @@ public class ReportServiceImpl implements ReportService {
throw new RuntimeException("Top report don't have other report type but houly!");
}
}
@Override
public DependencyReport queryDependencyReport(String domain, Date start, Date end) {
int type = getQueryType(start, end);
if (type == s_hourly) {
return m_hourlyReportService.queryDependencyReport(domain, start, end);
} else {
throw new RuntimeException("Top report don't have other report type but houly!");
}
}
@Override
public TransactionReport queryTransactionReport(String domain, Date start, Date end) {
......
......@@ -15,11 +15,11 @@ import com.dainping.cat.consumer.core.dal.Report;
import com.dainping.cat.consumer.core.dal.ReportDao;
import com.dainping.cat.consumer.core.dal.ReportEntity;
import com.dianping.cat.Cat;
import com.dianping.cat.consumer.DomainManager;
import com.dianping.cat.consumer.cross.model.entity.CrossReport;
import com.dianping.cat.consumer.cross.model.transform.DefaultSaxParser;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.page.cross.DomainManager;
import com.dianping.cat.report.page.cross.display.ProjectInfo;
import com.dianping.cat.report.page.cross.display.TypeDetailInfo;
import com.dianping.cat.report.page.model.cross.CrossReportMerger;
......
......@@ -45,6 +45,8 @@ public class NavigationBar {
ReportPage.MATRIX,
ReportPage.DEPENDENCY,
ReportPage.HEALTH,
ReportPage.TOP,
......
package com.dianping.cat.system.alarm;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
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.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.template.entity.Duration;
import com.dianping.cat.system.alarm.alert.AlertInfo;
import com.dianping.cat.system.alarm.threshold.template.ThresholdAlarmMeta;
import com.dianping.cat.system.notify.ReportRenderImpl;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class AlarmContentBuilder implements Initializable {
public Configuration m_configuration;
@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);
}
}
public String buildAlarmTitle(ThresholdAlarmMeta meta) {
String type = meta.getType();
if (type.equalsIgnoreCase(AlertInfo.EXCEPTION)) {
return CatString.EXCEPTION + "[ " + String.valueOf(meta.getDomain()) + " ]";
} else if (type.equalsIgnoreCase(AlertInfo.SERVICE)) {
return CatString.SERVICE + "[ " + String.valueOf(meta.getDomain()) + " ]";
}
return "Default";
}
public String buildEmailAlarmContent(ThresholdAlarmMeta meta) {
Map<Object, Object> root = new HashMap<Object, Object>();
StringWriter sw = new StringWriter(5000);
root.put("rule", buildRuleMeta(meta.getDuration()));
root.put("count", meta.getRealCount());
root.put("domain", meta.getDomain());
root.put("date", meta.getDate());
root.put("url", buildProblemUrl(meta.getBaseShowUrl(), meta.getDomain(), meta.getDate()));
try {
String type = meta.getType();
if (type.equalsIgnoreCase(AlertInfo.EXCEPTION)) {
Template t = m_configuration.getTemplate("exceptionAlarm.ftl");
t.process(root, sw);
} else if (type.equalsIgnoreCase(AlertInfo.SERVICE)) {
Template t = m_configuration.getTemplate("serviceAlarm.ftl");
t.process(root, sw);
}
} catch (Exception e) {
Cat.logError(e);
}
return sw.toString();
}
private String buildProblemUrl(String baseUrl, String domain, Date date) {
long time = date.getTime();
time = time - time % TimeUtil.ONE_HOUR;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
baseUrl = baseUrl.replaceAll("dashboard", "p");
StringBuilder sb = new StringBuilder(baseUrl);
sb.append("?").append("domain=").append(domain).append("&date=").append(sdf.format(new Date(time)));
return sb.toString();
}
private Object buildRuleMeta(Duration duration) {
StringBuilder sb = new StringBuilder(100);
sb.append("[ Interval:").append(duration.getInterval()).append(";");
sb.append(" Min:").append(duration.getMin()).append(";");
sb.append(" Max:").append(duration.getMax()).append("]");
return sb.toString();
}
}
......@@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import org.unidal.lookup.logger.LoggerFactory;
import org.unidal.tuple.Pair;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.template.entity.Duration;
......@@ -38,7 +39,7 @@ public class ThresholdRule {
resetTemplate(template);
}
public ThresholdAlarmMeta addData(ThresholdDataEntity entity, String type) {
public Pair<Boolean, ThresholdAlarmMeta> addData(ThresholdDataEntity entity, String type) {
if (validateData(entity)) {
m_datas.add(entity);
m_lastData = entity;
......@@ -63,10 +64,11 @@ public class ThresholdRule {
meta.setBaseUrl(m_template.getConnection().getBaseUrl());
if (needAlarm(entity, duration)) {
m_lastAlarmTime.put(duration.getId(), date.getTime());
return meta;
return new Pair<Boolean, ThresholdAlarmMeta>(true, meta);
}
return null;
return new Pair<Boolean, ThresholdAlarmMeta>(false, meta);
}
}
}
......
package com.dianping.cat.system.alarm.threshold.listener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.unidal.lookup.annotation.Inject;
import org.unidal.tuple.Pair;
import com.dianping.cat.Cat;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.report.page.externalError.EventCollectManager;
import com.dianping.cat.system.alarm.AlarmContentBuilder;
import com.dianping.cat.system.alarm.alert.AlertInfo;
import com.dianping.cat.system.alarm.threshold.ThresholdDataEntity;
import com.dianping.cat.system.alarm.threshold.ThresholdRule;
......@@ -27,6 +34,35 @@ public class ExceptionDataListener implements EventListener {
@Inject
private ThresholdRuleManager m_manager;
@Inject
private EventCollectManager m_eventCollectManager;
@Inject
private AlarmContentBuilder m_builder;
private SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMddHH");
private void buildAlarmEvent(ThresholdAlarmMeta meta) {
com.dianping.cat.home.dal.report.Event alertEvent = new com.dianping.cat.home.dal.report.Event();
alertEvent.setType(EventCollectManager.CAT_ERROR);
alertEvent.setDate(new Date());
alertEvent.setDomain(meta.getDomain());
alertEvent.setIp(CatString.ALL);
alertEvent.setSubject(CatString.EXCEPTION_MANY + "[" + meta.getDomain() + "]");
alertEvent.setContent(m_builder.buildEmailAlarmContent(meta));
alertEvent.setLink("/cat/r/p?domain=" + meta.getDomain() + "&date="
+ m_sdf.format(getCurrentHour(meta.getDate())));
m_eventCollectManager.addEvent(alertEvent);
}
private Date getCurrentHour(Date date) {
long time = date.getTime();
time = time - time % TimeUtil.ONE_HOUR;
return new Date(time);
}
@Override
public boolean isEligible(Event event) {
if (event.getEventType() == EventType.ExceptionDataEvent) {
......@@ -42,25 +78,31 @@ public class ExceptionDataListener implements EventListener {
List<ThresholdRule> rules = m_manager.getExceptionRuleByDomain(data.getDomain());
for (ThresholdRule rule : rules) {
ThresholdAlarmMeta alarmMeta = rule.addData(data, AlertInfo.EXCEPTION);
Pair<Boolean, ThresholdAlarmMeta> alarmMeta = rule.addData(data, AlertInfo.EXCEPTION);
if (alarmMeta != null) {
Transaction t = Cat.newTransaction("SendAlarm", "Exception");
t.addData(alarmMeta.toString());
try {
ThresholdAlertEvent alertEvent = new ThresholdAlertEvent(alarmMeta);
Cat.getProducer().logEvent("ExceptionAlarm", "Domain", Message.SUCCESS,
String.valueOf(alarmMeta.getRuleId()));
m_dispatcher.dispatch(alertEvent);
t.setStatus("Alarm");
} catch (Exception e) {
t.setStatus(e);
Cat.logError(e);
} finally {
t.complete();
ThresholdAlarmMeta value = alarmMeta.getValue();
// need send email or sms
if (alarmMeta.getKey().booleanValue()) {
Transaction t = Cat.newTransaction("SendAlarm", "Exception");
t.addData(alarmMeta.toString());
try {
ThresholdAlertEvent alertEvent = new ThresholdAlertEvent(value);
Cat.getProducer().logEvent("ExceptionAlarm", "Domain", Message.SUCCESS,
String.valueOf(value.getRuleId()));
m_dispatcher.dispatch(alertEvent);
t.setStatus("Alarm");
} catch (Exception e) {
t.setStatus(e);
Cat.logError(e);
} finally {
t.complete();
}
}
buildAlarmEvent(value);
}
}
}
......
package com.dianping.cat.system.alarm.threshold.listener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.unidal.lookup.annotation.Inject;
import org.unidal.tuple.Pair;
import com.dianping.cat.Cat;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.report.page.externalError.EventCollectManager;
import com.dianping.cat.system.alarm.AlarmContentBuilder;
import com.dianping.cat.system.alarm.alert.AlertInfo;
import com.dianping.cat.system.alarm.threshold.ThresholdDataEntity;
import com.dianping.cat.system.alarm.threshold.ThresholdRule;
......@@ -27,6 +34,36 @@ public class ServiceDataListener implements EventListener {
@Inject
private ThresholdRuleManager m_manager;
@Inject
private EventCollectManager m_eventCollectManager;
@Inject
private AlarmContentBuilder m_builder;
private SimpleDateFormat m_sdf = new SimpleDateFormat("yyyyMMddHH");
private void buildAlarmEvent(ThresholdAlarmMeta meta) {
com.dianping.cat.home.dal.report.Event alertEvent = new com.dianping.cat.home.dal.report.Event();
alertEvent.setType(EventCollectManager.CAT_ERROR);
alertEvent.setDate(new Date());
alertEvent.setDomain(meta.getDomain());
alertEvent.setIp(CatString.ALL);
alertEvent.setSubject(CatString.SERVICE_MANY + "[" + meta.getDomain() + "]");
alertEvent.setContent(m_builder.buildEmailAlarmContent(meta));
alertEvent.setLink("/cat/r/p?domain=" + meta.getDomain() + "&date="
+ m_sdf.format(getCurrentHour(meta.getDate())));
m_eventCollectManager.addEvent(alertEvent);
}
private Date getCurrentHour(Date date) {
long time = date.getTime();
time = time - time % TimeUtil.ONE_HOUR;
return new Date(time);
}
@Override
public boolean isEligible(Event event) {
if (event.getEventType() == EventType.ServiceDataEvent) {
......@@ -43,27 +80,32 @@ public class ServiceDataListener implements EventListener {
List<ThresholdRule> rules = m_manager.getServiceRuleByDomain(data.getDomain());
for (ThresholdRule rule : rules) {
ThresholdAlarmMeta alarmMeta = rule.addData(data, AlertInfo.SERVICE);
Pair<Boolean, ThresholdAlarmMeta> alarmMeta = rule.addData(data, AlertInfo.SERVICE);
if (alarmMeta != null) {
Transaction t = Cat.newTransaction("SendAlarm", "Service");
t.addData(alarmMeta.toString());
try {
ThresholdAlertEvent alertEvent = new ThresholdAlertEvent(alarmMeta);
Cat.getProducer().logEvent("ServiceAlarm", "Domain", Message.SUCCESS,
String.valueOf(alarmMeta.getRuleId()));
m_dispatcher.dispatch(alertEvent);
t.setStatus(Transaction.SUCCESS);
t.setStatus("Alarm");
} catch (Exception e) {
t.setStatus(e);
} finally {
t.complete();
ThresholdAlarmMeta value = alarmMeta.getValue();
// need send email or sms
if (alarmMeta.getKey().booleanValue()) {
Transaction t = Cat.newTransaction("SendAlarm", "Service");
t.addData(alarmMeta.toString());
try {
ThresholdAlertEvent alertEvent = new ThresholdAlertEvent(value);
Cat.getProducer().logEvent("ServiceAlarm", "Domain", Message.SUCCESS,
String.valueOf(value.getRuleId()));
m_dispatcher.dispatch(alertEvent);
t.setStatus("Alarm");
} catch (Exception e) {
t.setStatus(e);
Cat.logError(e);
} finally {
t.complete();
}
}
buildAlarmEvent(value);
}
}
}
}
package com.dianping.cat.system.alarm.threshold.listener;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.helper.CatString;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.home.template.entity.Duration;
import com.dianping.cat.system.alarm.AlarmContentBuilder;
import com.dianping.cat.system.alarm.alert.AlertInfo;
import com.dianping.cat.system.alarm.alert.AlertManager;
import com.dianping.cat.system.alarm.threshold.event.ThresholdAlertEvent;
......@@ -22,32 +12,18 @@ import com.dianping.cat.system.alarm.threshold.template.ThresholdAlarmMeta;
import com.dianping.cat.system.event.Event;
import com.dianping.cat.system.event.EventListener;
import com.dianping.cat.system.event.EventType;
import com.dianping.cat.system.notify.ReportRenderImpl;
import com.dianping.cat.system.page.alarm.RuleManager;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class ThresholdAlertListener implements EventListener, Initializable {
public class ThresholdAlertListener implements EventListener {
@Inject
private AlertManager m_alertManager;
public Configuration m_configuration;
@Inject
private RuleManager m_ruleManager;
@Inject
private AlarmContentBuilder m_builder;
private String buildAlarmTitle(ThresholdAlarmMeta meta) {
String type = meta.getType();
if (type.equalsIgnoreCase(AlertInfo.EXCEPTION)) {
return CatString.EXCEPTION + "[ " + String.valueOf(meta.getDomain()) + " ]";
} else if (type.equalsIgnoreCase(AlertInfo.SERVICE)) {
return CatString.SERVICE + "[ " + String.valueOf(meta.getDomain()) + " ]";
}
return "Default";
}
private AlertInfo buildAlertInfo(ThresholdAlarmMeta meta, String title, String content, String ruleType,
int alertType) {
......@@ -62,67 +38,7 @@ public class ThresholdAlertListener implements EventListener, Initializable {
return info;
}
private String buildEmailAlarmContent(ThresholdAlarmMeta meta) {
Map<Object, Object> root = new HashMap<Object, Object>();
StringWriter sw = new StringWriter(5000);
root.put("rule", buildRuleMeta(meta.getDuration()));
root.put("count", meta.getRealCount());
root.put("domain", meta.getDomain());
root.put("date", meta.getDate());
root.put("url", buildProblemUrl(meta.getBaseShowUrl(), meta.getDomain(), meta.getDate()));
try {
String type = meta.getType();
if (type.equalsIgnoreCase(AlertInfo.EXCEPTION)) {
Template t = m_configuration.getTemplate("exceptionAlarm.ftl");
t.process(root, sw);
} else if (type.equalsIgnoreCase(AlertInfo.SERVICE)) {
Template t = m_configuration.getTemplate("serviceAlarm.ftl");
t.process(root, sw);
}
} catch (Exception e) {
Cat.logError(e);
}
return sw.toString();
}
private String buildProblemUrl(String baseUrl, String domain, Date date) {
long time = date.getTime();
time = time - time % TimeUtil.ONE_HOUR;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
baseUrl = baseUrl.replaceAll("dashboard", "p");
StringBuilder sb = new StringBuilder(baseUrl);
sb.append("?").append("domain=").append(domain).append("&date=").append(sdf.format(new Date(time)));
return sb.toString();
}
private Object buildRuleMeta(Duration duration) {
StringBuilder sb = new StringBuilder(100);
sb.append("[ Interval:").append(duration.getInterval()).append(";");
sb.append(" Min:").append(duration.getMin()).append(";");
sb.append(" Max:").append(duration.getMax()).append("]");
return sb.toString();
}
@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);
}
}
@Override
public boolean isEligible(Event event) {
......@@ -136,8 +52,8 @@ public class ThresholdAlertListener implements EventListener, Initializable {
public void onEvent(Event event) {
ThresholdAlertEvent alertEvent = (ThresholdAlertEvent) event;
ThresholdAlarmMeta metaInfo = alertEvent.getAlarmMeta();
String title = buildAlarmTitle(metaInfo);
String content = buildEmailAlarmContent(metaInfo);
String title = m_builder.buildAlarmTitle(metaInfo);
String content = m_builder.buildEmailAlarmContent(metaInfo);
String alertType = metaInfo.getDuration().getAlarm().toLowerCase();
String ruleType = metaInfo.getType();
......
......@@ -86,6 +86,48 @@
</query>
</query-defs>
</entity>
<entity name="event" table="event" alias="e">
<member name="id" field="id" value-type="int" length="10" nullable="false" key="true" auto-increment="true" />
<member name="type" field="type" value-type="int" length="10" nullable="false" />
<member name="link" field="link" value-type="String" length="500" />
<member name="domain" field="domain" value-type="String" length="50" />
<member name="ip" field="ip" value-type="String" length="32" />
<member name="subject" field="subject" value-type="String" length="200" />
<member name="content" field="content" value-type="String" length="65535" />
<member name="date" field="date" value-type="Date" nullable="false" />
<member name="creation-date" field="creation_date" value-type="Date" nullable="false" />
<var name="key-id" value-type="int" key-member="id" />
<primary-key name="PRIMARY" members="id" />
<readsets>
<readset name="FULL" all="true" />
</readsets>
<updatesets>
<updateset name="FULL" all="true" />
</updatesets>
<query-defs>
<query name="find-by-PK" type="SELECT">
<param name="key-id" />
<statement><![CDATA[SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='id'/> = ${key-id}]]></statement>
</query>
<query name="insert" type="INSERT">
<statement><![CDATA[INSERT INTO <TABLE/>(<FIELDS/>)
VALUES(<VALUES/>)]]></statement>
</query>
<query name="update-by-PK" type="UPDATE">
<param name="key-id" />
<statement><![CDATA[UPDATE <TABLE/>
SET <FIELDS/>
WHERE <FIELD name='id'/> = ${key-id}]]></statement>
</query>
<query name="delete-by-PK" type="DELETE">
<param name="key-id" />
<statement><![CDATA[DELETE FROM <TABLE/>
WHERE <FIELD name='id'/> = ${key-id}]]></statement>
</query>
</query-defs>
</entity>
<entity name="graph" table="graph" alias="g">
<member name="id" field="id" value-type="int" length="10" nullable="false" key="true" auto-increment="true" />
<member name="name" field="name" value-type="String" length="20" nullable="false" />
......
<?xml version="1.0" encoding="UTF-8"?>
<entities do-package="com.dianping.cat.home.dal.report" gen="true">
<entity name="dailyreport" table="dailyreport" alias="dr">
<member name="count" value-type="int" select-expr="COUNT(*)"
all="false" />
......@@ -444,6 +443,25 @@
</query>
</query-defs>
</entity>
<entity name="event" table="event" alias="e">
<member name="creation-date" insert-expr="NOW()" />
<var name="start-date" value-type="Date" />
<var name="end-date" value-type="Date" />
<query-defs>
<query name="find-by-domain-time" type="SELECT" multiple="true">
<param name="domain" />
<param name="start-date" />
<param name="end-date" />
<statement><![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='domain'/> = ${domain}
AND <FIELD name='date'/> >= ${start-date}
AND <FIELD name='date'/> <= ${end-date}
]]></statement>
</query>
</query-defs>
</entity>
</entities>
......
......@@ -418,32 +418,20 @@
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<implementation>com.dianping.cat.report.page.NormalizePayload</implementation>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
<implementation>com.dianping.cat.report.page.PayloadNormalizer</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.cross.DomainManager</role>
<implementation>com.dianping.cat.report.page.cross.DomainManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
<requirement>
<role>com.dainping.cat.consumer.core.dal.HostinfoDao</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.task.health.HealthServiceCollector</role>
<implementation>com.dianping.cat.report.task.health.HealthServiceCollector</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.report.page.cross.DomainManager</role>
<role>com.dianping.cat.consumer.DomainManager</role>
</requirement>
<requirement>
<role>com.dainping.cat.consumer.core.dal.ReportDao</role>
......@@ -585,6 +573,18 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.externalError.EventCollectManager</role>
<implementation>com.dianping.cat.report.page.externalError.EventCollectManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.EventDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>transaction-local</role-hint>
......@@ -1065,6 +1065,50 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>dependency-local</role-hint>
<implementation>com.dianping.cat.report.page.model.dependency.LocalDependencyService</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.storage.BucketManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.message.spi.MessageConsumer</role>
<role-hint>realtime</role-hint>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>dependency-historical</role-hint>
<implementation>com.dianping.cat.report.page.model.dependency.HistoricalDependencyService</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.storage.BucketManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.service.ReportService</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>dependency</role-hint>
<implementation>com.dianping.cat.report.page.model.dependency.CompositeDependencyService</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hints>
<role-hint>dependency-historical</role-hint>
</role-hints>
<field-name>m_services</field-name>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>metric-local</role-hint>
......@@ -1178,6 +1222,16 @@
<data-source-name>cat</data-source-name>
</configuration>
</component>
<component>
<role>org.unidal.dal.jdbc.mapping.TableProvider</role>
<role-hint>event</role-hint>
<implementation>org.unidal.dal.jdbc.mapping.SimpleTableProvider</implementation>
<configuration>
<logical-table-name>event</logical-table-name>
<physical-table-name>event</physical-table-name>
<data-source-name>cat</data-source-name>
</configuration>
</component>
<component>
<role>org.unidal.dal.jdbc.mapping.TableProvider</role>
<role-hint>graph</role-hint>
......@@ -1236,6 +1290,15 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.EventDao</role>
<implementation>com.dianping.cat.home.dal.report.EventDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.GraphDao</role>
<implementation>com.dianping.cat.home.dal.report.GraphDao</implementation>
......@@ -1510,7 +1573,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -1558,8 +1621,13 @@
<implementation>com.dianping.cat.configuration.ServerConfigManager</implementation>
</component>
<component>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<implementation>com.dianping.cat.report.page.NormalizePayload</implementation>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
<implementation>com.dianping.cat.report.page.PayloadNormalizer</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.transaction.Handler</role>
......@@ -1584,7 +1652,7 @@
<role>com.dianping.cat.report.page.transaction.TransactionMergeManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
......@@ -1647,7 +1715,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -1698,7 +1766,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -1813,6 +1881,11 @@
<role-hint>metric-local</role-hint>
<field-name>m_metricService</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>dependency-local</role-hint>
<field-name>m_dependencyService</field-name>
</requirement>
</requirements>
</component>
<component>
......@@ -1997,6 +2070,20 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.model.dependency.LocalDependencyService</role>
<implementation>com.dianping.cat.report.page.model.dependency.LocalDependencyService</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.storage.BucketManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.message.spi.MessageConsumer</role>
<role-hint>realtime</role-hint>
<field-name>m_consumer</field-name>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.sql.Handler</role>
<implementation>com.dianping.cat.report.page.sql.Handler</implementation>
......@@ -2008,7 +2095,7 @@
<role>com.dianping.cat.report.page.sql.JspViewer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
......@@ -2076,7 +2163,7 @@
<role>com.dianping.cat.report.page.matrix.JspViewer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
......@@ -2102,7 +2189,7 @@
<role>com.dianping.cat.report.page.health.JspViewer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.service.ReportService</role>
......@@ -2141,10 +2228,10 @@
<role>com.dianping.cat.report.service.ReportService</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.cross.DomainManager</role>
<role>com.dianping.cat.consumer.DomainManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
......@@ -2163,8 +2250,8 @@
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.cross.DomainManager</role>
<implementation>com.dianping.cat.report.page.cross.DomainManager</implementation>
<role>com.dianping.cat.consumer.DomainManager</role>
<implementation>com.dianping.cat.consumer.DomainManager</implementation>
<requirements>
<requirement>
<role>com.dainping.cat.consumer.core.dal.HostinfoDao</role>
......@@ -2205,7 +2292,7 @@
<role>com.dianping.cat.report.page.event.EventMergeManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
......@@ -2239,7 +2326,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -2271,7 +2358,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -2330,7 +2417,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -2356,7 +2443,7 @@
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.NormalizePayload</role>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
......@@ -2387,6 +2474,80 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.dependency.Handler</role>
<implementation>com.dianping.cat.report.page.dependency.Handler</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.report.page.dependency.JspViewer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.externalError.EventCollectManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.model.spi.ModelService</role>
<role-hint>dependency</role-hint>
<field-name>m_service</field-name>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.PayloadNormalizer</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.dependency.JspViewer</role>
<implementation>com.dianping.cat.report.page.dependency.JspViewer</implementation>
<requirements>
<requirement>
<role>org.unidal.web.mvc.view.model.ModelHandler</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.externalError.EventCollectManager</role>
<implementation>com.dianping.cat.report.page.externalError.EventCollectManager</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.home.dal.report.EventDao</role>
</requirement>
<requirement>
<role>com.dianping.cat.configuration.ServerConfigManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.home.dal.report.EventDao</role>
<implementation>com.dianping.cat.home.dal.report.EventDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.externalError.Handler</role>
<implementation>com.dianping.cat.report.page.externalError.Handler</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.report.page.externalError.JspViewer</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.externalError.EventCollectManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.consumer.DomainManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.report.page.externalError.JspViewer</role>
<implementation>com.dianping.cat.report.page.externalError.JspViewer</implementation>
<requirements>
<requirement>
<role>org.unidal.web.mvc.view.model.ModelHandler</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.system.SystemModule</role>
<implementation>com.dianping.cat.system.SystemModule</implementation>
......@@ -2648,6 +2809,10 @@
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.system.alarm.AlarmContentBuilder</role>
<implementation>com.dianping.cat.system.alarm.AlarmContentBuilder</implementation>
</component>
<component>
<role>com.dianping.cat.system.alarm.AlarmRuleCreator</role>
<implementation>com.dianping.cat.system.alarm.AlarmRuleCreator</implementation>
......@@ -2758,6 +2923,12 @@
<requirement>
<role>com.dianping.cat.system.alarm.threshold.ThresholdRuleManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.externalError.EventCollectManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.system.alarm.AlarmContentBuilder</role>
</requirement>
</requirements>
</component>
<component>
......@@ -2770,6 +2941,12 @@
<requirement>
<role>com.dianping.cat.system.alarm.threshold.ThresholdRuleManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.report.page.externalError.EventCollectManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.system.alarm.AlarmContentBuilder</role>
</requirement>
</requirements>
</component>
<component>
......@@ -2782,6 +2959,9 @@
<requirement>
<role>com.dianping.cat.system.page.alarm.RuleManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.system.alarm.AlarmContentBuilder</role>
</requirement>
</requirements>
</component>
<component>
......
......@@ -15,6 +15,7 @@
<table name="weeklyreport"/>
<table name="monthreport"/>
<table name="location"/>
<table name="event"/>
</group>
<group name="alarm" package="com.dianping.cat.home.dal.alarm">
<table name="alarmTemplate"/>
......
......@@ -59,6 +59,12 @@
<page name="jsError" title="JsError" path="jsError">
<description>jsError</description>
</page>
<page name="dependency" title="Dependency" path="dependency" template="default">
<description>Dependency</description>
</page>
<page name="externalError" title="externalError" path="externalError" template="default">
<description>ExternalError</description>
</page>
</module>
<module name="system" path="s" default="false">
<page name="alarm" title="Alarm" default="true" path="alarm">
......
function init(){
$('#contents').dataTable({
"sPaginationType": "full_numbers",
'iDisplayLength': 25,
'iDisplayLength': 50,
"oLanguage": {
"sProcessing": "正在加载中......",
"sLengthMenu": "每页显示 _MENU_ 条记录",
......
......@@ -64,7 +64,7 @@
<table class="machines">
<tr style="text-align: left">
<th>Domains: &nbsp;[&nbsp; <c:choose>
<c:when test="${empty model.domain}">
<c:when test="${model.domain eq 'All'}">
<a href="?database=${model.database}&date=${model.date}"
class="current">All</a>
</c:when>
......
<%@ 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.dependency.Context" scope="request"/>
<jsp:useBean id="payload" type="com.dianping.cat.report.page.dependency.Payload" scope="request"/>
<jsp:useBean id="model" type="com.dianping.cat.report.page.dependency.Model" scope="request"/>
<a:report title="Dependency Report"
navUrlPrefix="domain=${model.domain}">
<jsp:attribute name="subtitle">From ${w:format(model.report.startTime,'yyyy-MM-dd HH:mm:ss')} to ${w:format(model.report.endTime,'yyyy-MM-dd HH:mm:ss')}</jsp:attribute>
<jsp:body>
<res:useCss value="${res.css.local['bootstrap.css']}" target="head-css" />
<res:useCss value='${res.css.local.report_css}' target="head-css" />
<res:useCss value='${res.css.local.table_css}' target="head-css" />
<res:useJs value="${res.js.local['jquery-1.7.1.js']}" target="head-js" />
<res:useJs value="${res.js.local['bootstrap.min.js']}" target="head-js" />
<res:useJs value="${res.js.local['jquery.dataTables.min.js']}"
target="head-js" />
<div class="report">
<c:forEach var="item" items="${model.minutes}" varStatus="status">
<c:if test="${status.index % 30 ==0}">
<div class="pagination text-center">
<ul>
</c:if>
<li id="minute${item}"><a
href="?domain=${model.domain}&date=${model.date}&minute=${item}">
<c:if test="${item < 10}">0${item}</c:if>
<c:if test="${item >= 10}">${item}</c:if>
</a></li>
<c:if test="${status.index % 30 ==29 || status.last}">
</ul>
</div>
</c:if>
</c:forEach>
<div class="row-fluid">
<div class="span6">
<table class="contents table table-striped table-bordered table-condensed">
<thead> <tr>
<th>Name</th>
<th>Total Count</th>
<th>Failure Count</th>
<th>Failure%</th>
<th>Avg(ms)</th>
</tr></thead><tbody>
<c:forEach var="item" items="${model.segment.indexs}"
varStatus="status">
<c:set var="itemKey" value="${item.key}" />
<c:set var="itemValue" value="${item.value}" />
<tr>
<td>${itemValue.name}</td>
<td>${w:format(itemValue.totalCount,'#,###,###,###,##0')}</td>
<td>${w:format(itemValue.errorCount,'#,###,###,###,##0')}</td>
<td>${w:format(itemValue.errorCount/itemValue.totalCount,'0.0000')}</td>
<td>${w:format(itemValue.avg,'0.0')}</td>
</tr>
</c:forEach></tbody>
</table>
</br>
<table class="contents table table-striped table-bordered table-condensed">
<thead> <tr>
<th>Type</th>
<th>Target</th>
<th>Total Count</th>
<th>Failure Count</th>
<th>Failure%</th>
<th>Avg(ms)</th>
</tr></thead><tbody>
<c:forEach var="item" items="${model.segment.dependencies}"
varStatus="status">
<c:set var="itemKey" value="${item.key}" />
<c:set var="itemValue" value="${item.value}" />
<tr>
<td>${itemValue.type}</td>
<td>${itemValue.target}</td>
<td>${w:format(itemValue.totalCount,'#,###,###,###,##0')}</td>
<td>${w:format(itemValue.errorCount,'#,###,###,###,##0')}</td>
<td>${w:format(itemValue.errorCount/itemValue.totalCount,'0.0000')}</td>
<td>${w:format(itemValue.avg,'0.0')}</td>
</tr>
</c:forEach></tbody>
</table>
</div>
<div class="span6">
<div class="tabbable" id="otherDependency">
<ul class="nav nav-tabs">
<c:forEach var="item" items="${model.events}" varStatus="status" >
<li id="leftTab${status.index}" class="text-right"><a href="#tab${status.index}" data-toggle="tab">
${item.key}
<c:set var="size" value="${w:size(item.value)}"/>
<c:if test="${size > 0 }"><span class='text-error'>(${size})</span></c:if>
</a></li>
</c:forEach>
</ul>
<div class="tab-content">
<c:forEach var="entry" items="${model.events}" varStatus="status" >
<c:set var="items" value="${entry.value}"/>
<div class="tab-pane" id="tab${status.index}">
<table class="table table-striped table-bordered table-condensed">
<thead>
<tr><th>时间</th>
<th>详情</th>
<th>来源</th>
<th>项目名</th>
<th>IP</th>
</tr>
</thead>
<tbody>
<c:forEach var="item" items="${items}">
<tr><td>${w:format(item.date,'HH:mm')}</td>
<td>
<c:choose>
<c:when test="${not empty item.link}"><a href="${item.link}" target="_blank">${item.subject}</a></c:when>
<c:otherwise>${item.subject}</c:otherwise>
</c:choose>
<i data-content="${item.content}" data-original-title="详情" data-placement="top" data-toggle="popover" class="icon-tags" data-trigger="hover" tips=""></i>
</td>
<td>
<c:choose>
<c:when test="${item.type==1}">运维</c:when>
<c:when test="${item.type==2}">数据库</c:when>
<c:when test="${item.type==3}">CAT</c:when>
</c:choose>
</td>
<td>${item.domain}</td>
<td>${item.ip}</td>
</tr>
</c:forEach>
</table></div>
</c:forEach>
</div>
</div>
</tbody>
</div>
</div>
</div>
</jsp:body>
</a:report>
<script type="text/javascript">
$(document).ready(function() {
$('#minute'+${model.minute}).addClass('disabled');
$('.contents').dataTable({
"sPaginationType": "full_numbers",
'iDisplayLength': 50,
"bPaginate": false,
"bFilter": false,
});
$('#otherDependency .nav-tabs a').mouseenter(function (e) {
e.preventDefault();
$(this).tab('show');
});
$('i[tips]').popover();
$('#tab0').addClass('active');
$('#leftTab0').addClass('active');
$('.switch').css('display','none');
$('.dataTables_info').css('display','none');
});
</script>
<style>
.pagination{
margin:4px 0;
}
.pagination ul{
margin-top:0px;
}
</style>
\ No newline at end of file
......@@ -57,10 +57,10 @@
<c:choose>
<c:when test="${empty payload.type}">
<tr>
<th> Type</a></th>
<th class="right"><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=total">Total Count</a></th>
<th class="right"><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=failure">Failure Count</a></th>
<th class="right"><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=failurePercent">Failure%</a></th>
<th><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=type">Type</a></th>
<th class="right"><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=total">Total Count</a></th>
<th class="right"><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=failure">Failure Count</a></th>
<th class="right"><a href="?domain=${model.domain}&date=${model.date}&ip=${model.ipAddress}&sort=failurePercent">Failure%</a></th>
<th class="right">Sample Link</th>
<th class="right">QPS</th>
</tr>
......
<%@ page contentType="text/html; charset=utf-8" %>
SUCCESS
\ No newline at end of file
......@@ -7,13 +7,11 @@
<jsp:useBean id="payload" type="com.dianping.cat.report.page.metric.Payload" scope="request"/>
<jsp:useBean id="model" type="com.dianping.cat.report.page.metric.Model" scope="request"/>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<a:body>
<res:useCss value="${res.css.local['bootstrap.css']}" target="head-css" />
<res:useCss value='${res.css.local.report_css}' target="head-css" />
<res:useCss value='${res.css.local.table_css}' target="head-css" />
<res:useJs value="${res.js.local['jquery-1.7.1.js']}" target="head-js" />
<res:useJs value="${res.js.local['bootstrap.min.js']}" target="head-js"/>
<res:useJs value="${res.js.local['flotr2_js']}" target="head-js"/>
<res:useJs value="${res.js.local['metric.js']}" target="head-js"/>
......
......@@ -7,22 +7,6 @@
<jsp:useBean id="payload" type="com.dianping.cat.report.page.top.Payload" scope="request"/>
<jsp:useBean id="model" type="com.dianping.cat.report.page.top.Model" scope="request"/>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<script type="text/javascript">
/* if(${model.refresh}){
setTimeout(function refresh(){
window.location.href="?count=10";
},10000);
} */
$(document).ready(function() {
$('#topMetric a').mouseenter(function (e) {
e.preventDefault();
$(this).tab('show');
});
});
</script>
<style>
.tab-content table {
max-width: 100%;
......@@ -36,6 +20,7 @@
<res:useCss value="${res.css.local['bootstrap.css']}" target="head-css" />
<res:useCss value='${res.css.local.report_css}' target="head-css" />
<res:useCss value='${res.css.local.table_css}' target="head-css" />
<res:useJs value="${res.js.local['jquery-1.7.1.js']}" target="head-js" />
<res:useJs value="${res.js.local['bootstrap.min.js']}" target="head-js"/>
<div class="report">
......@@ -51,7 +36,7 @@
</tr>
</table>
<div class="tabbable tabs-left alert-info" id="topMetric"> <!-- Only required for left/right tabs -->
<div class="tabbable tabs-left alert-info" id="topMetric"> <!-- Only required for left/right tabs -->
<ul class="nav nav-tabs">
<li class="text-right active"><a href="#tab1" data-toggle="tab">异常最多Top10</a></li>
<li class='text-right'><a href="#tab2" data-toggle="tab">URL最慢Top10</a></li>
......@@ -146,4 +131,17 @@
</tr>
</table>
</div>
</a:body>
\ No newline at end of file
</a:body>
<script type="text/javascript">
/* if(${model.refresh}){
setTimeout(function refresh(){
window.location.href="?count=10";
},10000);
} */
$(document).ready(function() {
$('#topMetric .nav-tabs a').mouseenter(function (e) {
e.preventDefault();
$(this).tab('show');
});
});
</script>
\ No newline at end of file
......@@ -10,9 +10,9 @@
<a:body>
<res:useCss value='${res.css.local.alarm_css}' target="head-css" />
<res:useJs value="${res.js.local['alarm_js']}" target="head-js" />
<res:useCss value='${res.css.local.table_css}' target="head-css" />
<res:useCss value='${res.css.local.alarm_css}' target="head-css" />
<res:useJs value="${res.js.local['alarm_js']}" target="head-js" />
<res:useCss value='${res.css.local.table_css}' target="head-css" />
<res:useJs value="${res.js.local['jquery-1.7.1.js']}" target="head-js"/>
<res:useJs value="${res.js.local['jquery.dataTables.min.js']}" target="head-js"/>
<res:useJs value="${res.js.local['tableInit.js']}" target="head-js"/>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册