support stat data report. #848

This commit is contained in:
hengyunabc
2019-09-24 22:28:06 +08:00
parent 0eff92a539
commit fc502725c0
8 changed files with 131 additions and 29 deletions
+14 -1
View File
@@ -133,6 +133,9 @@ TUNNEL_SERVER=
# agent id
AGENT_ID=
# stat report url
STAT_URL=
############ Command Arguments ############
# if arguments contains -c/--command or -f/--batch-file, BATCH_MODE will be true
@@ -400,7 +403,7 @@ usage()
Usage:
$0 [-h] [--target-ip <value>] [--telnet-port <value>]
[--http-port <value>] [--session-timeout <value>] [--arthas-home <value>]
[--tunnel-server <value>] [--agent-id <value>]
[--tunnel-server <value>] [--agent-id <value>] [--stat-url <value>]
[--use-version <value>] [--repo-mirror <value>] [--versions] [--use-http]
[--attach-only] [-c <value>] [-f <value>] [-v] [pid]
@@ -434,6 +437,7 @@ EXAMPLES:
./as.sh --telnet-port 9999 --http-port -1
./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws'
./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws' --agent-id bvDOe8XbTM2pQWjF4cfw
./as.sh --stat-url 'http://192.168.10.11:8080/api/stat'
./as.sh -c 'sysprop; thread' <pid>
./as.sh -f batch.as <pid>
./as.sh --use-version 3.1.3
@@ -539,6 +543,11 @@ parse_arguments()
shift # past argument
shift # past value
;;
--stat-url)
STAT_URL="$2"
shift # past argument
shift # past value
;;
--use-http)
USE_HTTP=true
shift # past argument
@@ -714,6 +723,10 @@ attach_jvm()
tempArgs+=("-agent-id")
tempArgs+=("${AGENT_ID}")
fi
if [ "${STAT_URL}" ]; then
tempArgs+=("-stat-url")
tempArgs+=("${STAT_URL}")
fi
"${java_command[@]}" \
${ARTHAS_OPTS} ${JVM_OPTS} \
@@ -42,6 +42,9 @@ import com.taobao.middleware.cli.annotations.Summary;
@Summary("Bootstrap Arthas")
@Description("EXAMPLES:\n" + " java -jar arthas-boot.jar <pid>\n" + " java -jar arthas-boot.jar --target-ip 0.0.0.0\n"
+ " java -jar arthas-boot.jar --telnet-port 9999 --http-port -1\n"
+ " java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws'\n"
+ " java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws' --agent-id bvDOe8XbTM2pQWjF4cfw\n"
+ " java -jar arthas-boot.jar --stat-url 'http://192.168.10.11:8080/api/stat'\n"
+ " java -jar arthas-boot.jar -c 'sysprop; thread' <pid>\n"
+ " java -jar arthas-boot.jar -f batch.as <pid>\n"
+ " java -jar arthas-boot.jar --use-version 3.1.3\n"
@@ -109,6 +112,8 @@ public class Bootstrap {
private String tunnelServer;
private String agentId;
private String statUrl;
static {
ARTHAS_LIB_DIR = new File(
System.getProperty("user.home") + File.separator + ".arthas" + File.separator + "lib");
@@ -245,6 +250,12 @@ public class Bootstrap {
this.agentId = agentId;
}
@Option(longName = "stat-url")
@Description("The report stat url")
public void setStatUrl(String statUrl) {
this.statUrl = statUrl;
}
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException,
ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
@@ -481,6 +492,10 @@ public class Bootstrap {
attachArgs.add("-agent-id");
attachArgs.add(bootstrap.getAgentId());
}
if (bootstrap.getStatUrl() != null) {
attachArgs.add("-stat-url");
attachArgs.add(bootstrap.getStatUrl());
}
AnsiLog.info("Try to attach process " + pid);
AnsiLog.debug("Start arthas-core.jar args: " + attachArgs);
@@ -666,4 +681,8 @@ public class Bootstrap {
public String getAgentId() {
return agentId;
}
public String getStatUrl() {
return statUrl;
}
}
@@ -43,8 +43,10 @@ public class Arthas {
Option tunnelServer = new TypedOption<String>().setType(String.class).setShortName("tunnel-server");
Option agentId = new TypedOption<String>().setType(String.class).setShortName("agent-id");
Option statUrl = new TypedOption<String>().setType(String.class).setShortName("stat-url");
CLI cli = CLIs.create("arthas").addOption(pid).addOption(core).addOption(agent).addOption(target)
.addOption(telnetPort).addOption(httpPort).addOption(sessionTimeout).addOption(tunnelServer).addOption(agentId);
.addOption(telnetPort).addOption(httpPort).addOption(sessionTimeout).addOption(tunnelServer).addOption(agentId).addOption(statUrl);
CommandLine commandLine = cli.parse(Arrays.asList(args));
Configure configure = new Configure();
@@ -63,6 +65,7 @@ public class Arthas {
configure.setTunnelServer((String) commandLine.getOptionValue("tunnel-server"));
configure.setAgentId((String) commandLine.getOptionValue("agent-id"));
configure.setStatUrl((String) commandLine.getOptionValue("stat-url"));
return configure;
}
@@ -4,6 +4,7 @@ import com.taobao.arthas.core.server.ArthasBootstrap;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.shell.session.Session;
import com.taobao.arthas.core.util.UserStatUtil;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Summary;
import com.taobao.text.Decoration;
@@ -43,6 +44,10 @@ public class SessionCommand extends AnnotatedCommand {
}
table.row("TUNNEL_SERVER", "" + tunnelClient.getTunnelServerUrl());
}
String statUrl = UserStatUtil.getStatUrl();
if (statUrl != null) {
table.row("STAT_URL", statUrl);
}
return table;
}
}
@@ -27,6 +27,11 @@ public class Configure {
private String tunnelServer;
private String agentId;
/**
* report executed command
*/
private String statUrl;
/**
* session timeout seconds
*/
@@ -104,6 +109,14 @@ public class Configure {
this.agentId = agentId;
}
public String getStatUrl() {
return statUrl;
}
public void setStatUrl(String statUrl) {
this.statUrl = statUrl;
}
// 对象的编码解码器
private final static FeatureCodec codec = new FeatureCodec(';', '=');
@@ -148,6 +148,10 @@ public class ArthasBootstrap {
logger.info("as-server listening on network={};telnet={};http={};timeout={};", configure.getIp(),
configure.getTelnetPort(), configure.getHttpPort(), options.getConnectionTimeout());
// 异步回报启动次数
if (configure.getStatUrl() != null) {
logger.info("arthas stat url: {}", configure.getStatUrl());
}
UserStatUtil.setStatUrl(configure.getStatUrl());
UserStatUtil.arthasStart();
logger.info("as-server started in {} ms", System.currentTimeMillis() - start );
@@ -1,6 +1,7 @@
package com.taobao.arthas.core.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
@@ -20,43 +21,51 @@ public class UserStatUtil {
private static final String version = URLEncoder.encode(ArthasBanner.version().replace("\n", ""));
private static volatile String statUrl = null;
public static String getStatUrl() {
return statUrl;
}
public static void setStatUrl(String url) {
statUrl = url;
}
public static void arthasStart() {
RemoteJob job = new RemoteJob();
job.setResource("anonymousStatStart.do");
job.appendQueryData("productName", "Arthas");
job.appendQueryData("productVersion", URLEncoder.encode(ArthasBanner.version()));
job.appendQueryData("ip", ip);
job.appendQueryData("version", version);
job.appendQueryData("command", "start");
try {
executorService.execute(job);
} catch(Throwable t) {
} catch (Throwable t) {
//
}
}
public static void arthasUsage(String cmd, String detail) {
RemoteJob job = new RemoteJob();
job.setResource("nonAnonymousStat.do");
job.appendQueryData("ip", ip);
job.appendQueryData("productName", "Arthas");
job.appendQueryData("productVersion", version);
job.appendQueryData("opName", URLEncoder.encode(cmd));
job.appendQueryData("version", version);
job.appendQueryData("command", URLEncoder.encode(cmd));
if (detail != null) {
job.appendQueryData("opDetail", URLEncoder.encode(detail));
job.appendQueryData("arguments", URLEncoder.encode(detail));
}
try {
executorService.execute(job);
} catch(Throwable t) {
} catch (Throwable t) {
//
}
}
public static void arthasUsageSuccess(String cmd, List<String> args) {
StringBuilder commandString = new StringBuilder(cmd);
for (String arg: args) {
for (String arg : args) {
commandString.append(" ").append(arg);
}
UserStatUtil.arthasUsage(cmd, commandString.toString() + " --> success");
UserStatUtil.arthasUsage(cmd, commandString.toString());
}
public static void destroy() {
@@ -65,19 +74,8 @@ public class UserStatUtil {
}
static class RemoteJob implements Runnable {
// private StringBuilder link = new StringBuilder("http://arthas.io/api/");
// disable stat
private StringBuilder link = null;
private String resource;
private StringBuilder queryData = new StringBuilder();
public void setResource(String resource) {
this.resource = resource;
}
public void appendQueryData(String key, String value) {
if (key != null && value != null) {
if (queryData.length() == 0) {
@@ -90,26 +88,36 @@ public class UserStatUtil {
@Override
public void run() {
String link = statUrl;
if (link == null) {
return;
}
BufferedReader br = null;
try {
link.append(resource);
if (queryData.length() != 0) {
link.append("?").append(queryData);
link = link + "?" + queryData;
}
URL url = new URL(link.toString());
URLConnection connection = url.openConnection();
connection.setConnectTimeout(1000);
connection.setReadTimeout(1000);
connection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
StringBuilder result = new StringBuilder();
while ((line = br.readLine()) != null) {
result.append(line);
}
} catch (Exception ex) {
} catch (Throwable t) {
// ignore
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
// ignore
}
}
}
}
}
@@ -0,0 +1,37 @@
package com.alibaba.arthas.tunnel.server.app.web;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
*
* @author hengyunabc 2019-09-24
*
*/
@Controller
public class StatController {
private final static Logger logger = LoggerFactory.getLogger(StatController.class);
@RequestMapping(value = "/api/stat")
@ResponseBody
public Map<String, Object> execute(@RequestParam(value = "ip", required = true) String ip,
@RequestParam(value = "version", required = true) String version,
@RequestParam(value = "command", required = true) String command,
@RequestParam(value = "arguments", required = false, defaultValue = "") String arguments) {
logger.info("arthas stat, ip: {}, version: {}, command: {}, arguments: {}", ip, version, command, arguments);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
return result;
}
}