|
|
|
|
Http API
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
[`Http API` online tutorial](https://arthas.aliyun.com/doc/arthas-tutorials.html?language=en&id=case-http-api)
|
|
|
|
|
|
|
|
|
|
### Overview
|
|
|
|
|
|
|
|
|
|
Http API provides a RESTful-like interactive interface, and both
|
|
|
|
|
requests and responses data in JSON format. Compared with
|
|
|
|
|
Telnet/WebConsole's output unstructured text data, Http API can provide
|
|
|
|
|
structured data and support more complex interactive functions, such as
|
|
|
|
|
a series of diagnostic operations in specific application scenarios.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Access address
|
|
|
|
|
|
|
|
|
|
The Http API address is: `http://ip:port/api`, the request parameters
|
|
|
|
|
must be submitted using `POST`. Such as POST
|
|
|
|
|
`http://127.0.0.1:8563/api`.
|
|
|
|
|
|
|
|
|
|
Note: The telnet port `3658` has compatibility issues with the Chrome
|
|
|
|
|
browser. It is recommended to use the http port `8563` to access the
|
|
|
|
|
http api.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Request data format
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"action": "exec",
|
|
|
|
|
"requestId": "req112",
|
|
|
|
|
"sessionId": "94766d3c-8b39-42d3-8596-98aee3ccbefb",
|
|
|
|
|
"consumerId": "955dbd1325334a84972b0f3ac19de4f7_2",
|
|
|
|
|
"command": "version",
|
|
|
|
|
"execTimeout": "10000"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
Request data format description:
|
|
|
|
|
|
|
|
|
|
* `action` : The requested action/behavior, please refer to "Request
|
|
|
|
|
Actions" for optional values.
|
|
|
|
|
* `requestId` : Optional request ID, generated by the client.
|
|
|
|
|
* `sessionId` : Arthas session ID, one-time command does not need to
|
|
|
|
|
set the session ID.
|
|
|
|
|
* `consumerId` : Arthas consumer ID, used for multi-person sharing
|
|
|
|
|
sessions.
|
|
|
|
|
* `command` : Arthas command line
|
|
|
|
|
* `execTimeout` : Timeout for executing commands (ms), default value is 30000.
|
|
|
|
|
|
|
|
|
|
Note: Different actions use different parameters. Set the parameters
|
|
|
|
|
according to the specific action.
|
|
|
|
|
|
|
|
|
|
#### Request Actions
|
|
|
|
|
|
|
|
|
|
Currently supported request actions are as follows:
|
|
|
|
|
|
|
|
|
|
* `exec` : The command is executed synchronously, and the command
|
|
|
|
|
results is returned after the command execution end or interrupted.
|
|
|
|
|
* `async_exec` : The command is executed asynchronously, and the
|
|
|
|
|
scheduling result of the command is returned immediately. The command
|
|
|
|
|
execution result is obtained through `pull_results` action.
|
|
|
|
|
* `interrupt_job` : To interrupt the foreground command of the session,
|
|
|
|
|
similar to the function of Telnet `Ctrl + c`.
|
|
|
|
|
* `pull_results` : Get the result of the command executed
|
|
|
|
|
asynchronously, and execute it repeatedly in http long-polling mode.
|
|
|
|
|
* `init_session` : Create new session.
|
|
|
|
|
* `join_session` : Join the session, used to support multiple people
|
|
|
|
|
sharing the same Arthas session.
|
|
|
|
|
* `close_session` : Close the session.
|
|
|
|
|
|
|
|
|
|
#### Response status
|
|
|
|
|
|
|
|
|
|
The state attribute in the response indicates the request processing
|
|
|
|
|
state, and its value is as follows:
|
|
|
|
|
|
|
|
|
|
* `SCHEDULED`: When the command is executed asynchronously, it means that
|
|
|
|
|
the job has been created, and may not be executed yet or is being
|
|
|
|
|
executed;
|
|
|
|
|
* `SUCCEEDED`: The request is processed successfully (completed status);
|
|
|
|
|
* `FAILED`: Request processing failed (completed status), usually
|
|
|
|
|
accompanied by a message explaining the reason;
|
|
|
|
|
* `REFUSED`: The request is rejected (completed status), usually
|
|
|
|
|
accompanied by a message explaining the reason;
|
|
|
|
|
|
|
|
|
|
### One-time command
|
|
|
|
|
|
|
|
|
|
Similar to executing batch commands, the one-time commands are executed
|
|
|
|
|
synchronously. No need to create a session, no need to set the
|
|
|
|
|
`sessionId` option.
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"action": "exec",
|
|
|
|
|
"command": "<Arthas command line>"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
For example, get the Arthas version number:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '
|
|
|
|
|
{
|
|
|
|
|
"action":"exec",
|
|
|
|
|
"command":"version"
|
|
|
|
|
}
|
|
|
|
|
'
|
|
|
|
|
```
|
|
|
|
|
The response is as follows:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"state" : "SUCCEEDED",
|
|
|
|
|
"sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869",
|
|
|
|
|
"body" : {
|
|
|
|
|
"results" : [
|
|
|
|
|
{
|
|
|
|
|
"type" : "version",
|
|
|
|
|
"version" : "3.3.7",
|
|
|
|
|
"jobId" : 5
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"jobId" : 5,
|
|
|
|
|
"statusCode" : 0,
|
|
|
|
|
"type" : "status"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"timeExpired" : false,
|
|
|
|
|
"command" : "version",
|
|
|
|
|
"jobStatus" : "TERMINATED",
|
|
|
|
|
"jobId" : 5
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
Response data format description:
|
|
|
|
|
|
|
|
|
|
* `state`: Request processing status, refer to the description of
|
|
|
|
|
"Response Status".
|
|
|
|
|
* `sessionId `: Arthas session ID, one-time command to automatically
|
|
|
|
|
create and destroy temporary sessions.
|
|
|
|
|
* `body.jobId`: The job ID of the command, all output results of the
|
|
|
|
|
same job are the same jobId.
|
|
|
|
|
* `body.jobStatus`: The job status of the command.
|
|
|
|
|
* `body.timeExpired`: Whether the job execution timed out.
|
|
|
|
|
* `body/results`: Command execution results.
|
|
|
|
|
|
|
|
|
|
**Command result format description**
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
[{
|
|
|
|
|
"type" : "version",
|
|
|
|
|
"version" : "3.3.7",
|
|
|
|
|
"jobId" : 5
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"jobId" : 5,
|
|
|
|
|
"statusCode" : 0,
|
|
|
|
|
"type" : "status"
|
|
|
|
|
}]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
* `type` : The command result type, except for the special ones such as
|
|
|
|
|
`status`, the others remain the same as the Arthas command name.
|
|
|
|
|
Please refer to the section
|
|
|
|
|
"[Special command results](#special_command_results)".
|
|
|
|
|
* `jobId` : The job ID of the command.
|
|
|
|
|
* Other fields are the data of each different command.
|
|
|
|
|
|
|
|
|
|
Note: You can also use a one-time command to execute continuous output
|
|
|
|
|
commands such as watch/trace, but you can't interrupt the command
|
|
|
|
|
execution, and there may be hang up for a long time. Please refer to the
|
|
|
|
|
example in the
|
|
|
|
|
"[Make watch command output a map object](#change_watch_value_to_map)"
|
|
|
|
|
section.
|
|
|
|
|
|
|
|
|
|
Please try to deal with it in the following way:
|
|
|
|
|
|
|
|
|
|
* Set a reasonable `execTimeout` to forcibly interrupt the command
|
|
|
|
|
execution after the timeout period is reached to avoid a long hang.
|
|
|
|
|
* Use the `-n` parameter to specify a smaller number of executions.
|
|
|
|
|
* Ensure the methods of the command matched can be successfully hit and
|
|
|
|
|
the `condition-express` is written correctly. If the `watch/trace` does
|
|
|
|
|
not hit, even if `-n 1` is specified, it will hang and wait until the
|
|
|
|
|
execution timeout.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Session interaction
|
|
|
|
|
|
|
|
|
|
Users create and manage Arthas sessions, which are suitable for complex
|
|
|
|
|
interactive processes. The access process is as follows:
|
|
|
|
|
|
|
|
|
|
* Create a session
|
|
|
|
|
* Join the session (optional)
|
|
|
|
|
* Pull command results
|
|
|
|
|
* Execute a series of commands
|
|
|
|
|
* Interrupt command execution
|
|
|
|
|
* Close the session
|
|
|
|
|
|
|
|
|
|
#### Create session
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '
|
|
|
|
|
{
|
|
|
|
|
"action":"init_session"
|
|
|
|
|
}
|
|
|
|
|
'
|
|
|
|
|
```
|
|
|
|
|
Response result:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
|
|
|
|
|
"consumerId" : "5ae4e5fbab8b4e529ac404f260d4e2d1_1",
|
|
|
|
|
"state" : "SUCCEEDED"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
The new session ID is: `b09f1353-202c-407b-af24-701b744f971e`, and
|
|
|
|
|
consumer ID is: `5ae4e5fbab8b4e529ac404f260d4e2d1_1`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Join session
|
|
|
|
|
|
|
|
|
|
Specify the session ID to join, and the server will assign a new
|
|
|
|
|
consumer ID. Multiple consumers can receive the same command results of
|
|
|
|
|
target session. This interface is used to support multiple people
|
|
|
|
|
sharing the same session or refreshing the page to retrieve the session
|
|
|
|
|
history.
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '
|
|
|
|
|
{
|
|
|
|
|
"action":"join_session",
|
|
|
|
|
"sessionId" : "b09f1353-202c-407b-af24-701b744f971e"
|
|
|
|
|
}
|
|
|
|
|
'
|
|
|
|
|
```
|
|
|
|
|
Response result:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2",
|
|
|
|
|
"sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
|
|
|
|
|
"state" : "SUCCEEDED"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
The new consumer ID is `8f7f6ad7bc2d4cb5aa57a530927a95cc_2 ` .
|
|
|
|
|
|
|
|
|
|
#### Pull command results
|
|
|
|
|
|
|
|
|
|
The action of pulling the command result message is `pull_results`.
|
|
|
|
|
Please use the Http long-polling method to periodically pull the result
|
|
|
|
|
messages. The consumer's timeout period is 5 minutes. After the timeout,
|
|
|
|
|
you need to call `join_session` to allocate a new consumer.
|
|
|
|
|
|
|
|
|
|
Each consumer is allocated a cache queue separately, and the pull order
|
|
|
|
|
does not affect the content received by the consumer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The request parameters require session ID and consumer ID:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '
|
|
|
|
|
{
|
|
|
|
|
"action":"pull_results",
|
|
|
|
|
"sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
|
|
|
|
|
"consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2"
|
|
|
|
|
}
|
|
|
|
|
'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Use Bash scripts to regularly pull results messages:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
while true; do curl -Ss -XPOST http://localhost:8563/api -d '
|
|
|
|
|
{
|
|
|
|
|
"action":"pull_results",
|
|
|
|
|
"sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
|
|
|
|
|
"consumerId" : "8ecb9cb7c7804d5d92e258b23d5245cc_1"
|
|
|
|
|
}
|
|
|
|
|
' | json_pp; sleep 2; done
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Note: The `json_pp` tool formats the output content as pretty json.
|
|
|
|
|
|
|
|
|
|
The response content is as follows:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"body" : {
|
|
|
|
|
"results" : [
|
|
|
|
|
{
|
|
|
|
|
"inputStatus" : "DISABLED",
|
|
|
|
|
"jobId" : 0,
|
|
|
|
|
"type" : "input_status"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"type" : "message",
|
|
|
|
|
"jobId" : 0,
|
|
|
|
|
"message" : "Welcome to arthas!"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"tutorials" : "https://arthas.aliyun.com/doc/arthas-tutorials.html",
|
|
|
|
|
"time" : "2020-08-06 15:56:43",
|
|
|
|
|
"type" : "welcome",
|
|
|
|
|
"jobId" : 0,
|
|
|
|
|
"pid" : "7909",
|
|
|
|
|
"wiki" : "https://arthas.aliyun.com/doc",
|
|
|
|
|
"version" : "3.3.7"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"inputStatus" : "ALLOW_INPUT",
|
|
|
|
|
"type" : "input_status",
|
|
|
|
|
"jobId" : 0
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
"sessionId" : "b09f1353-202c-407b-af24-701b744f971e",
|
|
|
|
|
"consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2",
|
|
|
|
|
"state" : "SUCCEEDED"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Execute commands asynchronously
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '''
|
|
|
|
|
{
|
|
|
|
|
"action":"async_exec",
|
|
|
|
|
"command":"watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" ",
|
|
|
|
|
"sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a"
|
|
|
|
|
}
|
|
|
|
|
'''
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Response of `async_exec`:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
|
|
|
|
|
"state" : "SCHEDULED",
|
|
|
|
|
"body" : {
|
|
|
|
|
"jobStatus" : "READY",
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
* `state` : The status of `SCHEDULED` means that the command has been
|
|
|
|
|
parsed and generated the job, but the execution has not started.
|
|
|
|
|
* `body.jobId` : The job id of command execution, filter the command
|
|
|
|
|
results output in `pull_results` according to this job ID.
|
|
|
|
|
* `body.jobStatus` : The job status `READY` means that execution has not started.
|
|
|
|
|
|
|
|
|
|
The shell output of the script that continuously pulls the result message:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"body" : {
|
|
|
|
|
"results" : [
|
|
|
|
|
{
|
|
|
|
|
"type" : "command",
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"state" : "SCHEDULED",
|
|
|
|
|
"command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"inputStatus" : "ALLOW_INTERRUPT",
|
|
|
|
|
"jobId" : 0,
|
|
|
|
|
"type" : "input_status"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"success" : true,
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"effect" : {
|
|
|
|
|
"listenerId" : 3,
|
|
|
|
|
"cost" : 24,
|
|
|
|
|
"classCount" : 1,
|
|
|
|
|
"methodCount" : 1
|
|
|
|
|
},
|
|
|
|
|
"type" : "enhancer"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"sizeLimit" : 10485760,
|
|
|
|
|
"expand" : 1,
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"type" : "watch",
|
|
|
|
|
"cost" : 0.071499,
|
|
|
|
|
"ts" : 1596703453237,
|
|
|
|
|
"value" : [
|
|
|
|
|
[
|
|
|
|
|
-170365
|
|
|
|
|
],
|
|
|
|
|
null,
|
|
|
|
|
{
|
|
|
|
|
"stackTrace" : [
|
|
|
|
|
{
|
|
|
|
|
"className" : "demo.MathGame",
|
|
|
|
|
"classLoaderName" : "app",
|
|
|
|
|
"methodName" : "primeFactors",
|
|
|
|
|
"nativeMethod" : false,
|
|
|
|
|
"lineNumber" : 46,
|
|
|
|
|
"fileName" : "MathGame.java"
|
|
|
|
|
},
|
|
|
|
|
...
|
|
|
|
|
],
|
|
|
|
|
"localizedMessage" : "number is: -170365, need >= 2",
|
|
|
|
|
"@type" : "java.lang.IllegalArgumentException",
|
|
|
|
|
"message" : "number is: -170365, need >= 2"
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"type" : "watch",
|
|
|
|
|
"cost" : 0.033375,
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"ts" : 1596703454241,
|
|
|
|
|
"value" : [
|
|
|
|
|
[
|
|
|
|
|
1
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
2,
|
|
|
|
|
2,
|
|
|
|
|
2,
|
|
|
|
|
2,
|
|
|
|
|
13,
|
|
|
|
|
491
|
|
|
|
|
],
|
|
|
|
|
null
|
|
|
|
|
],
|
|
|
|
|
"sizeLimit" : 10485760,
|
|
|
|
|
"expand" : 1
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
"consumerId" : "8ecb9cb7c7804d5d92e258b23d5245cc_1",
|
|
|
|
|
"sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a",
|
|
|
|
|
"state" : "SUCCEEDED"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `value` of the watch command result is the value of watch-experss,
|
|
|
|
|
and the above command is `{params, returnObj, throwExp}`, so the value
|
|
|
|
|
of the watch result is an array of length 3, and each element
|
|
|
|
|
corresponds to the expression in the corresponding order.
|
|
|
|
|
|
|
|
|
|
Please refer to the section "[Make watch command output a map object](#change_watch_value_to_map)".
|
|
|
|
|
|
|
|
|
|
#### Interrupt command execution
|
|
|
|
|
|
|
|
|
|
Interrupt the running foreground job of the session:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '''
|
|
|
|
|
{
|
|
|
|
|
"action":"interrupt_job",
|
|
|
|
|
"sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a"
|
|
|
|
|
}
|
|
|
|
|
'''
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"state" : "SUCCEEDED",
|
|
|
|
|
"body" : {
|
|
|
|
|
"jobStatus" : "TERMINATED",
|
|
|
|
|
"jobId" : 3
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### Close session
|
|
|
|
|
|
|
|
|
|
Specify the session ID to close the session.
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d '''
|
|
|
|
|
{
|
|
|
|
|
"action":"close_session",
|
|
|
|
|
"sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a"
|
|
|
|
|
}
|
|
|
|
|
'''
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"state" : "SUCCEEDED"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Web UI
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
A Web UI based on Http API, visit url :
|
|
|
|
|
[http://127.0.0.1:8563/ui](http://127.0.0.1:8563/ui) .
|
|
|
|
|
|
|
|
|
|
Completed functions:
|
|
|
|
|
|
|
|
|
|
* Create a session
|
|
|
|
|
* Copy and open the url to join the session, share the session with
|
|
|
|
|
multiple people
|
|
|
|
|
* Continuously pull session command result messages
|
|
|
|
|
* Refresh the web page or join the session to pull command messages
|
|
|
|
|
history
|
|
|
|
|
* Control input or interrupt command status
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pending function:
|
|
|
|
|
|
|
|
|
|
* Improve the readability of command result messages
|
|
|
|
|
* Support automatic completion of input commands and command templates
|
|
|
|
|
* Provide command help
|
|
|
|
|
* Support personal profile settings
|
|
|
|
|
|
|
|
|
|
<a id="special_command_results"></a>
|
|
|
|
|
### Special command results
|
|
|
|
|
|
|
|
|
|
#### status
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"jobId" : 5,
|
|
|
|
|
"statusCode" : 0,
|
|
|
|
|
"type" : "status"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`type` is `status` to indicate the command execution status:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
After each command is executed, there is a unique status result. If the
|
|
|
|
|
`statusCode` is 0, it means the execution is successful, and the
|
|
|
|
|
`statusCode` is a non-zero value that means the execution failed,
|
|
|
|
|
similar to the process exit code.
|
|
|
|
|
|
|
|
|
|
When the command execution fails, an error message is generally provided, such as:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"jobId":3,
|
|
|
|
|
"message":"The argument 'class-pattern' is required",
|
|
|
|
|
"statusCode":-10,
|
|
|
|
|
"type":"status"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### input_status
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"inputStatus" : "ALLOW_INPUT",
|
|
|
|
|
"type" : "input_status",
|
|
|
|
|
"jobId" : 0
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`type` is `input_status` to indicate input status:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
It is used to control user input during UI interaction, and a change
|
|
|
|
|
message will be sent before and after each command is executed.
|
|
|
|
|
|
|
|
|
|
Possible values of `inputStatus`:
|
|
|
|
|
|
|
|
|
|
* `ALLOW_INPUT` : Allow users to enter commands, which means that the
|
|
|
|
|
session has no foreground command being executed and can accept new
|
|
|
|
|
command.
|
|
|
|
|
* `ALLOW_INTERRUPT` : Allow the user to interrupt the command execution,
|
|
|
|
|
indicating that a command is currently being executed, and the user
|
|
|
|
|
can send `interrupt_job` to interrupt the execution.
|
|
|
|
|
* `DISABLED` : In the disabled state, commands cannot be entered or
|
|
|
|
|
interrupted.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### command
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"type" : "command",
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"state" : "SCHEDULED",
|
|
|
|
|
"command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" "
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
`type` is `command` to indicate the input command data:
|
|
|
|
|
|
|
|
|
|
It is used for the interactive UI to echo the commands entered by the
|
|
|
|
|
user. The pulled session command message history will contain messages
|
|
|
|
|
of type `command`, which can be processed in order.
|
|
|
|
|
|
|
|
|
|
#### enhancer
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"success" : true,
|
|
|
|
|
"jobId" : 3,
|
|
|
|
|
"effect" : {
|
|
|
|
|
"listenerId" : 3,
|
|
|
|
|
"cost" : 24,
|
|
|
|
|
"classCount" : 1,
|
|
|
|
|
"methodCount" : 1
|
|
|
|
|
},
|
|
|
|
|
"type" : "enhancer"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`type` is `enhancer` to indicate the result of class enhancement:
|
|
|
|
|
|
|
|
|
|
Commands such as `trace/watch/jad/tt` need to enhance the class and will
|
|
|
|
|
receive this `enhancer` result. It may happen that the result of
|
|
|
|
|
`enhancer` is successful, but there is no hit method. The client can
|
|
|
|
|
prompt the user according to the result of `enhancer`.
|
|
|
|
|
|
|
|
|
|
### Cases
|
|
|
|
|
|
|
|
|
|
#### Get classpath of Java application
|
|
|
|
|
|
|
|
|
|
Get system properties of the Java application through Http api and
|
|
|
|
|
extract the value of `java.class.path`.
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
json_data=$(curl -Ss -XPOST http://localhost:8563/api -d '
|
|
|
|
|
{
|
|
|
|
|
"action":"exec",
|
|
|
|
|
"command":"sysprop"
|
|
|
|
|
}')
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
* Extract value with `sed`:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
class_path=$(echo $json_data | tr -d '\n' | sed 's/.*"java.class.path":"\([^"]*\).*/\1/')
|
|
|
|
|
echo "classpath: $class_path"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
* Extract value with `json_pp/awk`:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
class_path=$(echo $json_data | tr -d '\n' | json_pp | grep java.class.path | awk -F'"' '{ print $4 }')
|
|
|
|
|
echo "classpath: $class_path"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Output:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
classpath: demo-arthas-spring-boot.jar
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
NOTE:
|
|
|
|
|
|
|
|
|
|
* `echo $json_data | tr -d '\n'` : Delete line breaks (the value of
|
|
|
|
|
`line.separator`) to avoid affecting the processing of `sed`/`json_pp`
|
|
|
|
|
commands.
|
|
|
|
|
* `awk -F'"' '{ print $4 }'` : Use double quote as delimiter
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a id="change_watch_value_to_map"></a>
|
|
|
|
|
#### Make watch command output a map object
|
|
|
|
|
|
|
|
|
|
The result value of `watch` is generated by calculating the
|
|
|
|
|
`watch-express` ognl expression. You can change the ognl expression to
|
|
|
|
|
generate the desired value, please refer to
|
|
|
|
|
[OGNL document](https://commons.apache.org/proper/commons-ognl/language-guide.html).
|
|
|
|
|
|
|
|
|
|
> Maps can also be created using a special syntax.
|
|
|
|
|
>
|
|
|
|
|
>#{ "foo" : "foo value", "bar" : "bar value" }
|
|
|
|
|
>
|
|
|
|
|
>This creates a Map initialized with mappings for "foo" and "bar".
|
|
|
|
|
|
|
|
|
|
The following command generates values in map format:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
watch *MathGame prime* '#{ "params" : params, "returnObj" : returnObj, "throwExp": throwExp}' -x 2 -n 5
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Execute the above command in Telnet shell/WebConsole, the output result:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
ts=2020-08-06 16:57:20; [cost=0.241735ms] result=@LinkedHashMap[
|
|
|
|
|
@String[params]:@Object[][
|
|
|
|
|
@Integer[1],
|
|
|
|
|
],
|
|
|
|
|
@String[returnObj]:@ArrayList[
|
|
|
|
|
@Integer[2],
|
|
|
|
|
@Integer[241],
|
|
|
|
|
@Integer[379],
|
|
|
|
|
],
|
|
|
|
|
@String[throwExp]:null,
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Execute the above command with Http api, pay attention to escaping the JSON double quotes:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -Ss -XPOST http://localhost:8563/api -d @- << EOF
|
|
|
|
|
{
|
|
|
|
|
"action":"exec",
|
|
|
|
|
"execTimeout": 30000,
|
|
|
|
|
"command":"watch *MathGame prime* '#{ \"params\" : params, \"returnObj\" : returnObj, \"throwExp\": throwExp}' -n 3 "
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Http api execution result:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"body": {
|
|
|
|
|
...
|
|
|
|
|
"results": [
|
|
|
|
|
...
|
|
|
|
|
{
|
|
|
|
|
...
|
|
|
|
|
"type": "watch",
|
|
|
|
|
"value": {
|
|
|
|
|
"params": [
|
|
|
|
|
1
|
|
|
|
|
],
|
|
|
|
|
"returnObj": [
|
|
|
|
|
2,
|
|
|
|
|
5,
|
|
|
|
|
17,
|
|
|
|
|
23,
|
|
|
|
|
23
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
...
|
|
|
|
|
"type": "watch",
|
|
|
|
|
"value": {
|
|
|
|
|
"params": [
|
|
|
|
|
-98278
|
|
|
|
|
],
|
|
|
|
|
"throwExp": {
|
|
|
|
|
"@type": "java.lang.IllegalArgumentException",
|
|
|
|
|
"localizedMessage": "number is: -98278, need >= 2",
|
|
|
|
|
"message": "number is: -98278, need >= 2",
|
|
|
|
|
"stackTrace": [
|
|
|
|
|
...
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
You can see that the value of the watch result becomes a map object, and
|
|
|
|
|
the program can read value through a key .
|