mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
support config appName;tunnel client/server support add appName prefix for agentId. #1562
This commit is contained in:
@@ -139,6 +139,9 @@ AGENT_ID=
|
||||
# stat report url
|
||||
STAT_URL=
|
||||
|
||||
# app name
|
||||
APP_NAME=
|
||||
|
||||
############ Command Arguments ############
|
||||
|
||||
# if arguments contains -c/--command or -f/--batch-file, BATCH_MODE will be true
|
||||
@@ -393,6 +396,7 @@ Usage:
|
||||
$0 [-h] [--target-ip <value>] [--telnet-port <value>]
|
||||
[--http-port <value>] [--session-timeout <value>] [--arthas-home <value>]
|
||||
[--tunnel-server <value>] [--agent-id <value>] [--stat-url <value>]
|
||||
[--app-name <value>]
|
||||
[--use-version <value>] [--repo-mirror <value>] [--versions] [--use-http]
|
||||
[--attach-only] [-c <value>] [-f <value>] [-v] [pid]
|
||||
|
||||
@@ -412,6 +416,7 @@ Options and Arguments:
|
||||
--debug-attach Debug attach agent
|
||||
--tunnel-server Remote tunnel server url
|
||||
--agent-id Special agent id
|
||||
--app-name Special app name
|
||||
--select select target process by classname or JARfilename
|
||||
-c,--command <value> Command to execute, multiple commands separated
|
||||
by ;
|
||||
@@ -425,7 +430,7 @@ EXAMPLES:
|
||||
./as.sh <pid>
|
||||
./as.sh --target-ip 0.0.0.0
|
||||
./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' --app-name demoapp
|
||||
./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>
|
||||
@@ -567,6 +572,11 @@ parse_arguments()
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--app-name)
|
||||
APP_NAME="$2"
|
||||
shift # past argument
|
||||
shift # past value
|
||||
;;
|
||||
--use-http)
|
||||
USE_HTTP=true
|
||||
shift # past argument
|
||||
@@ -759,6 +769,11 @@ attach_jvm()
|
||||
tempArgs+=("${STAT_URL}")
|
||||
fi
|
||||
|
||||
if [ "${APP_NAME}" ]; then
|
||||
tempArgs+=("-app-name")
|
||||
tempArgs+=("${APP_NAME}")
|
||||
fi
|
||||
|
||||
"${java_command[@]}" \
|
||||
${ARTHAS_OPTS} ${JVM_OPTS} \
|
||||
-jar "${arthas_lib_dir}/arthas-core.jar" \
|
||||
|
||||
@@ -47,7 +47,7 @@ import static com.taobao.arthas.boot.ProcessUtils.STATUS_EXEC_TIMEOUT;
|
||||
@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' --app-name demoapp\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"
|
||||
@@ -118,6 +118,8 @@ public class Bootstrap {
|
||||
private String tunnelServer;
|
||||
private String agentId;
|
||||
|
||||
private String appName;
|
||||
|
||||
private String statUrl;
|
||||
|
||||
private String select;
|
||||
@@ -258,6 +260,12 @@ public class Bootstrap {
|
||||
this.agentId = agentId;
|
||||
}
|
||||
|
||||
@Option(longName = "app-name")
|
||||
@Description("The app name")
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
@Option(longName = "stat-url")
|
||||
@Description("The report stat url")
|
||||
public void setStatUrl(String statUrl) {
|
||||
@@ -760,6 +768,10 @@ public class Bootstrap {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public String getStatUrl() {
|
||||
return statUrl;
|
||||
}
|
||||
|
||||
@@ -17,4 +17,9 @@ public class ArthasConstants {
|
||||
public static int MAX_HTTP_CONTENT_LENGTH = 1024 * 1024 * 8;
|
||||
|
||||
public static final String ARTHAS_OUTPUT = "arthas-output";
|
||||
|
||||
public static final String APP_NAME = "app-name";
|
||||
|
||||
public static final String PROJECT_NAME = "project.name";
|
||||
public static final String SPRING_APPLICATION_NAME = "spring.application.name";
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.taobao.arthas.core;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.taobao.arthas.common.AnsiLog;
|
||||
import com.taobao.arthas.common.ArthasConstants;
|
||||
import com.taobao.arthas.common.JavaVersionUtils;
|
||||
import com.taobao.arthas.core.config.Configure;
|
||||
import com.taobao.middleware.cli.CLI;
|
||||
@@ -42,11 +43,12 @@ 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 appName = new TypedOption<String>().setType(String.class).setShortName(ArthasConstants.APP_NAME);
|
||||
|
||||
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(statUrl);
|
||||
.addOption(telnetPort).addOption(httpPort).addOption(sessionTimeout).addOption(tunnelServer).addOption(agentId).addOption(appName).addOption(statUrl);
|
||||
CommandLine commandLine = cli.parse(Arrays.asList(args));
|
||||
|
||||
Configure configure = new Configure();
|
||||
@@ -66,6 +68,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"));
|
||||
configure.setAppName((String) commandLine.getOptionValue(ArthasConstants.APP_NAME));
|
||||
return configure;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,14 @@ public class Configure {
|
||||
private String tunnelServer;
|
||||
private String agentId;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 1. 如果显式传入 arthas.agentId ,则直接使用
|
||||
* 2. 如果用户没有指定,则自动尝试在查找应用的 appname,加为前缀,比如 system properties设置 project.name是 demo,则
|
||||
* 生成的 agentId是 demo-xxxx
|
||||
* </pre>
|
||||
*/
|
||||
private String appName;
|
||||
/**
|
||||
* report executed command
|
||||
*/
|
||||
@@ -118,6 +126,14 @@ public class Configure {
|
||||
this.statUrl = statUrl;
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化成字符串
|
||||
*
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.alibaba.arthas.deps.org.slf4j.Logger;
|
||||
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
|
||||
import com.alibaba.arthas.tunnel.client.TunnelClient;
|
||||
import com.taobao.arthas.common.AnsiLog;
|
||||
import com.taobao.arthas.common.ArthasConstants;
|
||||
import com.taobao.arthas.common.PidUtils;
|
||||
import com.taobao.arthas.common.SocketUtils;
|
||||
import com.taobao.arthas.core.advisor.Enhancer;
|
||||
@@ -294,11 +295,17 @@ public class ArthasBootstrap {
|
||||
configure.setHttpPort(newHttpPort);
|
||||
logger().info("generate random http port: " + newHttpPort);
|
||||
}
|
||||
// try to find appName
|
||||
if (configure.getAppName() == null) {
|
||||
configure.setAppName(System.getProperty(ArthasConstants.PROJECT_NAME,
|
||||
System.getProperty(ArthasConstants.SPRING_APPLICATION_NAME, null)));
|
||||
}
|
||||
|
||||
String agentId = null;
|
||||
try {
|
||||
if (configure.getTunnelServer() != null) {
|
||||
tunnelClient = new TunnelClient();
|
||||
tunnelClient.setAppName(configure.getAppName());
|
||||
tunnelClient.setId(configure.getAgentId());
|
||||
tunnelClient.setTunnelServerUrl(configure.getTunnelServer());
|
||||
tunnelClient.setVersion(ArthasBanner.version());
|
||||
|
||||
@@ -52,6 +52,7 @@ public class TunnelClient {
|
||||
// two thread because need to reconnect. #1284
|
||||
private EventLoopGroup eventLoopGroup = new NioEventLoopGroup(2, new DefaultThreadFactory("arthas-TunnelClient", true));
|
||||
|
||||
private String appName;
|
||||
// agent id, generated by tunnel server. if reconnect, reuse the id
|
||||
volatile private String id;
|
||||
|
||||
@@ -68,6 +69,9 @@ public class TunnelClient {
|
||||
QueryStringEncoder queryEncoder = new QueryStringEncoder(this.tunnelServerUrl);
|
||||
queryEncoder.addParam(URIConstans.METHOD, MethodConstants.AGENT_REGISTER);
|
||||
queryEncoder.addParam(URIConstans.ARTHAS_VERSION, this.version);
|
||||
if (appName != null) {
|
||||
queryEncoder.addParam(URIConstans.APP_NAME, appName);
|
||||
}
|
||||
if (id != null) {
|
||||
queryEncoder.addParam(URIConstans.ID, id);
|
||||
}
|
||||
@@ -178,4 +182,12 @@ public class TunnelClient {
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,6 @@ public class URIConstans {
|
||||
public static final String PROXY_RESPONSE_DATA = "responseData";
|
||||
|
||||
public static final String ARTHAS_VERSION = "arthasVersion";
|
||||
|
||||
public static final String APP_NAME = "appName";
|
||||
}
|
||||
|
||||
+20
-5
@@ -8,6 +8,7 @@ import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -206,17 +207,31 @@ public class TunnelSocketFrameHandler extends SimpleChannelInboundHandler<WebSoc
|
||||
}
|
||||
|
||||
private void agentRegister(ChannelHandlerContext ctx, HandshakeComplete handshake, String requestUri) throws URISyntaxException {
|
||||
// generate a random agent id
|
||||
String id = RandomStringUtils.random(20, true, true).toUpperCase();
|
||||
|
||||
QueryStringDecoder queryDecoder = new QueryStringDecoder(requestUri);
|
||||
List<String> idList = queryDecoder.parameters().get("id");
|
||||
Map<String, List<String>> parameters = queryDecoder.parameters();
|
||||
|
||||
String appName = null;
|
||||
List<String> appNameList = parameters.get(URIConstans.APP_NAME);
|
||||
if (appNameList != null && !appNameList.isEmpty()) {
|
||||
appName = appNameList.get(0);
|
||||
}
|
||||
|
||||
// generate a random agent id
|
||||
String id = null;
|
||||
if (appName != null) {
|
||||
// 如果有传 app name,则生成带 app name前缀的id,方便管理
|
||||
id = appName + "_" + RandomStringUtils.random(20, true, true).toUpperCase();
|
||||
} else {
|
||||
id = RandomStringUtils.random(20, true, true).toUpperCase();
|
||||
}
|
||||
// agent传过来,则优先用 agent的
|
||||
List<String> idList = parameters.get(URIConstans.ID);
|
||||
if (idList != null && !idList.isEmpty()) {
|
||||
id = idList.get(0);
|
||||
}
|
||||
|
||||
String arthasVersion = null;
|
||||
List<String> arthasVersionList = queryDecoder.parameters().get(URIConstans.ARTHAS_VERSION);
|
||||
List<String> arthasVersionList = parameters.get(URIConstans.ARTHAS_VERSION);
|
||||
if (arthasVersionList != null && !arthasVersionList.isEmpty()) {
|
||||
arthasVersion = arthasVersionList.get(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user