提交 f9097d9b 编写于 作者: Y youyong205

Merge pull request #397 from jialinsun/master

cat-agent 重构,app linechart
......@@ -45,7 +45,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(Executor.class, SystemStateExecutor.ID, SystemStateExecutor.class).req(EnvConfig.class,
CommandUtils.class));
all.add(C(TaskExecutors.class).req(DataSender.class));
all.add(C(TaskExecutors.class).req(DataSender.class, EnvConfig.class));
all.add(C(PaasTask.class).req(DataSender.class, DataBuilder.class));
......
package com.dianping.cat.agent.monitor.executors;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.util.StringUtils;
import com.dianping.cat.Cat;
import com.dianping.cat.configuration.NetworkInterfaceManager;
public class EnvConfig implements Initializable {
......@@ -20,6 +24,8 @@ public class EnvConfig implements Initializable {
private String m_hostName;
private String m_monitors;
private String MD5_PATH = "/usr/sbin/sshd";
private String PACKAGE_INTERFACE = "eth0";
......@@ -28,9 +34,9 @@ public class EnvConfig implements Initializable {
private String CATALINA_PATH = "/data/applogs/tomcat/catalina.out";
private List<String> TRAFFIC_INTERFACE_LIST = new ArrayList<String>(Arrays.asList("eth0", "lo"));
private List<String> TRAFFIC_INTERFACE_LIST = Arrays.asList("eth0", "lo");
private List<String> DISK_LIST = new ArrayList<String>(Arrays.asList("/", "/data", "/usr", "/var"));
private List<String> DISK_LIST = Arrays.asList("/", "/data", "/usr", "/var");
public String getDomain() {
return m_domain;
......@@ -48,6 +54,10 @@ public class EnvConfig implements Initializable {
return m_hostName;
}
public String getMonitors() {
return m_monitors;
}
public String getConfig() {
return CONFIG_FILE;
}
......@@ -91,31 +101,63 @@ public class EnvConfig implements Initializable {
return domain;
}
@Override
public void initialize() {
private void loadFromConfig(String defaultMonitors) {
Properties properties = new Properties();
InputStream in = null;
try {
String agent = System.getProperty("agent", "executors");
in = new BufferedInputStream(new FileInputStream(getConfig()));
properties.load(in);
if ("executors".equals(agent)) {
Properties properties = new Properties();
InputStream in = new BufferedInputStream(new FileInputStream(getConfig()));
properties.load(in);
m_hostName = properties.getProperty("host.name");
m_hostName = properties.getProperty("host.name");
if (m_hostName == null) {
m_hostName = NetworkInterfaceManager.INSTANCE.getLocalHostName();
m_domain = "unset";
} else {
m_domain = buildDomain(m_hostName);
}
m_ip = properties.getProperty("host.ip");
if (m_hostName == null) {
m_hostName = NetworkInterfaceManager.INSTANCE.getLocalHostName();
}
if (m_ip == null) {
m_ip = NetworkInterfaceManager.INSTANCE.getLocalHostAddress();
}
m_domain = buildDomain(m_hostName);
m_ip = properties.getProperty("host.ip");
m_monitors = properties.getProperty("host.monitors");
if (m_ip == null) {
m_ip = NetworkInterfaceManager.INSTANCE.getLocalHostAddress();
}
if (m_monitors == null) {
m_monitors = defaultMonitors;
}
} catch (Exception e) {
throw new RuntimeException("Error when init environment info ", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Cat.logError(e);
}
}
}
}
@Override
public void initialize() throws InitializationException {
String agent = System.getProperty("agent", "executors");
if ("executors".equals(agent)) {
File configFile = new File(getConfig());
String envMoniotors = System.getenv("MONITORS");
String defaultMonitors = StringUtils.isEmpty(envMoniotors) ? "system" : envMoniotors;
if (configFile.exists()) {
loadFromConfig(defaultMonitors);
} else {
m_domain = "unset";
m_monitors = defaultMonitors;
m_ip = NetworkInterfaceManager.INSTANCE.getLocalHostAddress();
m_hostName = NetworkInterfaceManager.INSTANCE.getLocalHostName();
}
}
}
}
package com.dianping.cat.agent.monitor.executors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
......@@ -14,15 +15,22 @@ import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.Cat;
import com.dianping.cat.agent.monitor.DataEntity;
import com.dianping.cat.agent.monitor.DataSender;
import com.dianping.cat.agent.monitor.executors.jvm.JVMMemoryExecutor;
import com.dianping.cat.agent.monitor.executors.jvm.JVMStateExecutor;
import com.dianping.cat.agent.monitor.executors.system.SystemPerformanceExecutor;
import com.dianping.cat.agent.monitor.executors.system.SystemStateExecutor;
import com.dianping.cat.message.Transaction;
public class TaskExecutors extends ContainerHolder implements Task, Initializable {
private Collection<Executor> m_executors;
@Inject
private DataSender m_sender;
@Inject
private EnvConfig m_config;
private Collection<Executor> m_executors = new ArrayList<Executor>();
private static final long DURATION = 5 * 1000;
@Override
......@@ -36,8 +44,17 @@ public class TaskExecutors extends ContainerHolder implements Task, Initializabl
if ("executors".equalsIgnoreCase(agent)) {
Map<String, Executor> map = lookupMap(Executor.class);
m_executors = map.values();
String monitors = m_config.getMonitors();
if (monitors.toLowerCase().contains("system")) {
m_executors.add(map.get(SystemPerformanceExecutor.ID));
m_executors.add(map.get(SystemStateExecutor.ID));
}
if (monitors.toLowerCase().contains("tomcat")) {
m_executors.add(map.get(JVMMemoryExecutor.ID));
m_executors.add(map.get(JVMStateExecutor.ID));
}
Threads.forGroup("Cat").start(this);
}
}
......
......@@ -7,7 +7,6 @@ import java.util.Map;
import org.codehaus.plexus.util.StringUtils;
import org.unidal.lookup.annotation.Inject;
import org.unidal.tuple.Pair;
import com.dianping.cat.Cat;
import com.dianping.cat.agent.monitor.CommandUtils;
......@@ -18,40 +17,38 @@ public class DataBuilder {
@Inject
private CommandUtils m_commandUtils;
private Map<String, String> m_ip2Md5 = new HashMap<String, String>();
private Map<String, Double> m_lastValues = new HashMap<String, Double>();
private Map<String, Pair<Double, Double>> m_lastFlow = new HashMap<String, Pair<Double, Double>>();
private Map<String, String> m_ip2Md5 = new HashMap<String, String>();
public String getPaasMonintor() {
return System.getProperty("user.dir") + "/paas-monitor.py";
}
private Pair<Double, Double> findOrCreateFlow(String ip) {
Pair<Double, Double> flow = m_lastFlow.get(ip);
private double findOrCreateSumValue(String key) {
Double value = m_lastValues.get(key);
if (flow == null) {
flow = new Pair<Double, Double>(-1D, -1D);
m_lastFlow.put(ip, flow);
if (value == null) {
value = new Double(-1D);
m_lastValues.put(key, value);
}
return flow;
return value;
}
private String findOrCreateMd5Info(String ip) {
String md5Info = m_ip2Md5.get(ip);
private String findOrCreateMd5Info(String key) {
String md5Info = m_ip2Md5.get(key);
if (md5Info == null) {
md5Info = "";
m_ip2Md5.put(ip, md5Info);
m_ip2Md5.put(key, md5Info);
}
return md5Info;
}
private List<DataEntity> convert2DataEntities(List<String> lines) {
List<DataEntity> dataEntities = new ArrayList<DataEntity>();
Pair<Double, Double> flow = null;
String domain = null;
String ip = null;
for (String line : lines) {
try {
......@@ -64,21 +61,15 @@ public class DataBuilder {
if (line.startsWith("domain")) {
domain = value;
ip = key.substring(key.lastIndexOf("_"));
flow = findOrCreateFlow(ip);
} else if (line.startsWith("system_eth0-in-flow")) {
DataEntity inFlow = buildInFlowData(domain, type, realKey, flow, value);
} else if ("sum".equals(type)) {
DataEntity inFlow = buildSumEntity(domain, type, realKey, key, value);
add2Entities(dataEntities, inFlow);
} else if (line.startsWith("system_eth0-out-flow")) {
DataEntity outFlow = buildOutFlowData(domain, type, realKey, flow, value);
add2Entities(dataEntities, outFlow);
} else if (line.startsWith("system_md5Change")) {
DataEntity md5Info = buildMd5Info(domain, type, realKey, ip, value);
DataEntity md5Info = buildMd5Info(domain, type, realKey, key, value);
add2Entities(dataEntities, md5Info);
} else {
} else if ("avg".equals(type)) {
DataEntity entity = new DataEntity();
entity.setGroup("system-" + domain).setDomain(domain).setId(realKey).setTime(System.currentTimeMillis())
......@@ -98,21 +89,21 @@ public class DataBuilder {
}
}
private DataEntity buildInFlowData(String domain, String type, String key, Pair<Double, Double> flow, String value) {
private DataEntity buildSumEntity(String domain, String type, String realKey, String key, String value) {
DataEntity entity = null;
try {
double flowValue = Double.parseDouble(value);
double lastInFlow = flow.getKey();
double currentValue = Double.parseDouble(value);
double lastValue = findOrCreateSumValue(key);
if (lastInFlow >= 0) {
double gap = flowValue - lastInFlow;
if (lastValue >= 0) {
double gap = currentValue - lastValue;
entity = new DataEntity();
entity.setGroup(buildGroup(domain)).setDomain(domain).setId(key).setTime(System.currentTimeMillis())
entity.setGroup(buildGroup(domain)).setDomain(domain).setId(realKey).setTime(System.currentTimeMillis())
.setType(type).setValue(gap);
}
flow.setKey(flowValue);
m_lastValues.put(key, currentValue);
} catch (Exception e) {
Cat.logError(e);
}
......@@ -120,29 +111,13 @@ public class DataBuilder {
return entity;
}
private DataEntity buildOutFlowData(String domain, String type, String key, Pair<Double, Double> flow, String value) {
DataEntity entity = null;
double flowValue = Double.parseDouble(value);
double lastFlow = flow.getValue();
if (lastFlow >= 0) {
double gap = flowValue - lastFlow;
entity = new DataEntity();
entity.setGroup(buildGroup(domain)).setDomain(domain).setId(key).setTime(System.currentTimeMillis())
.setType(type).setValue(gap);
}
flow.setValue(flowValue);
return entity;
}
private DataEntity buildMd5Info(String domain, String type, String key, String ip, String value) {
String md5Info = findOrCreateMd5Info(ip);
private DataEntity buildMd5Info(String domain, String type, String realKey, String key, String value) {
String md5Info = findOrCreateMd5Info(key);
DataEntity entity = null;
if (StringUtils.isNotEmpty(md5Info)) {
entity = new DataEntity();
entity.setGroup(buildGroup(domain)).setDomain(domain).setId(key).setTime(System.currentTimeMillis())
entity.setGroup(buildGroup(domain)).setDomain(domain).setId(realKey).setTime(System.currentTimeMillis())
.setType(type);
if (md5Info.equals(value)) {
entity.setValue(1);
......@@ -150,7 +125,7 @@ public class DataBuilder {
entity.setValue(0);
}
} else {
m_ip2Md5.put(ip, value);
m_ip2Md5.put(key, value);
}
return entity;
}
......
......@@ -101,6 +101,9 @@
<requirement>
<role>com.dianping.cat.agent.monitor.DataSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.agent.monitor.executors.EnvConfig</role>
</requirement>
</requirements>
</component>
<component>
......@@ -175,8 +178,15 @@
<requirement>
<role>com.dianping.cat.agent.monitor.DataSender</role>
</requirement>
<requirement>
<role>com.dianping.cat.agent.monitor.executors.EnvConfig</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.cat.agent.monitor.executors.EnvConfig</role>
<implementation>com.dianping.cat.agent.monitor.executors.EnvConfig</implementation>
</component>
<component>
<role>com.dianping.cat.agent.monitor.paas.PaasTask</role>
<implementation>com.dianping.cat.agent.monitor.paas.PaasTask</implementation>
......
......@@ -15,6 +15,11 @@ def execute(command):
return p.returncode, p.stdout.read(), p.stderr.read()
def docker_command(pid, command):
_, result, _ = execute(COMMAND_PATTERN % (pid, command))
return result.strip()
def get_instance_ids():
return [ele['Id'] for ele in json.loads(urllib2.urlopen('http://0.0.0.0:8090/containers/ps').read())]
......@@ -49,12 +54,12 @@ def get_name(inspect_info):
def get_cpu_usage(metric_info):
if 'current_usage' in metric_info['cpu_stats']['cpu_usage']:
return metric_info['cpu_stats']['cpu_usage']['current_usage']
return metric_info['cpu_stats']['cpu_usage']['cpu_usage']
return 0
def get_network_info(pid, network_name):
_, flow, _ = execute(COMMAND_PATTERN % (pid, 'ifconfig %s' % network_name))
flow = docker_command(pid, 'ifconfig %s' % network_name)
total_error, total_dropped, total_collision = [0] * 3
m = re.search(r'RX bytes:\s*(\d+).*?TX bytes:\s*(\d+)', flow, re.IGNORECASE)
......@@ -77,12 +82,11 @@ def get_network_info(pid, network_name):
return rx, tx, total_error, total_dropped, total_collision
def get_container_info(inspect_info):
pid = inspect_info['State']['Pid']
_, disk_usage, _ = execute(COMMAND_PATTERN % (pid, 'df -h | grep "rootfs"'))
def get_container_info(pid):
disk_usage = docker_command(pid, 'df -h | grep "rootfs"')
disk_usage = re.split(r'\s+', disk_usage.strip())[-2][:-1]
disk_usage = int(disk_usage) * 1.0 / 100
_, ssh_md5, _ = execute(COMMAND_PATTERN % (pid, 'md5sum /usr/sbin/sshd'))
ssh_md5 = docker_command(pid, 'md5sum /usr/sbin/sshd')
ssh_md5 = re.split(r'\s+', ssh_md5.strip())[0]
eth0_rx, eth0_tx, eth0_errors, eth0_dropped, eth0_collision = get_network_info(pid, 'eth0')
......@@ -97,7 +101,8 @@ def get_swap_usage(metric_info):
def get_memory_info(metric_info, instance_id):
used, cached = metric_info['memory_stats']['usage'], metric_info['memory_stats']['stats']['cache']
used, cached = metric_info['memory_stats']['stats']['rss'], metric_info['memory_stats']['stats']['cache']
shared, buffered = [0, 0]
total = -1
try:
result = json.loads(post('http://localhost:8090/containers/%s/cgroup' % instance_id,
......@@ -109,7 +114,29 @@ def get_memory_info(metric_info, instance_id):
except Exception, e:
pass
return total, used, cached
free = int(total) - int(used) - int(cached)
return total, used, cached, free, shared, buffered
def get_process_info(pid):
result = docker_command(pid, "top -b -n1 | grep Tasks | awk '{print $2,$4}'")
return re.split(r'\s+', result.strip())
def get_number_of_user_connected(pid):
result = docker_command(pid, "who | awk '{ print $1 }' | sort | uniq | wc -l")
return result.strip()
def get_tcp_established(pid):
result = docker_command(pid, 'netstat -anot | grep ESTABLISHED | wc -l')
return result.strip()
def get_inodes_info(pid):
result = docker_command(pid, "df -i | grep rootfs | awk '{print $2,$4}'")
return re.split(r'\s+', result.strip())
def post(url, data, headers={}):
......@@ -130,10 +157,16 @@ def get_all_info(current_instance=None):
inspect_info = instance_inspect(instance_id)
metric_info = instance_metric(instance_id)
pid = inspect_info['State']['Pid']
disk_usage, ssh_md5, eth0_rx, eth0_tx, eth0_errors, eth0_dropped, eth0_collision, lo_rx, lo_tx, \
lo_errors, lo_dropped, lo_collision = get_container_info(inspect_info)
lo_errors, lo_dropped, lo_collision = get_container_info(pid)
ip = get_ip(inspect_info)
mem_total, mem_used, mem_cached = get_memory_info(metric_info, instance_id)
mem_total, mem_used, mem_cached, mem_free, mem_shared, mem_buffered = get_memory_info(metric_info, instance_id)
process_total, process_running = get_process_info(pid)
number_of_user_connected = get_number_of_user_connected(pid)
tcp_established_num = get_tcp_established(pid)
inodes_total, inodes_free = get_inodes_info(pid)
m = [
('domain', '', get_name(inspect_info)),
......@@ -141,6 +174,9 @@ def get_all_info(current_instance=None):
('system_cachedMem', 'avg', mem_cached),
('system_totalMem', 'avg', mem_total),
('system_usedMem', 'avg', mem_used),
('system_freeMem', 'avg', mem_free),
('system_sharedMem', 'avg', mem_shared),
('system_buffersMem', 'avg', mem_buffered),
('system_/-usage', 'avg', disk_usage),
('system_swapUsage', 'avg', get_swap_usage(metric_info)),
('system_md5Change', 'avg', ssh_md5),
......@@ -152,9 +188,12 @@ def get_all_info(current_instance=None):
('system_eth0-collisions', 'sum', eth0_collision),
('system_lo-outFlow', 'sum', lo_tx),
('system_lo-inFlow', 'sum', lo_rx),
('system_lo-dropped', 'sum', lo_dropped),
('system_lo-errors', 'sum', lo_errors),
('system_lo-collisions', 'sum', lo_collision),
('system_totalProcess', 'avg', process_total),
('system_runningProcess', 'avg', process_running),
('system_establishedTcp', 'avg', tcp_established_num),
('system_loginUsers', 'avg', number_of_user_connected),
('system_/-freeInodes', 'avg', "%.3f" % (float(inodes_free) / int(inodes_total))),
]
print '\n'.join(['%s_%s%s=%s' % (k, ip, t and ':' + t, v) for k, t, v in m])
......
# pull cat-agent source and packge to RPM
# yum install rpm-build
# yum install rpmdevtools
set -e
set -u
if [ ! $# -eq 2 ];then
echo "Usage: makerpm.sh tomcat/jboss version."
exit 1
fi
container=$1
version=$2
if [ ! "$1" = "tomcat" ] && [ ! "$1" = "jboss" ]; then
echo "Usage: makerpm.sh tomcat/jboss version."
echo "Container can only be tomcat or jboss."
exit 1
fi
CAT_ROOT=~/cat
CAT_DIR=~/cat/cat
TMP_DIR=~/tmp
RPM_SOURCE_NAME=cat-agent-$container-$version
CAT_AGENT_INSTALL_DIR_NAME=cat-agent
mkdir -p $CAT_ROOT
cd $CAT_ROOT
if [ ! -e $CAT_DIR ]; then
git clone https://github.com/dianping/cat.git
fi
cd -
# pull lastest cat code
cd $CAT_DIR/cat-agent
git pull
# package it
mvn -Dmaven.test.skip clean package
cd -
# prepare agent code
mkdir -p $TMP_DIR
cd $TMP_DIR
rm -rf *
mkdir -p $RPM_SOURCE_NAME/$CAT_AGENT_INSTALL_DIR_NAME
unzip -d $RPM_SOURCE_NAME/$CAT_AGENT_INSTALL_DIR_NAME $CAT_DIR/cat-agent/target/cat-agent-*.war
tar czf $RPM_SOURCE_NAME.tar.gz $RPM_SOURCE_NAME
rpmdev-setuptree
cp $RPM_SOURCE_NAME.tar.gz ~/rpmbuild/SOURCES/
cp $CAT_DIR/cat-agent/src/main/rpm/cat-agent-$container.spec ~/rpmbuild/SPECS/
cd -
rpmbuild -bb ~/rpmbuild/SPECS/cat-agent-$container.spec
#%define name value
%define __jar_repack 0
Name: cat-agent-tomcat
Version: 1.0.5
Release: 1
Summary: cat-agent-tomcat
Requires: git
Requires(pre): /usr/sbin/useradd, /usr/bin/getent, /usr/sbin/usermod
Group: Development/Tools
License: GPL
Source0: %{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-XXXXXXXXXX)
%description
A powerful customized J2EE web container (JBoss, Jetty, Tomcat)
%pre
# add user cat
/usr/bin/getent passwd cat || /usr/sbin/useradd -u 2200 cat
/usr/sbin/usermod -a -G nobody cat || true
%prep
%setup -q
%build
%install
[ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT/*
# where to install agent files
AGENT_INSTALL_DIR=$RPM_BUILD_ROOT/data/webapps/cat/cat-agent
# create agent directories
[ -d $AGENT_INSTALL_DIR ] || mkdir -p $AGENT_INSTALL_DIR
# copy agent files to corresponding directories
cp -r cat-agent/* $AGENT_INSTALL_DIR/
chmod +x $AGENT_INSTALL_DIR/startup.sh
/bin/bash $AGENT_INSTALL_DIR/startup.sh
%post
# change required file permissions
APPLOGS_DIR=/data/applogs
APPDATAS_DIR=/data/appdatas
CAT_ROOT_DIR=/data/webapps/cat/
[ -d $APPLOGS_DIR ] && chown nobody:nobody $APPLOGS_DIR && chmod 775 $APPLOGS_DIR
[ -d $APPDATAS_DIR ] && chown nobody:nobody $APPDATAS_DIR && chmod 775 $APPDATAS_DIR
[ -d $CAT_ROOT_DIR ] && chown -R cat:cat $CAT_ROOT_DIR
# comment out Defaults requiretty to enabel sudo in scripts
awk 'BEGIN{result=""}{if(match($0, "^[^#]*Defaults[[:space:]]+requiretty")>0){result=sprintf("%s#%s\n",result,$0);}else{result=sprintf("%s%s\n",result,$0);}}END{print result > "/etc/sudoers"}' /etc/sudoers
AGENT_INSTALL_DIR=$RPM_BUILD_ROOT/data/webapps/cat/cat-agent
/bin/bash $AGENT_INSTALL_DIR/startup.sh
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,cat,cat,-)
/data/webapps/cat/cat-agent
%doc
%changelog
%preun
/usr/local/jdk/bin/jps -lvm | awk '$2=="com.dianping.cat.agent.monitor.CatAgent"{cmd=sprintf("kill -9 %s", $1);system(cmd)}'
%postun
/usr/local/jdk/bin/jps -lvm | awk '$2=="com.dianping.cat.agent.monitor.CatAgent"{cmd=sprintf("kill -9 %s", $1);system(cmd)}'
rm -rf /data/webapps/cat/cat-agent
......@@ -5,7 +5,13 @@ cd `dirname $0`
function kill_by_javaclass {
local javaclass=$1
/usr/local/jdk/bin/jps -lvm | awk -v javaclass=$javaclass '$2==javaclass{cmd=sprintf("kill -s TERM %s; sleep 1; kill -9 %s", $1, $1);system(cmd)}'
jps=/usr/local/jdk/bin/jps
if [ ! -x $jps ];then
jps=jps
fi
$jps -lvm | awk -v javaclass=$javaclass '$2==javaclass{cmd=sprintf("kill -s TERM %s; sleep 1; kill -9 %s", $1, $1);system(cmd)}'
}
agent_class="com.dianping.cat.agent.monitor.CatAgent"
......@@ -35,5 +41,12 @@ java=java
fi
echo "Starting cat-agent $agent_class $port `pwd`"
nohup $java -Xms128m -Xmx128m -classpath classes:"lib/*" -Dagent=$agent $agent_class $port /agent `pwd` >>/data/applogs/cat/agent-startup.log 2>&1 &
para=""
if [ "$agent" = "paas" ];then
ip=$(sh -c "ifconfig br0 | awk -v FS='[ \t:]+' 'NR == 2 {print \$4}'")
para="-Dhost.ip=$ip"
fi
nohup $java -Xms128m -Xmx128m -classpath classes:"lib/*" -Dagent=$agent $para $agent_class $port /agent `pwd` >>/data/applogs/cat/agent-startup.log 2>&1 &
echo "Started"
\ No newline at end of file
......@@ -12,7 +12,6 @@ import com.dianping.cat.DomainManager;
import com.dianping.cat.ServerConfigManager;
import com.dianping.cat.analysis.DefaultMessageAnalyzerManager;
import com.dianping.cat.analysis.MessageAnalyzerManager;
import com.dianping.cat.app.AppDataCommand;
import com.dianping.cat.app.AppDataCommandDao;
import com.dianping.cat.config.aggregation.AggregationConfigManager;
import com.dianping.cat.config.aggregation.AggregationHandler;
......@@ -64,11 +63,11 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(AggregationHandler.class, DefaultAggregationHandler.class));
all.add(C(AggregationConfigManager.class).req(AggregationHandler.class, ConfigDao.class));
all.add(C(AppConfigManager.class).req( ConfigDao.class));
all.add(C(AppDataService.class).req( AppDataCommandDao.class));
all.add(C(AppConfigManager.class).req(ConfigDao.class));
all.add(C(AppDataService.class).req(AppConfigManager.class, AppDataCommandDao.class));
all.add(C(UrlPatternHandler.class, DefaultUrlPatternHandler.class));
all.add(C(UrlPatternConfigManager.class).req(ConfigDao.class, UrlPatternHandler.class));
......@@ -80,7 +79,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
.req(ServerConfigManager.class, MessagePathBuilder.class, ServerStatisticManager.class));
all.add(C(Module.class, CatCoreModule.ID, CatCoreModule.class));
all.addAll(new CatCoreDatabaseConfigurator().defineComponents());
all.addAll(new CodecComponentConfigurator().defineComponents());
all.addAll(new StorageComponentConfigurator().defineComponents());
......
......@@ -3,6 +3,7 @@ package com.dianping.cat.config.app;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -106,7 +107,7 @@ public class AppConfigManager implements Initializable {
if (c != null) {
return c.getCodes().values();
} else {
return null;
return Collections.emptySet();
}
}
......@@ -120,14 +121,13 @@ public class AppConfigManager implements Initializable {
if (config != null) {
return new ArrayList<Item>(config.getItems().values());
} else {
System.out.println(name);
return new ArrayList<Item>();
}
}
public Map<String, Integer> getCommands() {
return m_commands;
}
return m_commands;
}
private void refreshCommand() {
Collection<Command> commands = m_config.getCommands().values();
......
package com.dianping.cat.config.app;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.unidal.dal.jdbc.DalException;
import org.unidal.lookup.annotation.Inject;
......@@ -10,12 +17,24 @@ import com.dianping.cat.Cat;
import com.dianping.cat.app.AppDataCommand;
import com.dianping.cat.app.AppDataCommandDao;
import com.dianping.cat.app.AppDataCommandEntity;
import com.dianping.cat.configuration.app.entity.Code;
public class AppDataService {
@Inject
private AppDataCommandDao m_dao;
@Inject
private AppConfigManager m_appConfigManager;
public static final String SUCCESS_RATIO = "successRatio";
public static final String REQUEST_COUNT = "requestCount";
public static final String DELAY_AVG = "delayAvg";
private static final int MAX_SIZE = 288;
public void insert(Date period, int minute, int commandId, int city, int operator, int network, int appVersion,
int connectType, int code, int platform, int count, int responseSumTime, int requestPackage,
int responsePackage) throws DalException {
......@@ -40,7 +59,7 @@ public class AppDataService {
m_dao.insertData(proto);
}
public void queryAvg(QueryEntity entity) {
public Map<String, double[]> queryValue(QueryEntity entity, String type) {
int commandId = entity.getCommand();
Date period = entity.getDate();
int city = entity.getCity();
......@@ -50,60 +69,142 @@ public class AppDataService {
int connnectType = entity.getChannel();
int code = entity.getCode();
int platform = entity.getPlatfrom();
List<AppDataCommand> datas;
try {
List<AppDataCommand> datas = m_dao.findData(commandId, period, city, operator, network, appVersion,
connnectType, code, platform, AppDataCommandEntity.READSET_DATA);
for (AppDataCommand data : datas) {
int minuteOrder = data.getMinuteOrder();
long count = data.getAccessNumberSum();
long sum = data.getResponseSumTimeSum();
double avg = sum / count;
datas = m_dao.findData(commandId, period, city, operator, network, appVersion, connnectType, code, platform,
AppDataCommandEntity.READSET_DATA);
Collections.sort(datas, new Comparator<AppDataCommand>() {
@Override
public int compare(AppDataCommand o1, AppDataCommand o2) {
return (int) (o2.getMinuteOrder() - o1.getMinuteOrder());
}
});
int n = calculateSize(entity.getDate().getTime());
if (SUCCESS_RATIO.equals(type)) {
return querySuccessRatio(datas, n);
} else if (REQUEST_COUNT.equals(type)) {
return queryRequestCount(datas, n);
} else if (DELAY_AVG.equals(type)) {
return queryDelayAvg(datas, n);
}
} catch (DalException e) {
Cat.logError(e);
}
return new LinkedHashMap<String, double[]>();
}
public void queryCount(QueryEntity entity) {
}
private Map<Integer, List<AppDataCommand>> convert2AppDataCommandMap(List<AppDataCommand> fromDatas) {
Map<Integer, List<AppDataCommand>> dataMap = new LinkedHashMap<Integer, List<AppDataCommand>>();
for (AppDataCommand from : fromDatas) {
int minute = from.getMinuteOrder();
List<AppDataCommand> data = dataMap.get(minute);
public void querySuccessRate(QueryEntity entity) {
if (data == null) {
data = new LinkedList<AppDataCommand>();
dataMap.put(minute, data);
}
data.add(from);
}
return dataMap;
}
public static class Statistics {
private Date m_period;
public Map<String, double[]> querySuccessRatio(List<AppDataCommand> datas, int n) {
Map<String, double[]> values = new LinkedHashMap<String, double[]>();
double[] value = new double[n];
int i = 0;
try {
Map<Integer, List<AppDataCommand>> dataMap = convert2AppDataCommandMap(datas);
int size = dataMap.size();
if (size <= n) {
for (Entry<Integer, List<AppDataCommand>> entry : dataMap.entrySet()) {
long success = 0;
long sum = 0;
for (AppDataCommand data : entry.getValue()) {
long number = data.getAccessNumberSum();
if (isSuccessStatus(data)) {
success += number;
}
sum += number;
}
value[i++] = (double) success / sum;
}
} else {
Cat.logError(new RuntimeException("query database minute number " + size + " lagger than expected size "
+ n));
}
} catch (Exception e) {
Cat.logError(e);
}
private long m_count;
values.put(DELAY_AVG, value);
return values;
}
private double m_avg;
private boolean isSuccessStatus(AppDataCommand data) {
int code = data.getCode();
Collection<Code> codes = m_appConfigManager.queryCodeByCommand(data.getCommandId());
public Date getPeriod() {
return m_period;
for (Code c : codes) {
if (c.getId() == code) {
return (c.getStatus() == 0);
}
}
return false;
}
public void setPeriod(Date period) {
m_period = period;
}
public Map<String, double[]> queryRequestCount(List<AppDataCommand> datas, int n) {
Map<String, double[]> values = new LinkedHashMap<String, double[]>();
double[] value = new double[n];
int i = 0;
public long getCount() {
return m_count;
}
for (AppDataCommand data : datas) {
long count = data.getAccessNumberSum();
public void setCount(long count) {
m_count = count;
if (i < n) {
value[i++] = count;
}
}
values.put(DELAY_AVG, value);
return values;
}
public double getAvg() {
return m_avg;
}
public Map<String, double[]> queryDelayAvg(List<AppDataCommand> datas, int n) {
Map<String, double[]> values = new LinkedHashMap<String, double[]>();
double[] value = new double[n];
int i = 0;
public void setAvg(double avg) {
m_avg = avg;
for (AppDataCommand data : datas) {
long count = data.getAccessNumberSum();
long sum = data.getResponseSumTimeSum();
double avg = sum / count;
if (i < n) {
value[i++] = avg;
}
}
values.put(DELAY_AVG, value);
return values;
}
private int calculateSize(long startTime) {
int n = MAX_SIZE;
int oneDay = 24 * 3600 * 1000;
if (startTime + oneDay > System.currentTimeMillis()) {
long current = System.currentTimeMillis();
long endTime = current - current % 300000;
n = (int) (endTime - startTime) / 300000;
}
return n;
}
}
......@@ -92,6 +92,9 @@
<role>com.dianping.cat.config.app.AppDataService</role>
<implementation>com.dianping.cat.config.app.AppDataService</implementation>
<requirements>
<requirement>
<role>com.dianping.cat.config.app.AppConfigManager</role>
</requirement>
<requirement>
<role>com.dianping.cat.app.AppDataCommandDao</role>
</requirement>
......
......@@ -13,6 +13,7 @@ import org.unidal.lookup.configuration.Component;
import com.dianping.cat.CatHomeModule;
import com.dianping.cat.ServerConfigManager;
import com.dianping.cat.config.app.AppDataService;
import com.dianping.cat.config.app.AppDataCommandTableProvider;
import com.dianping.cat.consumer.dependency.DependencyAnalyzer;
import com.dianping.cat.consumer.metric.MetricAnalyzer;
......@@ -38,6 +39,7 @@ import com.dianping.cat.report.graph.GraphBuilder;
import com.dianping.cat.report.graph.ValueTranslater;
import com.dianping.cat.report.page.JsonBuilder;
import com.dianping.cat.report.page.PayloadNormalizer;
import com.dianping.cat.report.page.app.graph.AppGraphCreator;
import com.dianping.cat.report.page.cdn.graph.CdnGraphCreator;
import com.dianping.cat.report.page.dependency.graph.TopologyGraphBuilder;
import com.dianping.cat.report.page.dependency.graph.TopologyGraphConfigManager;
......@@ -234,6 +236,69 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
MetricDataFetcher.class).req(BaselineService.class, MetricConfigManager.class,
ProductLineConfigManager.class, MetricGroupConfigManager.class, AlertInfo.class));
all.add(C(AppGraphCreator.class).req(AppDataService.class, CachedMetricReportService.class, DataExtractor.class,
MetricDataFetcher.class).req(BaselineService.class, MetricConfigManager.class,
ProductLineConfigManager.class, MetricGroupConfigManager.class, AlertInfo.class));
// report serivce
all.addAll(new ReportServiceComponentConfigurator().defineComponents());
// task
all.addAll(new TaskComponentConfigurator().defineComponents());
// model service
all.addAll(new ServiceComponentConfigurator().defineComponents());
all.add(C(RemoteMetricReportService.class).req(ServerConfigManager.class));
all.add(C(BusinessAlertConfig.class).req(AlertConfigManager.class));
all.add(C(NetworkAlertConfig.class).req(AlertConfigManager.class));
all.add(C(SystemAlertConfig.class).req(AlertConfigManager.class));
all.add(C(ExceptionAlertConfig.class).req(AlertConfigManager.class));
all.add(C(AlertInfo.class));
all.add(C(DefaultMailImpl.class).req(ServerConfigManager.class));
all.add(C(DataChecker.class, DefaultDataChecker.class));
all.add(C(BusinessAlert.class).req(MetricConfigManager.class, ProductLineConfigManager.class,
BaselineService.class, MailSMS.class, BusinessAlertConfig.class, AlertInfo.class, AlertDao.class)//
.req(RemoteMetricReportService.class, BusinessRuleConfigManager.class, DataChecker.class));
all.add(C(NetworkAlert.class).req(MetricConfigManager.class, ProductLineConfigManager.class,
BaselineService.class, MailSMS.class, NetworkAlertConfig.class, AlertInfo.class, AlertDao.class)//
.req(RemoteMetricReportService.class, NetworkRuleConfigManager.class, DataChecker.class));
all.add(C(SystemAlert.class).req(MetricConfigManager.class, ProductLineConfigManager.class,
BaselineService.class, MailSMS.class, SystemAlertConfig.class, AlertInfo.class, AlertDao.class)//
.req(RemoteMetricReportService.class, SystemRuleConfigManager.class, DataChecker.class));
all.add(C(AlertExceptionBuilder.class).req(ExceptionConfigManager.class));
all.add(C(ExceptionAlert.class).req(ProjectDao.class, ExceptionAlertConfig.class, MailSMS.class,
ExceptionConfigManager.class, AlertExceptionBuilder.class, AlertDao.class).req(ModelService.class,
TopAnalyzer.ID));
all.add(C(NetGraphConfigManager.class).req(ConfigDao.class));
// database
all.add(C(JdbcDataSourceDescriptorManager.class) //
.config(E("datasourceFile").value("/data/appdatas/cat/datasources.xml")));
all.addAll(new CatDatabaseConfigurator().defineComponents());
all.addAll(new UserDatabaseConfigurator().defineComponents());
// update project database
all.add(C(ProjectUpdateTask.class)//
.req(ProjectDao.class, HostinfoDao.class));
// web, please keep it last
all.addAll(new WebComponentConfigurator().defineComponents());
// for alarm module
all.addAll(new AlarmComponentConfigurator().defineComponents());
return all;
}
}
......@@ -230,7 +230,7 @@ public abstract class AbstractGraphCreator implements LogEnabled {
}
}
protected Map<Long, Double> buildNoneData(Date startDate, Date endDate, int step) {
public Map<Long, Double> buildNoneData(Date startDate, Date endDate, int step) {
int n = 0;
long current = System.currentTimeMillis();
......
package com.dianping.cat.report.page.app;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletException;
import com.dianping.cat.config.app.AppConfigManager;
import com.dianping.cat.config.app.QueryEntity;
import com.dianping.cat.report.ReportPage;
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.config.app.AppConfigManager;
import com.dianping.cat.config.app.QueryEntity;
import com.dianping.cat.report.ReportPage;
import com.dianping.cat.report.page.LineChart;
import com.dianping.cat.report.page.app.graph.AppGraphCreator;
public class Handler implements PageHandler<Context> {
@Inject
private JspViewer m_jspViewer;
......@@ -20,6 +26,9 @@ public class Handler implements PageHandler<Context> {
@Inject
private AppConfigManager m_manager;
@Inject
private AppGraphCreator m_appGraphCreator;
@Override
@PayloadMeta(Payload.class)
@InboundActionMeta(name = "app")
......@@ -45,14 +54,36 @@ public class Handler implements PageHandler<Context> {
QueryEntity entity1 = payload.getQueryEntity1();
QueryEntity entity2 = payload.getQueryEntity2();
String type = payload.getType();
if (StringUtils.isEmpty(type)) {
type = "successRatio";
}
LineChart lineCharts = new LineChart();
if (entity1 != null) {
System.out.println(entity1.toString());
LineChart lineChart1 = m_appGraphCreator.buildLineChart(entity1, type);
Iterator<Map<Long, Double>> idata = lineChart1.getDatas().iterator();
if (lineChart1.getDatas().size() == 1) {
lineCharts.add("查询1", idata.next());
}
}
if (entity2 != null) {
System.out.println(entity2.toString());
LineChart lineChart2 = m_appGraphCreator.buildLineChart(entity2, type);
Iterator<Map<Long, Double>> idata = lineChart2.getDatas().iterator();
if (lineChart2.getDatas().size() == 1) {
lineCharts.add("查询2", idata.next());
}
}
lineCharts.setId("app");
lineCharts.setHtmlTitle(type);
model.setLineChart(lineCharts);
if (!ctx.isProcessStopped()) {
m_jspViewer.view(ctx, model);
}
......
......@@ -6,14 +6,20 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.unidal.web.mvc.view.annotation.EntityMeta;
import com.dianping.cat.configuration.app.entity.Code;
import com.dianping.cat.configuration.app.entity.Command;
import com.dianping.cat.configuration.app.entity.Item;
import com.dianping.cat.report.page.AbstractReportModel;
import com.dianping.cat.report.page.JsonBuilder;
import com.dianping.cat.report.page.LineChart;
public class Model extends AbstractReportModel<Action, Context> {
@EntityMeta
private LineChart m_lineChart;
private List<Item> m_cities;
private List<Item> m_versions;
......@@ -117,4 +123,12 @@ public class Model extends AbstractReportModel<Action, Context> {
public void setVersions(List<Item> versions) {
m_versions = versions;
}
public LineChart getLineChart() {
return m_lineChart;
}
public void setLineChart(LineChart lineChart) {
m_lineChart = lineChart;
}
}
......@@ -19,6 +19,9 @@ public class Payload extends AbstractReportPayload<Action> {
@FieldMeta("query2")
private String m_query2;
@FieldMeta("type")
private String m_type = "successRatio";
public Payload() {
super(ReportPage.APP);
}
......@@ -74,6 +77,14 @@ public class Payload extends AbstractReportPayload<Action> {
m_query2 = query2;
}
public void setType(String type) {
m_type = type;
}
public String getType() {
return m_type;
}
@Override
public void validate(ActionContext<?> ctx) {
if (m_action == null) {
......
package com.dianping.cat.report.page.app.graph;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import org.unidal.lookup.annotation.Inject;
import com.dianping.cat.config.app.AppDataService;
import com.dianping.cat.config.app.QueryEntity;
import com.dianping.cat.helper.TimeUtil;
import com.dianping.cat.report.chart.AbstractGraphCreator;
import com.dianping.cat.report.page.LineChart;
public class AppGraphCreator extends AbstractGraphCreator {
@Inject
private AppDataService m_appDataService;
public LineChart buildLineChart(QueryEntity queryEntity, String type) {
Map<String, double[]> values = prepareAllData(queryEntity, type);
long startTime = queryEntity.getDate().getTime();
long endTime = startTime + TimeUtil.ONE_DAY;
Date endDate = new Date(endTime);
Date startDate = new Date(startTime);
return buildChartData(values, startDate, endDate);
}
private Map<String, double[]> prepareAllData(QueryEntity queryEntity, String type) {
Map<String, double[]> value = new AppDataServiceMock().queryValue(queryEntity, type);
return value;
}
public LineChart buildChartData(final Map<String, double[]> datas, Date startDate, Date endDate) {
LineChart lineChart = new LineChart();
for (Entry<String, double[]> entry : datas.entrySet()) {
String key = entry.getKey();
lineChart.setId(startDate.toString());
lineChart.setHtmlTitle(key);
Map<Long, Double> all = convertToMap(datas.get(key), startDate, 5);
lineChart.add(startDate.toString(), all);
}
return lineChart;
}
protected Map<Long, Double> convertToMap(double[] data, Date start, int step) {
Map<Long, Double> map = new LinkedHashMap<Long, Double>();
int length = data.length;
long startTime = start.getTime();
long time = startTime;
int i = 0;
for (; i < length; i++) {
time += step * TimeUtil.ONE_MINUTE;
map.put(time, data[i]);
}
return map;
}
public class AppDataServiceMock extends AppDataService {
public Map<String, double[]> queryValue(QueryEntity entity, String type) {
if (SUCCESS_RATIO.equals(type)) {
return querySuccessRatio(entity);
} else if (REQUEST_COUNT.equals(type)) {
return queryRequestCount(entity);
} else if (DELAY_AVG.equals(type)) {
return queryDelayAvg(entity);
} else {
return new LinkedHashMap<String, double[]>();
}
}
private Map<String, double[]> makeMockValue(String type) {
Map<String, double[]> map = new LinkedHashMap<String, double[]>();
long startTime = TimeUtil.getCurrentDay().getTime();
long current = System.currentTimeMillis();
long endTime = current - current % 300000;
int n = (int) (endTime - startTime) / 300000;
double[] value = new double[n];
for (int i = 0; i < n; i++) {
value[i] = (new Random().nextDouble() + 1) * 100;
}
map.put(type, value);
return map;
}
private Map<String, double[]> querySuccessRatio(QueryEntity entity) {
return makeMockValue(SUCCESS_RATIO);
}
private Map<String, double[]> queryDelayAvg(QueryEntity entity) {
return makeMockValue(DELAY_AVG);
}
private Map<String, double[]> queryRequestCount(QueryEntity entity) {
return makeMockValue(REQUEST_COUNT);
}
}
}
......@@ -31,11 +31,11 @@ public class SystemGraphCreator extends AbstractGraphCreator {
"/-usage:avg", "/-freeInodes:avg", "/-read:sum", "/-write:sum", "/data-usage:avg", "/data-freeInodes:avg",
"/data-read:sum", "/data-write:sum", "/usr-usage:avg", "/usr-freeInodes:avg", "/usr-read:sum",
"/usr-write:sum", "/var-usage:avg", "/var-freeInodes:avg", "/var-read:sum", "/var-write:sum",
"eth0-inFlow:sum", "eth0-outFlow:sum", "eth0-dropped:sum", "eth0-errors:sum", "lo-inFlow:sum",
"lo-outFlow:sum", "lo-dropped:sum", "lo-errors:sum", "swapUsage:avg", "loadAvg1:avg", "loadAvg5:avg",
"totalMem:avg", "usedMem:avg", "freeMem:avg", "sharedMem:avg", "buffersMem:avg", "cachedMem:avg",
"totalProcess:avg", "runningProcess:avg", "swapUsage:avg", "establishedTcp:avg", "loginUsers:avg",
"uptime:avg", "md5Change:avg", "hostNameChange:avg", "hostIpChange:avg"));
"eth0-inFlow:sum", "eth0-outFlow:sum", "eth0-dropped:sum", "eth0-errors:sum", "eth0-collisions:sum",
"lo-inFlow:sum", "lo-outFlow:sum", "swapUsage:avg", "loadAvg1:avg", "loadAvg5:avg", "totalMem:avg",
"usedMem:avg", "freeMem:avg", "sharedMem:avg", "buffersMem:avg", "cachedMem:avg", "totalProcess:avg",
"runningProcess:avg", "swapUsage:avg", "establishedTcp:avg", "loginUsers:avg", "uptime:avg", "md5Change:avg",
"hostNameChange:avg", "hostIpChange:avg"));
private static final List<String> JVM_KEY_LIST = new ArrayList<String>(Arrays.asList("edenUsage:avg",
"oldUsage:avg", "permUsage:avg", "catalinaLogSize:sum"));
......
<alert-config>
<receiver id="network" enable="false">
<email>leon.li@dianping.com</email>
<phone>18662513308</phone>
</receiver>
<receiver id="exception" enable="false">
<email>jialin.sun@dianping.com</email>
</receiver>
<receiver id="business" enable="false">
<email>yong.you@dianping.com</email>
<email>argus@dianping.com</email>
<email>jialin.sun@dianping.com</email>
<email>monitor@dianping.com</email>
<phone>13916536843</phone>
<phone>18616671676</phone>
<phone>13858086694</phone>
</receiver>
</alert-config>
......@@ -117,8 +117,100 @@ function graphMetricChart(container, data) {
week : '%Y-%m-%d',
month : '%m-%d',
year : '%Y-%m'
},
},
yAxis : {
min : ylabelMin,
title: {
text: data.unit,
}
},
credits : {
enabled : false
},
plotOptions : {
spline : {
lineWidth : 2,
states : {
hover : {
lineWidth : 2
}
},
marker : {
enabled : false
}
}
},
legend : {
maxHeight : 82
},
tooltip : {
allowPointSelect : false,
formatter : function() {
var number0 = Number(this.y).toFixed(0);
var number1 = Number(this.y).toFixed(1);
var number = number1;
if(Number(number1)==Number(number0)){
number = number0;
}
return Highcharts.dateFormat('%Y-%m-%d %H:%M',
this.x)
+ '<br/>['+ this.series.name + '] '+ '<b>' + number + '</b>';
}
},
series : _data
});
}
function parseMetricLineDataForApp(data) {
var res = [];
data.subTitles.forEach(function(title, i) {
var series = {}
series.name = title;
series.data = [];
var map = data.datas[i];
var j = 0;
for ( var key in map) {
var value = map[key];
series.data[j] = value;
j++;
}
res.push(series);
});
return res;
}
function graphMetricChartForApp(container, data) {
Highcharts.setOptions({
global : {
useUTC : false
}
});
var ylabelMin = data.minYlable;
var _data = parseMetricLineDataForApp(data);
$(container).highcharts(
{
chart : {
type : 'spline'
},
title : {
text : data.htmlTitle,
useHTML: true
},
xAxis : {
type : "category",
labels : {
step : 12,
maxStaggerLines : 1,
formatter: function() {
return this.value / 12;
}
},
max : 288
},
yAxis : {
min : ylabelMin,
title: {
......@@ -163,6 +255,7 @@ function graphMetricChart(container, data) {
series : _data
});
}
function graphLineChart(container, data) {
Highcharts.setOptions({
global : {
......
......@@ -3,18 +3,18 @@
<%@ 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.app.Context"
scope="request" />
<jsp:useBean id="payload"
type="com.dianping.cat.report.page.app.Payload" scope="request" />
<jsp:useBean id="model" type="com.dianping.cat.report.page.app.Model"
scope="request" />
<jsp:useBean id="ctx" type="com.dianping.cat.report.page.app.Context" scope="request" />
<jsp:useBean id="payload" type="com.dianping.cat.report.page.app.Payload" scope="request" />
<jsp:useBean id="model" type="com.dianping.cat.report.page.app.Model" scope="request" />
<a:body>
<res:useCss value="${res.css.local['select2.css']}" target="head-css" />
<res:useCss value="${res.css.local['bootstrap-datetimepicker.min.css']}" target="head-css" />
<res:useCss
value="${res.css.local['bootstrap-datetimepicker.min.css']}"
target="head-css" />
<res:useJs value="${res.js.local['select2.min.js']}" target="head-js" />
<res:useJs value="${res.js.local['bootstrap-datetimepicker.min.js']}" target="head-js" />
<res:useJs value="${res.js.local['bootstrap-datetimepicker.min.js']}"
target="head-js" />
<res:useJs value="${res.js.local['baseGraph.js']}" target="head-js" />
<script type="text/javascript">
var commandInfo = ${model.command};
......@@ -32,7 +32,6 @@
var key = $("#command").val();
var value = commandInfo[key];
var code = document.getElementById("code");
code.length = 0;
for ( var prop in value) {
var opt = $('<option />');
......@@ -45,7 +44,6 @@
var key = $("#command2").val();
var value = commandInfo[key];
var code = document.getElementById("code2");
code.length = 0;
for ( var prop in value) {
var opt = $('<option />');
......@@ -61,7 +59,7 @@
return myDate.getFullYear() + "-" + myDate.getMonth() + "-"
+ myDate.getDate();
}
function query() {
var time = $("#time").val();
var command = $("#command").val();
......@@ -94,8 +92,18 @@
+ split + palteform2 + split + city2 + split
+ operator2;
}
var checkboxs = document.getElementsByName("typeCheckbox");
var type = "";
for(var i=0; i<checkboxs.length;i++){
if(checkboxs[i].checked){
type = checkboxs[i].value;
break;
}
}
var href = "?query1=" + query1 + "&query2=" + query2;
var href = "?query1=" + query1 + "&query2=" + query2 + "&type=" + type;
window.location.href = href;
}
......@@ -113,13 +121,14 @@
command2.on('change', command2Change);
$("#command").val(words[1]);
if(words[0]==null||words[0].length==0){
if (words[0] == null || words[0].length == 0) {
$("#time").val(getDate());
}else{
} else {
$("#time").val(words[0]);
}
command1Change();
$("#code").val(words[2]);
$("#network").val(words[3]);
......@@ -134,9 +143,9 @@
document.getElementById("checkbox").checked = true;
var words = query2.split(";");
if(words[0]==null||words[0].length==0){
if (words[0] == null || words[0].length == 0) {
$("#time2").val(getDate());
}else{
} else {
$("#time2").val(words[0]);
}
......@@ -149,9 +158,22 @@
$("#platform2").val(words[6]);
$("#city2").val(words[7]);
$("#operator2").val(words[8]);
}else{
} else {
$("#time2").val(getDate());
}
var checkboxs = document.getElementsByName("typeCheckbox");
for(var i=0; i<checkboxs.length;i++){
if(checkboxs[i].value == "${payload.type}"){
checkboxs[i].checked = true;
break;
}
}
var data = ${model.lineChart.jsonString};
graphMetricChartForApp(document.getElementById('${model.lineChart.id}'), data);
});
</script>
<div class="report">
......@@ -166,11 +188,13 @@
data-date-icon="icon-calendar"> </i>
</span>
</div> 命令字 <select id="command" style="width: 350px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.commands}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 返回码 <select id="code" style="width: 120px;">
</select> 返回码 <select id="code" style="width: 120px;"><option value='0' >All</option>
</select> 网络类型 <select id="network" style="width: 80px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.networks}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
......@@ -179,23 +203,28 @@
</tr>
<tr>
<th align=left>版本 <select id="version" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.versions}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 渠道 <select id="channel" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.channels}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 平台 <select id="platform" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.platforms}"
varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 地区 <select id="city" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.cities}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 运营商 <select id="operator" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.operators}"
varStatus="status">
<option value='${item.id}'>${item.name}</option>
......@@ -219,11 +248,14 @@
data-date-icon="icon-calendar"> </i>
</span>
</div> 命令字 <select id="command2" style="width: 350px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.commands}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 返回码 <select id="code2" style="width: 120px;">
<option value='0' >All</option>
</select> 网络类型 <select id="network2" style="width: 80px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.networks}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
......@@ -232,23 +264,28 @@
</tr>
<tr>
<th align=left>版本 <select id="version2" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.versions}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 渠道 <select id="channel2" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.channels}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 平台 <select id="platform2" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.platforms}"
varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 地区 <select id="city2" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.cities}" varStatus="status">
<option value='${item.id}'>${item.name}</option>
</c:forEach>
</select> 运营商 <select id="operator2" style="width: 100px;">
<option value='0' >All</option>
<c:forEach var="item" items="${model.operators}"
varStatus="status">
<option value='${item.id}'>${item.name}</option>
......@@ -258,6 +295,20 @@
</tr>
</table>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-info"> <input type="radio"
name="typeCheckbox" value="successRatio" onclick="query()" >成功率
</label> <label class="btn btn-info"> <input type="radio"
name="typeCheckbox" value="requestCount" onclick="query()" >总请求数
</label> <label class="btn btn-info"> <input type="radio"
name="typeCheckbox" value="delayAvg" onclick="query()" >成功延时(ms)
</label>
</div>
<div style="float:left;width:95%;">
<div id="${model.lineChart.id}"></div>
</div>
<table class="footer">
<tr>
<td>[ end ]</td>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册