@ -8,10 +8,10 @@
# program : Arthas
# author : Core Engine @ Taobao.com
# date : 2020-0 4-11
# date : 2020-0 6-05
# current arthas script version
ARTHAS_SCRIPT_VERSION = 3.2.0
ARTHAS_SCRIPT_VERSION = 3.3.3
# SYNOPSIS
# rreadlink <fileOrDirPath>
@ -120,6 +120,9 @@ HEIGHT=
# arthas-client terminal width
WIDTH =
# select target process by classname or JARfilename
SELECT =
# Verbose, print debug info.
VERBOSE = false
@ -423,6 +426,7 @@ Options and Arguments:
--debug-attach Debug attach agent
--tunnel-server Remote tunnel server url
--agent-id Special agent id
--select select target process by classname or JARfilename
-c,--command <value> Command to execute, multiple commands separated
by ;
-f,--batch-file <value> The batch file to execute
@ -440,9 +444,10 @@ EXAMPLES:
./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.2.0
./as.sh --use-version 3.3.3
./as.sh --session-timeout 3600
./as.sh --attach-only
./as.sh --select arthas-demo
./as.sh --repo-mirror aliyun --use-http
WIKI:
https://alibaba.github.io/arthas
@ -470,6 +475,34 @@ find_listen_port_process()
fi
}
# Status from com.taobao.arthas.client.TelnetConsole
# Execute commands timeout
STATUS_EXEC_TIMEOUT = 100
# Execute commands error
STATUS_EXEC_ERROR = 101
# find the process pid of target telnet port
# maybe another user start an arthas server at the same port, but invisible for current user
find_listen_port_process_by_client( )
{
local arthas_lib_dir = " ${ ARTHAS_HOME } "
# http://www.inonit.com/cygwin/faq/
if [ " ${ OS_TYPE } " = "Cygwin" ] ; then
arthas_lib_dir = ` cygpath -wp " $arthas_lib_dir " `
fi
" ${ JAVA_HOME } /bin/java " ${ ARTHAS_OPTS } ${ JVM_OPTS } \
-jar " ${ arthas_lib_dir } /arthas-client.jar " \
${ TARGET_IP } \
${ TELNET_PORT } \
-c "session" \
--execution-timeout 2000 \
2>& 1
# return java process exit status code !
return $?
}
parse_arguments( )
{
POSITIONAL = ( )
@ -583,6 +616,11 @@ parse_arguments()
shift # past argument
shift # past value
; ;
--select)
SELECT = " $2 "
shift # past argument
shift # past value
; ;
-v| --verbose)
VERBOSE = true
shift # past argument
@ -634,6 +672,15 @@ parse_arguments()
fi
fi
# try to find target pid by --select option
if [ -z ${ TARGET_PID } ] && [ ${ SELECT } ] ; then
local IFS = $'\n'
CANDIDATES = ( $( call_jps | grep -v sun.tools.jps.Jps | grep " ${ SELECT } " | awk '{print $0}' ) )
if [ ${# CANDIDATES [@] } -eq 1 ] ; then
TARGET_PID = ${ CANDIDATES [0] }
fi
fi
# check pid
if [ -z ${ TARGET_PID } ] && [ ${ BATCH_MODE } = false ] ; then
# interactive mode
@ -680,9 +727,7 @@ parse_arguments()
# check the process already using telnet port if equals to target pid
if [ [ ( $telnetPortPid ) && ( $TARGET_PID != $telnetPortPid ) ] ] ; then
echo " [ERROR] Target process $TARGET_PID is not the process using port $TELNET_PORT , you will connect to an unexpected process. "
echo " [ERROR] 1. Try to restart as.sh, select process $telnetPortPid , shutdown it first with running the 'stop' command. "
echo "[ERROR] 2. Try to use different telnet port, for example: as.sh --telnet-port 9998 --http-port -1"
print_telnet_port_pid_error
exit 1
fi
if [ [ ( $httpPortPid ) && ( $TARGET_PID != $httpPortPid ) ] ] ; then
@ -779,6 +824,52 @@ sanity_check() {
fi
}
port_pid_check( ) {
if [ [ $TELNET_PORT > 0 ] ] ; then
local telnet_output
local find_process_status
# declare local var before var=$()
telnet_output = $( find_listen_port_process_by_client)
find_process_status = $?
#echo "find_process_status: $find_process_status"
#echo "telnet_output: $telnet_output"
#check return code
if [ [ $find_process_status -eq $STATUS_EXEC_TIMEOUT ] ] ; then
print_telnet_port_used_error "detection timeout"
exit 1
elif [ [ $find_process_status -eq $STATUS_EXEC_ERROR ] ] ; then
print_telnet_port_used_error "detection error"
exit 1
fi
if [ [ -n $telnet_output ] ] ; then
# check JAVA_PID
telnetPortPid = $( echo " $telnet_output " | grep JAVA_PID | awk '{ print $2 }' )
#echo "telnetPortPid: $telnetPortPid"
# check the process already using telnet port if equals to target pid
if [ [ -n $telnetPortPid && ( $TARGET_PID != $telnetPortPid ) ] ] ; then
print_telnet_port_pid_error
exit 1
fi
fi
fi
}
print_telnet_port_pid_error( ) {
echo " [ERROR] The telnet port $TELNET_PORT is used by process $telnetPortPid instead of target process $TARGET_PID , you will connect to an unexpected process. "
echo " [ERROR] 1. Try to restart as.sh, select process $telnetPortPid , shutdown it first with running the 'stop' command. "
echo " [ERROR] 2. Try to stop the existing arthas instance: java -jar arthas-client.jar 127.0.0.1 $TELNET_PORT -c \"stop\" "
echo "[ERROR] 3. Try to use different telnet port, for example: as.sh --telnet-port 9998 --http-port -1"
}
print_telnet_port_used_error( ) {
local error_msg = $1
echo " [ERROR] The telnet port $TELNET_PORT is used, but process $error_msg , you will connect to an unexpected process. "
echo "[ERROR] Try to use different telnet port, for example: as.sh --telnet-port 9998 --http-port -1"
}
# active console
# $1 : arthas_lib_dir
active_console( )
@ -880,6 +971,8 @@ main()
sanity_check
port_pid_check
echo "Calculating attach execution time..."
time ( attach_jvm " ${ ARTHAS_HOME } " || exit 1)
@ -896,4 +989,4 @@ main()
main " ${ @ } "
main " ${ @ } "