Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Administrator
Arthas
Commits
5d7c4150
Commit
5d7c4150
authored
Dec 21, 2023
by
shengnan hu
Browse files
init
parents
Pipeline
#4720
failed with stage
in 31 seconds
Changes
457
Pipelines
621
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1966 additions
and
0 deletions
+1966
-0
core/src/main/java/com/taobao/arthas/core/command/model/ThreadModel.java
...ava/com/taobao/arthas/core/command/model/ThreadModel.java
+101
-0
core/src/main/java/com/taobao/arthas/core/command/model/ThreadNode.java
...java/com/taobao/arthas/core/command/model/ThreadNode.java
+99
-0
core/src/main/java/com/taobao/arthas/core/command/model/ThreadVO.java
...n/java/com/taobao/arthas/core/command/model/ThreadVO.java
+122
-0
core/src/main/java/com/taobao/arthas/core/command/model/ThrowNode.java
.../java/com/taobao/arthas/core/command/model/ThrowNode.java
+40
-0
core/src/main/java/com/taobao/arthas/core/command/model/TimeFragmentVO.java
.../com/taobao/arthas/core/command/model/TimeFragmentVO.java
+123
-0
core/src/main/java/com/taobao/arthas/core/command/model/TimeTunnelModel.java
...com/taobao/arthas/core/command/model/TimeTunnelModel.java
+122
-0
core/src/main/java/com/taobao/arthas/core/command/model/TomcatInfoVO.java
...va/com/taobao/arthas/core/command/model/TomcatInfoVO.java
+129
-0
core/src/main/java/com/taobao/arthas/core/command/model/TraceModel.java
...java/com/taobao/arthas/core/command/model/TraceModel.java
+39
-0
core/src/main/java/com/taobao/arthas/core/command/model/TraceNode.java
.../java/com/taobao/arthas/core/command/model/TraceNode.java
+79
-0
core/src/main/java/com/taobao/arthas/core/command/model/TraceTree.java
.../java/com/taobao/arthas/core/command/model/TraceTree.java
+132
-0
core/src/main/java/com/taobao/arthas/core/command/model/VMOptionModel.java
...a/com/taobao/arthas/core/command/model/VMOptionModel.java
+47
-0
core/src/main/java/com/taobao/arthas/core/command/model/VersionModel.java
...va/com/taobao/arthas/core/command/model/VersionModel.java
+20
-0
core/src/main/java/com/taobao/arthas/core/command/model/VmToolModel.java
...ava/com/taobao/arthas/core/command/model/VmToolModel.java
+48
-0
core/src/main/java/com/taobao/arthas/core/command/model/WatchModel.java
...java/com/taobao/arthas/core/command/model/WatchModel.java
+84
-0
core/src/main/java/com/taobao/arthas/core/command/model/WelcomeModel.java
...va/com/taobao/arthas/core/command/model/WelcomeModel.java
+70
-0
core/src/main/java/com/taobao/arthas/core/command/monitor200/AbstractTraceAdviceListener.java
.../core/command/monitor200/AbstractTraceAdviceListener.java
+115
-0
core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardCommand.java
...obao/arthas/core/command/monitor200/DashboardCommand.java
+272
-0
core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardInterruptHandler.java
...as/core/command/monitor200/DashboardInterruptHandler.java
+25
-0
core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java
...aobao/arthas/core/command/monitor200/EnhancerCommand.java
+223
-0
core/src/main/java/com/taobao/arthas/core/command/monitor200/GroovyAdviceListener.java
.../arthas/core/command/monitor200/GroovyAdviceListener.java
+76
-0
No files found.
Too many changes to show.
To preserve performance only
457 of 457+
files are displayed.
Plain diff
Email patch
core/src/main/java/com/taobao/arthas/core/command/model/ThreadModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.lang.management.ThreadInfo
;
import
java.util.List
;
import
java.util.Map
;
/**
* Model of 'thread' command
*
* @author gongdewei 2020/4/26
*/
public
class
ThreadModel
extends
ResultModel
{
//single thread: thread 12
private
ThreadInfo
threadInfo
;
//thread -b
private
BlockingLockInfo
blockingLockInfo
;
//thread -n 5
private
List
<
BusyThreadInfo
>
busyThreads
;
//thread stats
private
List
<
ThreadVO
>
threadStats
;
private
Map
<
Thread
.
State
,
Integer
>
threadStateCount
;
private
boolean
all
;
public
ThreadModel
()
{
}
public
ThreadModel
(
ThreadInfo
threadInfo
)
{
this
.
threadInfo
=
threadInfo
;
}
public
ThreadModel
(
BlockingLockInfo
blockingLockInfo
)
{
this
.
blockingLockInfo
=
blockingLockInfo
;
}
public
ThreadModel
(
List
<
BusyThreadInfo
>
busyThreads
)
{
this
.
busyThreads
=
busyThreads
;
}
public
ThreadModel
(
List
<
ThreadVO
>
threadStats
,
Map
<
Thread
.
State
,
Integer
>
threadStateCount
,
boolean
all
)
{
this
.
threadStats
=
threadStats
;
this
.
threadStateCount
=
threadStateCount
;
this
.
all
=
all
;
}
@Override
public
String
getType
()
{
return
"thread"
;
}
public
ThreadInfo
getThreadInfo
()
{
return
threadInfo
;
}
public
void
setThreadInfo
(
ThreadInfo
threadInfo
)
{
this
.
threadInfo
=
threadInfo
;
}
public
BlockingLockInfo
getBlockingLockInfo
()
{
return
blockingLockInfo
;
}
public
void
setBlockingLockInfo
(
BlockingLockInfo
blockingLockInfo
)
{
this
.
blockingLockInfo
=
blockingLockInfo
;
}
public
List
<
BusyThreadInfo
>
getBusyThreads
()
{
return
busyThreads
;
}
public
void
setBusyThreads
(
List
<
BusyThreadInfo
>
busyThreads
)
{
this
.
busyThreads
=
busyThreads
;
}
public
List
<
ThreadVO
>
getThreadStats
()
{
return
threadStats
;
}
public
void
setThreadStats
(
List
<
ThreadVO
>
threadStats
)
{
this
.
threadStats
=
threadStats
;
}
public
Map
<
Thread
.
State
,
Integer
>
getThreadStateCount
()
{
return
threadStateCount
;
}
public
void
setThreadStateCount
(
Map
<
Thread
.
State
,
Integer
>
threadStateCount
)
{
this
.
threadStateCount
=
threadStateCount
;
}
public
boolean
isAll
()
{
return
all
;
}
public
void
setAll
(
boolean
all
)
{
this
.
all
=
all
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/ThreadNode.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.Date
;
/**
* Thread root node of TraceCommand
* @author gongdewei 2020/4/29
*/
public
class
ThreadNode
extends
TraceNode
{
private
String
threadName
;
private
long
threadId
;
private
boolean
daemon
;
private
int
priority
;
private
String
classloader
;
private
Date
timestamp
;
private
String
traceId
;
private
String
rpcId
;
public
ThreadNode
()
{
super
(
"thread"
);
timestamp
=
new
Date
();
}
public
ThreadNode
(
String
threadName
,
long
threadId
,
boolean
daemon
,
int
priority
,
String
classloader
)
{
super
(
"thread"
);
this
.
threadName
=
threadName
;
this
.
threadId
=
threadId
;
this
.
daemon
=
daemon
;
this
.
priority
=
priority
;
this
.
classloader
=
classloader
;
timestamp
=
new
Date
();
}
public
String
getThreadName
()
{
return
threadName
;
}
public
void
setThreadName
(
String
threadName
)
{
this
.
threadName
=
threadName
;
}
public
long
getThreadId
()
{
return
threadId
;
}
public
void
setThreadId
(
long
threadId
)
{
this
.
threadId
=
threadId
;
}
public
boolean
isDaemon
()
{
return
daemon
;
}
public
void
setDaemon
(
boolean
daemon
)
{
this
.
daemon
=
daemon
;
}
public
int
getPriority
()
{
return
priority
;
}
public
void
setPriority
(
int
priority
)
{
this
.
priority
=
priority
;
}
public
String
getClassloader
()
{
return
classloader
;
}
public
void
setClassloader
(
String
classloader
)
{
this
.
classloader
=
classloader
;
}
public
Date
getTimestamp
()
{
return
timestamp
;
}
public
void
setTimestamp
(
Date
timestamp
)
{
this
.
timestamp
=
timestamp
;
}
public
String
getTraceId
()
{
return
traceId
;
}
public
void
setTraceId
(
String
traceId
)
{
this
.
traceId
=
traceId
;
}
public
String
getRpcId
()
{
return
rpcId
;
}
public
void
setRpcId
(
String
rpcId
)
{
this
.
rpcId
=
rpcId
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/ThreadVO.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.lang.Thread.State
;
/**
* Thread VO of 'dashboard' and 'thread' command
*
* @author gongdewei 2020/4/22
*/
public
class
ThreadVO
{
private
long
id
;
private
String
name
;
private
String
group
;
private
int
priority
;
private
State
state
;
private
double
cpu
;
private
long
deltaTime
;
private
long
time
;
private
boolean
interrupted
;
private
boolean
daemon
;
public
ThreadVO
()
{
}
public
long
getId
()
{
return
id
;
}
public
void
setId
(
long
id
)
{
this
.
id
=
id
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getGroup
()
{
return
group
;
}
public
void
setGroup
(
String
group
)
{
this
.
group
=
group
;
}
public
int
getPriority
()
{
return
priority
;
}
public
void
setPriority
(
int
priority
)
{
this
.
priority
=
priority
;
}
public
State
getState
()
{
return
state
;
}
public
void
setState
(
State
state
)
{
this
.
state
=
state
;
}
public
double
getCpu
()
{
return
cpu
;
}
public
void
setCpu
(
double
cpu
)
{
this
.
cpu
=
cpu
;
}
public
long
getDeltaTime
()
{
return
deltaTime
;
}
public
void
setDeltaTime
(
long
deltaTime
)
{
this
.
deltaTime
=
deltaTime
;
}
public
long
getTime
()
{
return
time
;
}
public
void
setTime
(
long
time
)
{
this
.
time
=
time
;
}
public
boolean
isInterrupted
()
{
return
interrupted
;
}
public
void
setInterrupted
(
boolean
interrupted
)
{
this
.
interrupted
=
interrupted
;
}
public
boolean
isDaemon
()
{
return
daemon
;
}
public
void
setDaemon
(
boolean
daemon
)
{
this
.
daemon
=
daemon
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
ThreadVO
threadVO
=
(
ThreadVO
)
o
;
if
(
id
!=
threadVO
.
id
)
return
false
;
return
name
!=
null
?
name
.
equals
(
threadVO
.
name
)
:
threadVO
.
name
==
null
;
}
@Override
public
int
hashCode
()
{
int
result
=
(
int
)
(
id
^
(
id
>>>
32
));
result
=
31
*
result
+
(
name
!=
null
?
name
.
hashCode
()
:
0
);
return
result
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/ThrowNode.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
/**
* Throw exception info node of TraceCommand
* @author gongdewei 2020/7/21
*/
public
class
ThrowNode
extends
TraceNode
{
private
String
exception
;
private
String
message
;
private
int
lineNumber
;
public
ThrowNode
()
{
super
(
"throw"
);
}
public
String
getException
()
{
return
exception
;
}
public
void
setException
(
String
exception
)
{
this
.
exception
=
exception
;
}
public
int
getLineNumber
()
{
return
lineNumber
;
}
public
void
setLineNumber
(
int
lineNumber
)
{
this
.
lineNumber
=
lineNumber
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/TimeFragmentVO.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.Date
;
/**
* VO for TimeFragment
* @author gongdewei 2020/4/27
*/
public
class
TimeFragmentVO
{
private
Integer
index
;
private
Date
timestamp
;
private
double
cost
;
private
boolean
isReturn
;
private
boolean
isThrow
;
private
String
object
;
private
String
className
;
private
String
methodName
;
private
ObjectVO
[]
params
;
private
ObjectVO
returnObj
;
private
ObjectVO
throwExp
;
public
TimeFragmentVO
()
{
}
public
Integer
getIndex
()
{
return
index
;
}
public
TimeFragmentVO
setIndex
(
Integer
index
)
{
this
.
index
=
index
;
return
this
;
}
public
Date
getTimestamp
()
{
return
timestamp
;
}
public
TimeFragmentVO
setTimestamp
(
Date
timestamp
)
{
this
.
timestamp
=
timestamp
;
return
this
;
}
public
double
getCost
()
{
return
cost
;
}
public
TimeFragmentVO
setCost
(
double
cost
)
{
this
.
cost
=
cost
;
return
this
;
}
public
boolean
isReturn
()
{
return
isReturn
;
}
public
TimeFragmentVO
setReturn
(
boolean
aReturn
)
{
isReturn
=
aReturn
;
return
this
;
}
public
boolean
isThrow
()
{
return
isThrow
;
}
public
TimeFragmentVO
setThrow
(
boolean
aThrow
)
{
isThrow
=
aThrow
;
return
this
;
}
public
String
getObject
()
{
return
object
;
}
public
TimeFragmentVO
setObject
(
String
object
)
{
this
.
object
=
object
;
return
this
;
}
public
String
getClassName
()
{
return
className
;
}
public
TimeFragmentVO
setClassName
(
String
className
)
{
this
.
className
=
className
;
return
this
;
}
public
String
getMethodName
()
{
return
methodName
;
}
public
TimeFragmentVO
setMethodName
(
String
methodName
)
{
this
.
methodName
=
methodName
;
return
this
;
}
public
ObjectVO
[]
getParams
()
{
return
params
;
}
public
TimeFragmentVO
setParams
(
ObjectVO
[]
params
)
{
this
.
params
=
params
;
return
this
;
}
public
ObjectVO
getReturnObj
()
{
return
returnObj
;
}
public
TimeFragmentVO
setReturnObj
(
ObjectVO
returnObj
)
{
this
.
returnObj
=
returnObj
;
return
this
;
}
public
ObjectVO
getThrowExp
()
{
return
throwExp
;
}
public
TimeFragmentVO
setThrowExp
(
ObjectVO
throwExp
)
{
this
.
throwExp
=
throwExp
;
return
this
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/TimeTunnelModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.List
;
import
java.util.Map
;
/**
* Data model of TimeTunnelCommand
* @author gongdewei 2020/4/27
*/
public
class
TimeTunnelModel
extends
ResultModel
{
//查看列表
private
List
<
TimeFragmentVO
>
timeFragmentList
;
//是否为第一次输出(需要加表头)
private
Boolean
isFirst
;
//查看单条记录
private
TimeFragmentVO
timeFragment
;
//重放执行的结果
private
TimeFragmentVO
replayResult
;
//重放执行的次数
private
Integer
replayNo
;
private
ObjectVO
watchValue
;
//search: tt -s {} -w {}
private
Map
<
Integer
,
ObjectVO
>
watchResults
;
private
Integer
expand
;
private
Integer
sizeLimit
;
@Override
public
String
getType
()
{
return
"tt"
;
}
public
List
<
TimeFragmentVO
>
getTimeFragmentList
()
{
return
timeFragmentList
;
}
public
TimeTunnelModel
setTimeFragmentList
(
List
<
TimeFragmentVO
>
timeFragmentList
)
{
this
.
timeFragmentList
=
timeFragmentList
;
return
this
;
}
public
TimeFragmentVO
getTimeFragment
()
{
return
timeFragment
;
}
public
TimeTunnelModel
setTimeFragment
(
TimeFragmentVO
timeFragment
)
{
this
.
timeFragment
=
timeFragment
;
return
this
;
}
public
Integer
getExpand
()
{
return
expand
;
}
public
TimeTunnelModel
setExpand
(
Integer
expand
)
{
this
.
expand
=
expand
;
return
this
;
}
public
Integer
getSizeLimit
()
{
return
sizeLimit
;
}
public
TimeTunnelModel
setSizeLimit
(
Integer
sizeLimit
)
{
this
.
sizeLimit
=
sizeLimit
;
return
this
;
}
public
ObjectVO
getWatchValue
()
{
return
watchValue
;
}
public
TimeTunnelModel
setWatchValue
(
ObjectVO
watchValue
)
{
this
.
watchValue
=
watchValue
;
return
this
;
}
public
Map
<
Integer
,
ObjectVO
>
getWatchResults
()
{
return
watchResults
;
}
public
TimeTunnelModel
setWatchResults
(
Map
<
Integer
,
ObjectVO
>
watchResults
)
{
this
.
watchResults
=
watchResults
;
return
this
;
}
public
TimeFragmentVO
getReplayResult
()
{
return
replayResult
;
}
public
TimeTunnelModel
setReplayResult
(
TimeFragmentVO
replayResult
)
{
this
.
replayResult
=
replayResult
;
return
this
;
}
public
Integer
getReplayNo
()
{
return
replayNo
;
}
public
TimeTunnelModel
setReplayNo
(
Integer
replayNo
)
{
this
.
replayNo
=
replayNo
;
return
this
;
}
public
Boolean
getFirst
()
{
return
isFirst
;
}
public
TimeTunnelModel
setFirst
(
Boolean
first
)
{
isFirst
=
first
;
return
this
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/TomcatInfoVO.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.List
;
/**
* Tomcat info of 'dashboard' command
*
* @author gongdewei 2020/4/23
*/
public
class
TomcatInfoVO
{
private
List
<
ConnectorStats
>
connectorStats
;
private
List
<
ThreadPool
>
threadPools
;
public
TomcatInfoVO
()
{
}
public
List
<
ConnectorStats
>
getConnectorStats
()
{
return
connectorStats
;
}
public
void
setConnectorStats
(
List
<
ConnectorStats
>
connectorStats
)
{
this
.
connectorStats
=
connectorStats
;
}
public
List
<
ThreadPool
>
getThreadPools
()
{
return
threadPools
;
}
public
void
setThreadPools
(
List
<
ThreadPool
>
threadPools
)
{
this
.
threadPools
=
threadPools
;
}
public
static
class
ConnectorStats
{
private
String
name
;
private
double
qps
;
private
double
rt
;
private
double
error
;
private
long
received
;
private
long
sent
;
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
double
getQps
()
{
return
qps
;
}
public
void
setQps
(
double
qps
)
{
this
.
qps
=
qps
;
}
public
double
getRt
()
{
return
rt
;
}
public
void
setRt
(
double
rt
)
{
this
.
rt
=
rt
;
}
public
double
getError
()
{
return
error
;
}
public
void
setError
(
double
error
)
{
this
.
error
=
error
;
}
public
long
getReceived
()
{
return
received
;
}
public
void
setReceived
(
long
received
)
{
this
.
received
=
received
;
}
public
long
getSent
()
{
return
sent
;
}
public
void
setSent
(
long
sent
)
{
this
.
sent
=
sent
;
}
}
public
static
class
ThreadPool
{
private
String
name
;
private
long
busy
;
private
long
total
;
public
ThreadPool
()
{
}
public
ThreadPool
(
String
name
,
long
busy
,
long
total
)
{
this
.
name
=
name
;
this
.
busy
=
busy
;
this
.
total
=
total
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
long
getBusy
()
{
return
busy
;
}
public
void
setBusy
(
long
busy
)
{
this
.
busy
=
busy
;
}
public
long
getTotal
()
{
return
total
;
}
public
void
setTotal
(
long
total
)
{
this
.
total
=
total
;
}
}
}
core/src/main/java/com/taobao/arthas/core/command/model/TraceModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
/**
* Data model of TraceCommand
* @author gongdewei 2020/4/29
*/
public
class
TraceModel
extends
ResultModel
{
private
TraceNode
root
;
private
int
nodeCount
;
public
TraceModel
()
{
}
public
TraceModel
(
TraceNode
root
,
int
nodeCount
)
{
this
.
root
=
root
;
this
.
nodeCount
=
nodeCount
;
}
@Override
public
String
getType
()
{
return
"trace"
;
}
public
TraceNode
getRoot
()
{
return
root
;
}
public
void
setRoot
(
TraceNode
root
)
{
this
.
root
=
root
;
}
public
int
getNodeCount
()
{
return
nodeCount
;
}
public
void
setNodeCount
(
int
nodeCount
)
{
this
.
nodeCount
=
nodeCount
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/TraceNode.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* Abstract Node of TraceCommand
* @author gongdewei 2020/4/28
*/
public
abstract
class
TraceNode
{
protected
TraceNode
parent
;
protected
List
<
TraceNode
>
children
;
/**
* node type: method,
*/
private
String
type
;
/**
* 备注
*/
private
String
mark
;
/**
* TODO marks数量的作用?是否可以去掉
*/
private
int
marks
=
0
;
public
TraceNode
(
String
type
)
{
this
.
type
=
type
;
}
public
void
addChild
(
TraceNode
child
)
{
if
(
children
==
null
)
{
children
=
new
ArrayList
<
TraceNode
>();
}
this
.
children
.
add
(
child
);
child
.
setParent
(
this
);
}
public
void
setMark
(
String
mark
)
{
this
.
mark
=
mark
;
marks
++;
}
public
String
getMark
()
{
return
mark
;
}
public
Integer
marks
()
{
return
marks
;
}
public
void
begin
()
{
}
public
void
end
()
{
}
public
String
getType
()
{
return
type
;
}
public
void
setType
(
String
type
)
{
this
.
type
=
type
;
}
public
TraceNode
parent
()
{
return
parent
;
}
public
void
setParent
(
TraceNode
parent
)
{
this
.
parent
=
parent
;
}
public
List
<
TraceNode
>
getChildren
()
{
return
children
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/TraceTree.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
com.taobao.arthas.core.util.StringUtils
;
import
java.util.List
;
/**
* Tree model of TraceCommand
* @author gongdewei 2020/4/28
*/
public
class
TraceTree
{
private
TraceNode
root
;
private
TraceNode
current
;
private
int
nodeCount
=
0
;
public
TraceTree
(
ThreadNode
root
)
{
this
.
root
=
root
;
this
.
current
=
root
;
}
/**
* Begin a new method call
* @param className className of method
* @param methodName method name of the call
* @param lineNumber line number of invoke point
* @param isInvoking Whether to invoke this method in other classes
*/
public
void
begin
(
String
className
,
String
methodName
,
int
lineNumber
,
boolean
isInvoking
)
{
TraceNode
child
=
findChild
(
current
,
className
,
methodName
,
lineNumber
);
if
(
child
==
null
)
{
child
=
new
MethodNode
(
className
,
methodName
,
lineNumber
,
isInvoking
);
current
.
addChild
(
child
);
}
child
.
begin
();
current
=
child
;
nodeCount
+=
1
;
}
private
TraceNode
findChild
(
TraceNode
node
,
String
className
,
String
methodName
,
int
lineNumber
)
{
List
<
TraceNode
>
childList
=
node
.
getChildren
();
if
(
childList
!=
null
)
{
//less memory than foreach/iterator
for
(
int
i
=
0
;
i
<
childList
.
size
();
i
++)
{
TraceNode
child
=
childList
.
get
(
i
);
if
(
matchNode
(
child
,
className
,
methodName
,
lineNumber
))
{
return
child
;
}
}
}
return
null
;
}
private
boolean
matchNode
(
TraceNode
node
,
String
className
,
String
methodName
,
int
lineNumber
)
{
if
(
node
instanceof
MethodNode
)
{
MethodNode
methodNode
=
(
MethodNode
)
node
;
if
(
lineNumber
!=
methodNode
.
getLineNumber
())
return
false
;
if
(
className
!=
null
?
!
className
.
equals
(
methodNode
.
getClassName
())
:
methodNode
.
getClassName
()
!=
null
)
return
false
;
return
methodName
!=
null
?
methodName
.
equals
(
methodNode
.
getMethodName
())
:
methodNode
.
getMethodName
()
==
null
;
}
return
false
;
}
public
void
end
()
{
current
.
end
();
if
(
current
.
parent
()
!=
null
)
{
//TODO 为什么会到达这里? 调用end次数比begin多?
current
=
current
.
parent
();
}
}
public
void
end
(
Throwable
throwable
,
int
lineNumber
)
{
ThrowNode
throwNode
=
new
ThrowNode
();
throwNode
.
setException
(
throwable
.
getClass
().
getName
());
throwNode
.
setMessage
(
throwable
.
getMessage
());
throwNode
.
setLineNumber
(
lineNumber
);
current
.
addChild
(
throwNode
);
this
.
end
(
true
);
}
public
void
end
(
boolean
isThrow
)
{
if
(
isThrow
)
{
current
.
setMark
(
"throws Exception"
);
if
(
current
instanceof
MethodNode
)
{
MethodNode
methodNode
=
(
MethodNode
)
current
;
methodNode
.
setThrow
(
true
);
}
}
this
.
end
();
}
/**
* 修整树结点
*/
public
void
trim
()
{
this
.
normalizeClassName
(
root
);
}
/**
* 转换标准类名,放在trace结束后统一转换,减少重复操作
* @param node
*/
private
void
normalizeClassName
(
TraceNode
node
)
{
if
(
node
instanceof
MethodNode
)
{
MethodNode
methodNode
=
(
MethodNode
)
node
;
String
nodeClassName
=
methodNode
.
getClassName
();
String
normalizeClassName
=
StringUtils
.
normalizeClassName
(
nodeClassName
);
methodNode
.
setClassName
(
normalizeClassName
);
}
List
<
TraceNode
>
children
=
node
.
getChildren
();
if
(
children
!=
null
)
{
//less memory fragment than foreach
for
(
int
i
=
0
;
i
<
children
.
size
();
i
++)
{
TraceNode
child
=
children
.
get
(
i
);
normalizeClassName
(
child
);
}
}
}
public
TraceNode
getRoot
()
{
return
root
;
}
public
TraceNode
current
()
{
return
current
;
}
public
int
getNodeCount
()
{
return
nodeCount
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/VMOptionModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
com.sun.management.VMOption
;
import
java.util.List
;
/**
* @author gongdewei 2020/4/15
*/
public
class
VMOptionModel
extends
ResultModel
{
private
List
<
VMOption
>
vmOptions
;
private
ChangeResultVO
changeResult
;
public
VMOptionModel
()
{
}
public
VMOptionModel
(
List
<
VMOption
>
vmOptions
)
{
this
.
vmOptions
=
vmOptions
;
}
public
VMOptionModel
(
ChangeResultVO
changeResult
)
{
this
.
changeResult
=
changeResult
;
}
@Override
public
String
getType
()
{
return
"vmoption"
;
}
public
List
<
VMOption
>
getVmOptions
()
{
return
vmOptions
;
}
public
void
setVmOptions
(
List
<
VMOption
>
vmOptions
)
{
this
.
vmOptions
=
vmOptions
;
}
public
ChangeResultVO
getChangeResult
()
{
return
changeResult
;
}
public
void
setChangeResult
(
ChangeResultVO
changeResult
)
{
this
.
changeResult
=
changeResult
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/VersionModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
public
class
VersionModel
extends
ResultModel
{
private
String
version
;
@Override
public
String
getType
()
{
return
"version"
;
}
public
String
getVersion
()
{
return
version
;
}
public
void
setVersion
(
String
version
)
{
this
.
version
=
version
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/VmToolModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.Collection
;
/**
*
* @author hengyunabc 2022-04-24
*
*/
public
class
VmToolModel
extends
ResultModel
{
private
ObjectVO
value
;
private
Collection
<
ClassLoaderVO
>
matchedClassLoaders
;
private
String
classLoaderClass
;
@Override
public
String
getType
()
{
return
"vmtool"
;
}
public
ObjectVO
getValue
()
{
return
value
;
}
public
VmToolModel
setValue
(
ObjectVO
value
)
{
this
.
value
=
value
;
return
this
;
}
public
String
getClassLoaderClass
()
{
return
classLoaderClass
;
}
public
VmToolModel
setClassLoaderClass
(
String
classLoaderClass
)
{
this
.
classLoaderClass
=
classLoaderClass
;
return
this
;
}
public
Collection
<
ClassLoaderVO
>
getMatchedClassLoaders
()
{
return
matchedClassLoaders
;
}
public
VmToolModel
setMatchedClassLoaders
(
Collection
<
ClassLoaderVO
>
matchedClassLoaders
)
{
this
.
matchedClassLoaders
=
matchedClassLoaders
;
return
this
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/WatchModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
import
java.util.Date
;
/**
* Watch command result model
*
* @author gongdewei 2020/03/26
*/
public
class
WatchModel
extends
ResultModel
{
private
Date
ts
;
private
double
cost
;
private
ObjectVO
value
;
private
Integer
sizeLimit
;
private
String
className
;
private
String
methodName
;
private
String
accessPoint
;
public
WatchModel
()
{
}
@Override
public
String
getType
()
{
return
"watch"
;
}
public
Date
getTs
()
{
return
ts
;
}
public
void
setTs
(
Date
ts
)
{
this
.
ts
=
ts
;
}
public
double
getCost
()
{
return
cost
;
}
public
ObjectVO
getValue
()
{
return
value
;
}
public
void
setCost
(
double
cost
)
{
this
.
cost
=
cost
;
}
public
void
setValue
(
ObjectVO
value
)
{
this
.
value
=
value
;
}
public
void
setSizeLimit
(
Integer
sizeLimit
)
{
this
.
sizeLimit
=
sizeLimit
;
}
public
Integer
getSizeLimit
()
{
return
sizeLimit
;
}
public
String
getClassName
()
{
return
className
;
}
public
void
setClassName
(
String
className
)
{
this
.
className
=
className
;
}
public
String
getMethodName
()
{
return
methodName
;
}
public
void
setMethodName
(
String
methodName
)
{
this
.
methodName
=
methodName
;
}
public
String
getAccessPoint
()
{
return
accessPoint
;
}
public
void
setAccessPoint
(
String
accessPoint
)
{
this
.
accessPoint
=
accessPoint
;
}
}
core/src/main/java/com/taobao/arthas/core/command/model/WelcomeModel.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.model
;
/**
* @author gongdewei 2020/4/20
*/
public
class
WelcomeModel
extends
ResultModel
{
private
String
pid
;
private
String
time
;
private
String
version
;
private
String
wiki
;
private
String
tutorials
;
private
String
mainClass
;
public
WelcomeModel
()
{
}
@Override
public
String
getType
()
{
return
"welcome"
;
}
public
String
getPid
()
{
return
pid
;
}
public
void
setPid
(
String
pid
)
{
this
.
pid
=
pid
;
}
public
String
getTime
()
{
return
time
;
}
public
void
setTime
(
String
time
)
{
this
.
time
=
time
;
}
public
String
getVersion
()
{
return
version
;
}
public
void
setVersion
(
String
version
)
{
this
.
version
=
version
;
}
public
String
getWiki
()
{
return
wiki
;
}
public
void
setWiki
(
String
wiki
)
{
this
.
wiki
=
wiki
;
}
public
String
getTutorials
()
{
return
tutorials
;
}
public
void
setTutorials
(
String
tutorials
)
{
this
.
tutorials
=
tutorials
;
}
public
String
getMainClass
()
{
return
mainClass
;
}
public
void
setMainClass
(
String
mainClass
)
{
this
.
mainClass
=
mainClass
;
}
}
core/src/main/java/com/taobao/arthas/core/command/monitor200/AbstractTraceAdviceListener.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.monitor200
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
com.taobao.arthas.core.advisor.Advice
;
import
com.taobao.arthas.core.advisor.AdviceListenerAdapter
;
import
com.taobao.arthas.core.advisor.ArthasMethod
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.LogUtil
;
import
com.taobao.arthas.core.util.ThreadLocalWatch
;
/**
* @author ralf0131 2017-01-06 16:02.
*/
public
class
AbstractTraceAdviceListener
extends
AdviceListenerAdapter
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
AbstractTraceAdviceListener
.
class
);
protected
final
ThreadLocalWatch
threadLocalWatch
=
new
ThreadLocalWatch
();
protected
TraceCommand
command
;
protected
CommandProcess
process
;
protected
final
ThreadLocal
<
TraceEntity
>
threadBoundEntity
=
new
ThreadLocal
<
TraceEntity
>();
/**
* Constructor
*/
public
AbstractTraceAdviceListener
(
TraceCommand
command
,
CommandProcess
process
)
{
this
.
command
=
command
;
this
.
process
=
process
;
}
protected
TraceEntity
threadLocalTraceEntity
(
ClassLoader
loader
)
{
TraceEntity
traceEntity
=
threadBoundEntity
.
get
();
if
(
traceEntity
==
null
)
{
traceEntity
=
new
TraceEntity
(
loader
);
threadBoundEntity
.
set
(
traceEntity
);
}
return
traceEntity
;
}
@Override
public
void
destroy
()
{
threadBoundEntity
.
remove
();
}
@Override
public
void
before
(
ClassLoader
loader
,
Class
<?>
clazz
,
ArthasMethod
method
,
Object
target
,
Object
[]
args
)
throws
Throwable
{
TraceEntity
traceEntity
=
threadLocalTraceEntity
(
loader
);
traceEntity
.
tree
.
begin
(
clazz
.
getName
(),
method
.
getName
(),
-
1
,
false
);
traceEntity
.
deep
++;
// 开始计算本次方法调用耗时
threadLocalWatch
.
start
();
}
@Override
public
void
afterReturning
(
ClassLoader
loader
,
Class
<?>
clazz
,
ArthasMethod
method
,
Object
target
,
Object
[]
args
,
Object
returnObject
)
throws
Throwable
{
threadLocalTraceEntity
(
loader
).
tree
.
end
();
final
Advice
advice
=
Advice
.
newForAfterReturning
(
loader
,
clazz
,
method
,
target
,
args
,
returnObject
);
finishing
(
loader
,
advice
);
}
@Override
public
void
afterThrowing
(
ClassLoader
loader
,
Class
<?>
clazz
,
ArthasMethod
method
,
Object
target
,
Object
[]
args
,
Throwable
throwable
)
throws
Throwable
{
int
lineNumber
=
-
1
;
StackTraceElement
[]
stackTrace
=
throwable
.
getStackTrace
();
if
(
stackTrace
.
length
!=
0
)
{
lineNumber
=
stackTrace
[
0
].
getLineNumber
();
}
threadLocalTraceEntity
(
loader
).
tree
.
end
(
throwable
,
lineNumber
);
final
Advice
advice
=
Advice
.
newForAfterThrowing
(
loader
,
clazz
,
method
,
target
,
args
,
throwable
);
finishing
(
loader
,
advice
);
}
public
TraceCommand
getCommand
()
{
return
command
;
}
private
void
finishing
(
ClassLoader
loader
,
Advice
advice
)
{
// 本次调用的耗时
TraceEntity
traceEntity
=
threadLocalTraceEntity
(
loader
);
if
(
traceEntity
.
deep
>=
1
)
{
// #1817 防止deep为负数
traceEntity
.
deep
--;
}
if
(
traceEntity
.
deep
==
0
)
{
double
cost
=
threadLocalWatch
.
costInMillis
();
try
{
boolean
conditionResult
=
isConditionMet
(
command
.
getConditionExpress
(),
advice
,
cost
);
if
(
this
.
isVerbose
())
{
process
.
write
(
"Condition express: "
+
command
.
getConditionExpress
()
+
" , result: "
+
conditionResult
+
"\n"
);
}
if
(
conditionResult
)
{
// 满足输出条件
process
.
times
().
incrementAndGet
();
// TODO: concurrency issues for process.write
process
.
appendResult
(
traceEntity
.
getModel
());
// 是否到达数量限制
if
(
isLimitExceeded
(
command
.
getNumberOfLimit
(),
process
.
times
().
get
()))
{
// TODO: concurrency issue to abort process
abortProcess
(
process
,
command
.
getNumberOfLimit
());
}
}
}
catch
(
Throwable
e
)
{
logger
.
warn
(
"trace failed."
,
e
);
process
.
end
(
1
,
"trace failed, condition is: "
+
command
.
getConditionExpress
()
+
", "
+
e
.
getMessage
()
+
", visit "
+
LogUtil
.
loggingFile
()
+
" for more details."
);
}
finally
{
threadBoundEntity
.
remove
();
}
}
}
}
core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.monitor200
;
import
java.lang.management.GarbageCollectorMXBean
;
import
java.lang.management.ManagementFactory
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
java.util.concurrent.atomic.AtomicLong
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.command.model.DashboardModel
;
import
com.taobao.arthas.core.command.model.GcInfoVO
;
import
com.taobao.arthas.core.command.model.RuntimeInfoVO
;
import
com.taobao.arthas.core.command.model.ThreadVO
;
import
com.taobao.arthas.core.command.model.TomcatInfoVO
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.shell.handlers.Handler
;
import
com.taobao.arthas.core.shell.handlers.shell.QExitHandler
;
import
com.taobao.arthas.core.shell.session.Session
;
import
com.taobao.arthas.core.util.NetUtils
;
import
com.taobao.arthas.core.util.NetUtils.Response
;
import
com.taobao.arthas.core.util.StringUtils
;
import
com.taobao.arthas.core.util.ThreadUtil
;
import
com.taobao.arthas.core.util.metrics.SumRateCounter
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Option
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* @author hengyunabc 2015年11月19日 上午11:57:21
*/
@Name
(
"dashboard"
)
@Summary
(
"Overview of target jvm's thread, memory, gc, vm, tomcat info."
)
@Description
(
Constants
.
EXAMPLE
+
" dashboard\n"
+
" dashboard -n 10\n"
+
" dashboard -i 2000\n"
+
Constants
.
WIKI
+
Constants
.
WIKI_HOME
+
"dashboard"
)
public
class
DashboardCommand
extends
AnnotatedCommand
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
DashboardCommand
.
class
);
private
SumRateCounter
tomcatRequestCounter
=
new
SumRateCounter
();
private
SumRateCounter
tomcatErrorCounter
=
new
SumRateCounter
();
private
SumRateCounter
tomcatReceivedBytesCounter
=
new
SumRateCounter
();
private
SumRateCounter
tomcatSentBytesCounter
=
new
SumRateCounter
();
private
int
numOfExecutions
=
Integer
.
MAX_VALUE
;
private
long
interval
=
5000
;
private
final
AtomicLong
count
=
new
AtomicLong
(
0
);
private
volatile
Timer
timer
;
@Option
(
shortName
=
"n"
,
longName
=
"number-of-execution"
)
@Description
(
"The number of times this command will be executed."
)
public
void
setNumOfExecutions
(
int
numOfExecutions
)
{
this
.
numOfExecutions
=
numOfExecutions
;
}
@Option
(
shortName
=
"i"
,
longName
=
"interval"
)
@Description
(
"The interval (in ms) between two executions, default is 5000 ms."
)
public
void
setInterval
(
long
interval
)
{
this
.
interval
=
interval
;
}
@Override
public
void
process
(
final
CommandProcess
process
)
{
Session
session
=
process
.
session
();
timer
=
new
Timer
(
"Timer-for-arthas-dashboard-"
+
session
.
getSessionId
(),
true
);
// ctrl-C support
process
.
interruptHandler
(
new
DashboardInterruptHandler
(
process
,
timer
));
/*
* 通过handle回调,在suspend和end时停止timer,resume时重启timer
*/
Handler
<
Void
>
stopHandler
=
new
Handler
<
Void
>()
{
@Override
public
void
handle
(
Void
event
)
{
stop
();
}
};
Handler
<
Void
>
restartHandler
=
new
Handler
<
Void
>()
{
@Override
public
void
handle
(
Void
event
)
{
restart
(
process
);
}
};
process
.
suspendHandler
(
stopHandler
);
process
.
resumeHandler
(
restartHandler
);
process
.
endHandler
(
stopHandler
);
// q exit support
process
.
stdinHandler
(
new
QExitHandler
(
process
));
// start the timer
timer
.
scheduleAtFixedRate
(
new
DashboardTimerTask
(
process
),
0
,
getInterval
());
}
public
synchronized
void
stop
()
{
if
(
timer
!=
null
)
{
timer
.
cancel
();
timer
.
purge
();
timer
=
null
;
}
}
public
synchronized
void
restart
(
CommandProcess
process
)
{
if
(
timer
==
null
)
{
Session
session
=
process
.
session
();
timer
=
new
Timer
(
"Timer-for-arthas-dashboard-"
+
session
.
getSessionId
(),
true
);
timer
.
scheduleAtFixedRate
(
new
DashboardTimerTask
(
process
),
0
,
getInterval
());
}
}
public
int
getNumOfExecutions
()
{
return
numOfExecutions
;
}
public
long
getInterval
()
{
return
interval
;
}
private
static
void
addRuntimeInfo
(
DashboardModel
dashboardModel
)
{
RuntimeInfoVO
runtimeInfo
=
new
RuntimeInfoVO
();
runtimeInfo
.
setOsName
(
System
.
getProperty
(
"os.name"
));
runtimeInfo
.
setOsVersion
(
System
.
getProperty
(
"os.version"
));
runtimeInfo
.
setJavaVersion
(
System
.
getProperty
(
"java.version"
));
runtimeInfo
.
setJavaHome
(
System
.
getProperty
(
"java.home"
));
runtimeInfo
.
setSystemLoadAverage
(
ManagementFactory
.
getOperatingSystemMXBean
().
getSystemLoadAverage
());
runtimeInfo
.
setProcessors
(
Runtime
.
getRuntime
().
availableProcessors
());
runtimeInfo
.
setUptime
(
ManagementFactory
.
getRuntimeMXBean
().
getUptime
()
/
1000
);
runtimeInfo
.
setTimestamp
(
System
.
currentTimeMillis
());
dashboardModel
.
setRuntimeInfo
(
runtimeInfo
);
}
private
static
void
addGcInfo
(
DashboardModel
dashboardModel
)
{
List
<
GcInfoVO
>
gcInfos
=
new
ArrayList
<
GcInfoVO
>();
dashboardModel
.
setGcInfos
(
gcInfos
);
List
<
GarbageCollectorMXBean
>
garbageCollectorMxBeans
=
ManagementFactory
.
getGarbageCollectorMXBeans
();
for
(
GarbageCollectorMXBean
gcMXBean
:
garbageCollectorMxBeans
)
{
String
name
=
gcMXBean
.
getName
();
gcInfos
.
add
(
new
GcInfoVO
(
StringUtils
.
beautifyName
(
name
),
gcMXBean
.
getCollectionCount
(),
gcMXBean
.
getCollectionTime
()));
}
}
private
void
addTomcatInfo
(
DashboardModel
dashboardModel
)
{
// 如果请求tomcat信息失败,则不显示tomcat信息
if
(!
NetUtils
.
request
(
"http://localhost:8006"
).
isSuccess
())
{
return
;
}
TomcatInfoVO
tomcatInfoVO
=
new
TomcatInfoVO
();
dashboardModel
.
setTomcatInfo
(
tomcatInfoVO
);
String
threadPoolPath
=
"http://localhost:8006/connector/threadpool"
;
String
connectorStatPath
=
"http://localhost:8006/connector/stats"
;
Response
connectorStatResponse
=
NetUtils
.
request
(
connectorStatPath
);
if
(
connectorStatResponse
.
isSuccess
())
{
List
<
TomcatInfoVO
.
ConnectorStats
>
connectorStats
=
new
ArrayList
<
TomcatInfoVO
.
ConnectorStats
>();
List
<
JSONObject
>
tomcatConnectorStats
=
JSON
.
parseArray
(
connectorStatResponse
.
getContent
(),
JSONObject
.
class
);
for
(
JSONObject
stat
:
tomcatConnectorStats
)
{
String
connectorName
=
stat
.
getString
(
"name"
).
replace
(
"\""
,
""
);
long
bytesReceived
=
stat
.
getLongValue
(
"bytesReceived"
);
long
bytesSent
=
stat
.
getLongValue
(
"bytesSent"
);
long
processingTime
=
stat
.
getLongValue
(
"processingTime"
);
long
requestCount
=
stat
.
getLongValue
(
"requestCount"
);
long
errorCount
=
stat
.
getLongValue
(
"errorCount"
);
tomcatRequestCounter
.
update
(
requestCount
);
tomcatErrorCounter
.
update
(
errorCount
);
tomcatReceivedBytesCounter
.
update
(
bytesReceived
);
tomcatSentBytesCounter
.
update
(
bytesSent
);
double
qps
=
tomcatRequestCounter
.
rate
();
double
rt
=
processingTime
/
(
double
)
requestCount
;
double
errorRate
=
tomcatErrorCounter
.
rate
();
long
receivedBytesRate
=
Double
.
valueOf
(
tomcatReceivedBytesCounter
.
rate
()).
longValue
();
long
sentBytesRate
=
Double
.
valueOf
(
tomcatSentBytesCounter
.
rate
()).
longValue
();
TomcatInfoVO
.
ConnectorStats
connectorStat
=
new
TomcatInfoVO
.
ConnectorStats
();
connectorStat
.
setName
(
connectorName
);
connectorStat
.
setQps
(
qps
);
connectorStat
.
setRt
(
rt
);
connectorStat
.
setError
(
errorRate
);
connectorStat
.
setReceived
(
receivedBytesRate
);
connectorStat
.
setSent
(
sentBytesRate
);
connectorStats
.
add
(
connectorStat
);
}
tomcatInfoVO
.
setConnectorStats
(
connectorStats
);
}
Response
threadPoolResponse
=
NetUtils
.
request
(
threadPoolPath
);
if
(
threadPoolResponse
.
isSuccess
())
{
List
<
TomcatInfoVO
.
ThreadPool
>
threadPools
=
new
ArrayList
<
TomcatInfoVO
.
ThreadPool
>();
List
<
JSONObject
>
threadPoolInfos
=
JSON
.
parseArray
(
threadPoolResponse
.
getContent
(),
JSONObject
.
class
);
for
(
JSONObject
info
:
threadPoolInfos
)
{
String
name
=
info
.
getString
(
"name"
).
replace
(
"\""
,
""
);
long
busy
=
info
.
getLongValue
(
"threadBusy"
);
long
total
=
info
.
getLongValue
(
"threadCount"
);
threadPools
.
add
(
new
TomcatInfoVO
.
ThreadPool
(
name
,
busy
,
total
));
}
tomcatInfoVO
.
setThreadPools
(
threadPools
);
}
}
private
class
DashboardTimerTask
extends
TimerTask
{
private
CommandProcess
process
;
private
ThreadSampler
threadSampler
;
public
DashboardTimerTask
(
CommandProcess
process
)
{
this
.
process
=
process
;
this
.
threadSampler
=
new
ThreadSampler
();
}
@Override
public
void
run
()
{
try
{
if
(
count
.
get
()
>=
getNumOfExecutions
())
{
// stop the timer
timer
.
cancel
();
timer
.
purge
();
process
.
end
(
0
,
"Process ends after "
+
getNumOfExecutions
()
+
" time(s)."
);
return
;
}
DashboardModel
dashboardModel
=
new
DashboardModel
();
//thread sample
List
<
ThreadVO
>
threads
=
ThreadUtil
.
getThreads
();
dashboardModel
.
setThreads
(
threadSampler
.
sample
(
threads
));
//memory
dashboardModel
.
setMemoryInfo
(
MemoryCommand
.
memoryInfo
());
//gc
addGcInfo
(
dashboardModel
);
//runtime
addRuntimeInfo
(
dashboardModel
);
//tomcat
try
{
addTomcatInfo
(
dashboardModel
);
}
catch
(
Throwable
e
)
{
logger
.
error
(
"try to read tomcat info error"
,
e
);
}
process
.
appendResult
(
dashboardModel
);
count
.
getAndIncrement
();
process
.
times
().
incrementAndGet
();
}
catch
(
Throwable
e
)
{
String
msg
=
"process dashboard failed: "
+
e
.
getMessage
();
logger
.
error
(
msg
,
e
);
process
.
end
(-
1
,
msg
);
}
}
}
}
core/src/main/java/com/taobao/arthas/core/command/monitor200/DashboardInterruptHandler.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.monitor200
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.shell.handlers.command.CommandInterruptHandler
;
import
java.util.Timer
;
/**
* @author ralf0131 2017-01-09 13:37.
*/
public
class
DashboardInterruptHandler
extends
CommandInterruptHandler
{
private
volatile
Timer
timer
;
public
DashboardInterruptHandler
(
CommandProcess
process
,
Timer
timer
)
{
super
(
process
);
this
.
timer
=
timer
;
}
@Override
public
void
handle
(
Void
event
)
{
timer
.
cancel
();
super
.
handle
(
event
);
}
}
core/src/main/java/com/taobao/arthas/core/command/monitor200/EnhancerCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.monitor200
;
import
java.lang.instrument.Instrumentation
;
import
java.util.Collections
;
import
java.util.List
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
com.taobao.arthas.core.advisor.AdviceListener
;
import
com.taobao.arthas.core.advisor.AdviceWeaver
;
import
com.taobao.arthas.core.advisor.Enhancer
;
import
com.taobao.arthas.core.advisor.InvokeTraceable
;
import
com.taobao.arthas.core.command.model.EnhancerModel
;
import
com.taobao.arthas.core.shell.cli.Completion
;
import
com.taobao.arthas.core.shell.cli.CompletionUtils
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.shell.handlers.command.CommandInterruptHandler
;
import
com.taobao.arthas.core.shell.handlers.shell.QExitHandler
;
import
com.taobao.arthas.core.shell.session.Session
;
import
com.taobao.arthas.core.util.Constants
;
import
com.taobao.arthas.core.util.LogUtil
;
import
com.taobao.arthas.core.util.affect.EnhancerAffect
;
import
com.taobao.arthas.core.util.matcher.Matcher
;
import
com.taobao.arthas.core.view.Ansi
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Option
;
/**
* @author beiwei30 on 29/11/2016.
*/
public
abstract
class
EnhancerCommand
extends
AnnotatedCommand
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
EnhancerCommand
.
class
);
protected
static
final
List
<
String
>
EMPTY
=
Collections
.
emptyList
();
public
static
final
String
[]
EXPRESS_EXAMPLES
=
{
"params"
,
"returnObj"
,
"throwExp"
,
"target"
,
"clazz"
,
"method"
,
"{params,returnObj}"
,
"params[0]"
};
private
String
excludeClassPattern
;
protected
Matcher
classNameMatcher
;
protected
Matcher
classNameExcludeMatcher
;
protected
Matcher
methodNameMatcher
;
protected
long
listenerId
;
protected
boolean
verbose
;
@Option
(
longName
=
"exclude-class-pattern"
)
@Description
(
"exclude class name pattern, use either '.' or '/' as separator"
)
public
void
setExcludeClassPattern
(
String
excludeClassPattern
)
{
this
.
excludeClassPattern
=
excludeClassPattern
;
}
@Option
(
longName
=
"listenerId"
)
@Description
(
"The special listenerId"
)
public
void
setListenerId
(
long
listenerId
)
{
this
.
listenerId
=
listenerId
;
}
@Option
(
shortName
=
"v"
,
longName
=
"verbose"
,
flag
=
true
)
@Description
(
"Enables print verbose information, default value false."
)
public
void
setVerbosee
(
boolean
verbose
)
{
this
.
verbose
=
verbose
;
}
/**
* 类名匹配
*
* @return 获取类名匹配
*/
protected
abstract
Matcher
getClassNameMatcher
();
/**
* 排除类名匹配
*/
protected
abstract
Matcher
getClassNameExcludeMatcher
();
/**
* 方法名匹配
*
* @return 获取方法名匹配
*/
protected
abstract
Matcher
getMethodNameMatcher
();
/**
* 获取监听器
*
* @return 返回监听器
*/
protected
abstract
AdviceListener
getAdviceListener
(
CommandProcess
process
);
AdviceListener
getAdviceListenerWithId
(
CommandProcess
process
)
{
if
(
listenerId
!=
0
)
{
AdviceListener
listener
=
AdviceWeaver
.
listener
(
listenerId
);
if
(
listener
!=
null
)
{
return
listener
;
}
}
return
getAdviceListener
(
process
);
}
@Override
public
void
process
(
final
CommandProcess
process
)
{
// ctrl-C support
process
.
interruptHandler
(
new
CommandInterruptHandler
(
process
));
// q exit support
process
.
stdinHandler
(
new
QExitHandler
(
process
));
// start to enhance
enhance
(
process
);
}
@Override
public
void
complete
(
Completion
completion
)
{
int
argumentIndex
=
CompletionUtils
.
detectArgumentIndex
(
completion
);
if
(
argumentIndex
==
1
)
{
// class name
if
(!
CompletionUtils
.
completeClassName
(
completion
))
{
super
.
complete
(
completion
);
}
return
;
}
else
if
(
argumentIndex
==
2
)
{
// method name
if
(!
CompletionUtils
.
completeMethodName
(
completion
))
{
super
.
complete
(
completion
);
}
return
;
}
else
if
(
argumentIndex
==
3
)
{
// watch express
completeArgument3
(
completion
);
return
;
}
super
.
complete
(
completion
);
}
protected
void
enhance
(
CommandProcess
process
)
{
Session
session
=
process
.
session
();
if
(!
session
.
tryLock
())
{
String
msg
=
"someone else is enhancing classes, pls. wait."
;
process
.
appendResult
(
new
EnhancerModel
(
null
,
false
,
msg
));
process
.
end
(-
1
,
msg
);
return
;
}
EnhancerAffect
effect
=
null
;
int
lock
=
session
.
getLock
();
try
{
Instrumentation
inst
=
session
.
getInstrumentation
();
AdviceListener
listener
=
getAdviceListenerWithId
(
process
);
if
(
listener
==
null
)
{
logger
.
error
(
"advice listener is null"
);
String
msg
=
"advice listener is null, check arthas log"
;
process
.
appendResult
(
new
EnhancerModel
(
effect
,
false
,
msg
));
process
.
end
(-
1
,
msg
);
return
;
}
boolean
skipJDKTrace
=
false
;
if
(
listener
instanceof
AbstractTraceAdviceListener
)
{
skipJDKTrace
=
((
AbstractTraceAdviceListener
)
listener
).
getCommand
().
isSkipJDKTrace
();
}
Enhancer
enhancer
=
new
Enhancer
(
listener
,
listener
instanceof
InvokeTraceable
,
skipJDKTrace
,
getClassNameMatcher
(),
getClassNameExcludeMatcher
(),
getMethodNameMatcher
());
// 注册通知监听器
process
.
register
(
listener
,
enhancer
);
effect
=
enhancer
.
enhance
(
inst
);
if
(
effect
.
getThrowable
()
!=
null
)
{
String
msg
=
"error happens when enhancing class: "
+
effect
.
getThrowable
().
getMessage
();
process
.
appendResult
(
new
EnhancerModel
(
effect
,
false
,
msg
));
process
.
end
(
1
,
msg
+
", check arthas log: "
+
LogUtil
.
loggingFile
());
return
;
}
if
(
effect
.
cCnt
()
==
0
||
effect
.
mCnt
()
==
0
)
{
// no class effected
// might be method code too large
process
.
appendResult
(
new
EnhancerModel
(
effect
,
false
,
"No class or method is affected"
));
String
smCommand
=
Ansi
.
ansi
().
fg
(
Ansi
.
Color
.
GREEN
).
a
(
"sm CLASS_NAME METHOD_NAME"
).
reset
().
toString
();
String
optionsCommand
=
Ansi
.
ansi
().
fg
(
Ansi
.
Color
.
GREEN
).
a
(
"options unsafe true"
).
reset
().
toString
();
String
javaPackage
=
Ansi
.
ansi
().
fg
(
Ansi
.
Color
.
GREEN
).
a
(
"java.*"
).
reset
().
toString
();
String
resetCommand
=
Ansi
.
ansi
().
fg
(
Ansi
.
Color
.
GREEN
).
a
(
"reset CLASS_NAME"
).
reset
().
toString
();
String
logStr
=
Ansi
.
ansi
().
fg
(
Ansi
.
Color
.
GREEN
).
a
(
LogUtil
.
loggingFile
()).
reset
().
toString
();
String
issueStr
=
Ansi
.
ansi
().
fg
(
Ansi
.
Color
.
GREEN
).
a
(
"https://github.com/alibaba/arthas/issues/47"
).
reset
().
toString
();
String
msg
=
"No class or method is affected, try:\n"
+
"1. Execute `"
+
smCommand
+
"` to make sure the method you are tracing actually exists (it might be in your parent class).\n"
+
"2. Execute `"
+
optionsCommand
+
"`, if you want to enhance the classes under the `"
+
javaPackage
+
"` package.\n"
+
"3. Execute `"
+
resetCommand
+
"` and try again, your method body might be too large.\n"
+
"4. Match the constructor, use `<init>`, for example: `watch demo.MathGame <init>`\n"
+
"5. Check arthas log: "
+
logStr
+
"\n"
+
"6. Visit "
+
issueStr
+
" for more details."
;
process
.
end
(-
1
,
msg
);
return
;
}
// 这里做个补偿,如果在enhance期间,unLock被调用了,则补偿性放弃
if
(
session
.
getLock
()
==
lock
)
{
if
(
process
.
isForeground
())
{
process
.
echoTips
(
Constants
.
Q_OR_CTRL_C_ABORT_MSG
+
"\n"
);
}
}
process
.
appendResult
(
new
EnhancerModel
(
effect
,
true
));
//异步执行,在AdviceListener中结束
}
catch
(
Throwable
e
)
{
String
msg
=
"error happens when enhancing class: "
+
e
.
getMessage
();
logger
.
error
(
msg
,
e
);
process
.
appendResult
(
new
EnhancerModel
(
effect
,
false
,
msg
));
process
.
end
(-
1
,
msg
);
}
finally
{
if
(
session
.
getLock
()
==
lock
)
{
// enhance结束后解锁
process
.
session
().
unLock
();
}
}
}
protected
void
completeArgument3
(
Completion
completion
)
{
super
.
complete
(
completion
);
}
public
String
getExcludeClassPattern
()
{
return
excludeClassPattern
;
}
}
core/src/main/java/com/taobao/arthas/core/command/monitor200/GroovyAdviceListener.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.monitor200
;
import
com.taobao.arthas.core.advisor.Advice
;
import
com.taobao.arthas.core.advisor.AdviceListenerAdapter
;
import
com.taobao.arthas.core.advisor.ArthasMethod
;
import
com.taobao.arthas.core.command.ScriptSupportCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
/**
* Groovy support has been completed dropped in Arthas 3.0 because of severer memory leak.
* @author beiwei30 on 01/12/2016.
*/
@Deprecated
public
class
GroovyAdviceListener
extends
AdviceListenerAdapter
{
private
ScriptSupportCommand
.
ScriptListener
scriptListener
;
private
ScriptSupportCommand
.
Output
output
;
public
GroovyAdviceListener
(
ScriptSupportCommand
.
ScriptListener
scriptListener
,
CommandProcess
process
)
{
this
.
scriptListener
=
scriptListener
;
this
.
output
=
new
CommandProcessAdaptor
(
process
);
}
@Override
public
void
create
()
{
scriptListener
.
create
(
output
);
}
@Override
public
void
destroy
()
{
scriptListener
.
destroy
(
output
);
}
@Override
public
void
before
(
ClassLoader
loader
,
Class
<?>
clazz
,
ArthasMethod
method
,
Object
target
,
Object
[]
args
)
throws
Throwable
{
scriptListener
.
before
(
output
,
Advice
.
newForBefore
(
loader
,
clazz
,
method
,
target
,
args
));
}
@Override
public
void
afterReturning
(
ClassLoader
loader
,
Class
<?>
clazz
,
ArthasMethod
method
,
Object
target
,
Object
[]
args
,
Object
returnObject
)
throws
Throwable
{
scriptListener
.
afterReturning
(
output
,
Advice
.
newForAfterReturning
(
loader
,
clazz
,
method
,
target
,
args
,
returnObject
));
}
@Override
public
void
afterThrowing
(
ClassLoader
loader
,
Class
<?>
clazz
,
ArthasMethod
method
,
Object
target
,
Object
[]
args
,
Throwable
throwable
)
throws
Throwable
{
scriptListener
.
afterThrowing
(
output
,
Advice
.
newForAfterThrowing
(
loader
,
clazz
,
method
,
target
,
args
,
throwable
));
}
private
static
class
CommandProcessAdaptor
implements
ScriptSupportCommand
.
Output
{
private
CommandProcess
process
;
public
CommandProcessAdaptor
(
CommandProcess
process
)
{
this
.
process
=
process
;
}
@Override
public
ScriptSupportCommand
.
Output
print
(
String
string
)
{
process
.
write
(
string
);
return
this
;
}
@Override
public
ScriptSupportCommand
.
Output
println
(
String
string
)
{
process
.
write
(
string
).
write
(
"\n"
);
return
this
;
}
@Override
public
ScriptSupportCommand
.
Output
finish
()
{
process
.
end
();
return
this
;
}
}
}
Prev
1
…
14
15
16
17
18
19
20
21
22
23
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment