mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
support stat data report. #848
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user