From 7a01f23a73dcec7d1ca4f12f802a8c7fecbb2500 Mon Sep 17 00:00:00 2001 From: gongdewei Date: Fri, 7 Aug 2020 16:09:19 +0800 Subject: [PATCH 1/8] HTTP API support one-time command execution and add HTTP API docs (#1408) --- .../session/impl/SessionManagerImpl.java | 15 +- .../shell/term/impl/http/api/ApiRequest.java | 22 +- .../term/impl/http/api/HttpApiHandler.java | 168 +++-- site/src/site/sphinx/en/http-api.md | 711 ++++++++++++++++++ site/src/site/sphinx/en/index.md | 1 + site/src/site/sphinx/http-api.md | 630 ++++++++++++++++ site/src/site/sphinx/index.md | 1 + 7 files changed, 1452 insertions(+), 96 deletions(-) create mode 100644 site/src/site/sphinx/en/http-api.md create mode 100644 site/src/site/sphinx/http-api.md diff --git a/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java index 5a86f4154..bbce73603 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionManagerImpl.java @@ -29,7 +29,8 @@ public class SessionManagerImpl implements SessionManager { private final InternalCommandManager commandManager; private final Instrumentation instrumentation; private final JobController jobController; - private final long timeoutMillis; + private final long sessionTimeoutMillis; + private final int consumerTimeoutMillis; private final long reaperInterval; private final Map sessions; private final long pid; @@ -42,7 +43,8 @@ public class SessionManagerImpl implements SessionManager { this.commandManager = commandManager; this.jobController = jobController; this.sessions = new ConcurrentHashMap(); - this.timeoutMillis = options.getSessionTimeout(); + this.sessionTimeoutMillis = options.getSessionTimeout(); + this.consumerTimeoutMillis = 5 * 60 * 1000; // 5 minutes this.reaperInterval = options.getReaperInterval(); this.instrumentation = options.getInstrumentation(); this.pid = options.getPid(); @@ -62,9 +64,6 @@ public class SessionManagerImpl implements SessionManager { String sessionId = UUID.randomUUID().toString(); session.put(Session.ID, sessionId); - //Result Distributor - session.setResultDistributor(new SharingResultDistributorImpl(session)); - sessions.put(sessionId, session); return session; } @@ -135,7 +134,7 @@ public class SessionManagerImpl implements SessionManager { // do not close if there is still job running, // e.g. trace command might wait for a long time before condition is met //TODO check background job size - if (now - session.getLastAccessTime() > timeoutMillis && session.getForegroundJob() == null) { + if (now - session.getLastAccessTime() > sessionTimeoutMillis && session.getForegroundJob() == null) { toClose.add(session); } evictConsumers(session); @@ -146,7 +145,7 @@ public class SessionManagerImpl implements SessionManager { if (job != null) { job.interrupt(); } - long timeOutInMinutes = timeoutMillis / 1000 / 60; + long timeOutInMinutes = sessionTimeoutMillis / 1000 / 60; String reason = "session is inactive for " + timeOutInMinutes + " min(s)."; session.getResultDistributor().appendResult(new MessageModel(reason)); this.removeSession(session.getSessionId()); @@ -166,7 +165,7 @@ public class SessionManagerImpl implements SessionManager { long now = System.currentTimeMillis(); for (ResultConsumer consumer : consumers) { long inactiveTime = now - consumer.getLastAccessTime(); - if (inactiveTime > 30000) { + if (inactiveTime > consumerTimeoutMillis) { //inactive duration must be large than pollTimeLimit logger.info("Removing inactive consumer from session, sessionId: {}, consumerId: {}, inactive duration: {}", session.getSessionId(), consumer.getConsumerId(), inactiveTime); diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java index a3d2da354..545c3165a 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/ApiRequest.java @@ -13,8 +13,7 @@ public class ApiRequest { private String requestId; private String sessionId; private String consumerId; - private Integer timeout; - private Map options; + private Integer execTimeout; @Override public String toString() { @@ -24,8 +23,7 @@ public class ApiRequest { ", requestId='" + requestId + '\'' + ", sessionId='" + sessionId + '\'' + ", consumerId='" + consumerId + '\'' + - ", timeout=" + timeout + - ", options=" + options + + ", execTimeout=" + execTimeout + '}'; } @@ -45,14 +43,6 @@ public class ApiRequest { this.command = command; } - public Map getOptions() { - return options; - } - - public void setOptions(Map options) { - this.options = options; - } - public String getRequestId() { return requestId; } @@ -77,11 +67,11 @@ public class ApiRequest { this.consumerId = consumerId; } - public Integer getTimeout() { - return timeout; + public Integer getExecTimeout() { + return execTimeout; } - public void setTimeout(Integer timeout) { - this.timeout = timeout; + public void setExecTimeout(Integer execTimeout) { + this.execTimeout = execTimeout; } } diff --git a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java index 66c5ee364..a5d1ee3a0 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/term/impl/http/api/HttpApiHandler.java @@ -8,8 +8,10 @@ import com.taobao.arthas.core.command.model.*; import com.taobao.arthas.core.distribution.PackingResultDistributor; import com.taobao.arthas.core.distribution.ResultConsumer; import com.taobao.arthas.core.distribution.ResultDistributor; +import com.taobao.arthas.core.distribution.SharingResultDistributor; import com.taobao.arthas.core.distribution.impl.PackingResultDistributorImpl; import com.taobao.arthas.core.distribution.impl.ResultConsumerImpl; +import com.taobao.arthas.core.distribution.impl.SharingResultDistributorImpl; import com.taobao.arthas.core.shell.cli.CliToken; import com.taobao.arthas.core.shell.cli.CliTokens; import com.taobao.arthas.core.shell.cli.Completion; @@ -53,7 +55,6 @@ public class HttpApiHandler { private static final Logger logger = LoggerFactory.getLogger(HttpApiHandler.class); public static final int DEFAULT_EXEC_TIMEOUT = 30000; private final SessionManager sessionManager; - private final AtomicInteger requestIdGenerator = new AtomicInteger(0); private static HttpApiHandler instance; private final InternalCommandManager commandManager; private final JobController jobController; @@ -84,13 +85,13 @@ public class HttpApiHandler { ApiResponse result; String requestBody = null; - String requestId = "req_" + requestIdGenerator.addAndGet(1); + String requestId = null; try { HttpMethod method = request.method(); if (HttpMethod.POST.equals(method)) { requestBody = getBody(request); ApiRequest apiRequest = parseRequest(requestBody); - apiRequest.setRequestId(requestId); + requestId = apiRequest.getRequestId(); result = processRequest(apiRequest); } else { result = createResponse(ApiState.REFUSED, "Unsupported http method: " + method.name()); @@ -210,15 +211,20 @@ public class HttpApiHandler { } //required session + Session session = null; + boolean allowNullSession = ApiAction.EXEC.equals(action); String sessionId = apiRequest.getSessionId(); if (StringUtils.isBlank(sessionId)) { - throw new ApiException("'sessionId' is required"); + if (!allowNullSession) { + throw new ApiException("'sessionId' is required"); + } + } else { + session = sessionManager.getSession(sessionId); + if (session == null) { + throw new ApiException("session not found: " + sessionId); + } + sessionManager.updateAccessTime(session); } - Session session = sessionManager.getSession(sessionId); - if (session == null) { - throw new ApiException("session not found: " + sessionId); - } - sessionManager.updateAccessTime(session); //dispatch requests ApiResponse response = dispatchRequest(action, apiRequest, session); @@ -266,11 +272,14 @@ public class HttpApiHandler { Session session = sessionManager.createSession(); if (session != null) { + //Result Distributor + SharingResultDistributorImpl resultDistributor = new SharingResultDistributorImpl(session); //create consumer ResultConsumer resultConsumer = new ResultConsumerImpl(); - session.getResultDistributor().addConsumer(resultConsumer); + resultDistributor.addConsumer(resultConsumer); + session.setResultDistributor(resultDistributor); - session.getResultDistributor().appendResult(new MessageModel("Welcome to arthas!")); + resultDistributor.appendResult(new MessageModel("Welcome to arthas!")); //welcome message WelcomeModel welcomeModel = new WelcomeModel(); @@ -279,7 +288,7 @@ public class HttpApiHandler { welcomeModel.setTutorials(ArthasBanner.tutorials()); welcomeModel.setPid(PidUtils.currentPid()); welcomeModel.setTime(DateUtils.getCurrentDate()); - session.getResultDistributor().appendResult(welcomeModel); + resultDistributor.appendResult(welcomeModel); //allow input updateSessionInputStatus(session, InputStatus.ALLOW_INPUT); @@ -300,7 +309,10 @@ public class HttpApiHandler { * @param inputStatus */ private void updateSessionInputStatus(Session session, InputStatus inputStatus) { - session.getResultDistributor().appendResult(new InputStatusModel(inputStatus)); + SharingResultDistributor resultDistributor = session.getResultDistributor(); + if (resultDistributor != null) { + resultDistributor.appendResult(new InputStatusModel(inputStatus)); + } } private ApiResponse processJoinSessionRequest(ApiRequest apiRequest, Session session) { @@ -347,78 +359,90 @@ public class HttpApiHandler { * @return */ private ApiResponse processExecRequest(ApiRequest apiRequest, Session session) { - String commandLine = apiRequest.getCommand(); - Map body = new TreeMap(); - body.put("command", commandLine); - - ApiResponse response = new ApiResponse(); - response.setSessionId(session.getSessionId()) - .setBody(body); - - if (!session.tryLock()) { - response.setState(ApiState.REFUSED) - .setMessage("Another command is executing."); - return response; + boolean oneTimeAccess = false; + if (session == null) { + oneTimeAccess = true; + session = sessionManager.createSession(); } - int lock = session.getLock(); - PackingResultDistributor packingResultDistributor = null; - Job job = null; try { - Job foregroundJob = session.getForegroundJob(); - if (foregroundJob != null) { + String commandLine = apiRequest.getCommand(); + Map body = new TreeMap(); + body.put("command", commandLine); + + ApiResponse response = new ApiResponse(); + response.setSessionId(session.getSessionId()) + .setBody(body); + + if (!session.tryLock()) { response.setState(ApiState.REFUSED) - .setMessage("Another job is running."); - logger.info("Another job is running, jobId: {}", foregroundJob.id()); + .setMessage("Another command is executing."); return response; } - //distribute result message both to origin session channel and request channel by CompositeResultDistributor - packingResultDistributor = new PackingResultDistributorImpl(session); - //ResultDistributor resultDistributor = new CompositeResultDistributorImpl(packingResultDistributor, session.getResultDistributor()); - job = this.createJob(commandLine, session, packingResultDistributor); - session.setForegroundJob(job); - updateSessionInputStatus(session, InputStatus.ALLOW_INTERRUPT); + int lock = session.getLock(); + PackingResultDistributor packingResultDistributor = null; + Job job = null; + try { + Job foregroundJob = session.getForegroundJob(); + if (foregroundJob != null) { + response.setState(ApiState.REFUSED) + .setMessage("Another job is running."); + logger.info("Another job is running, jobId: {}", foregroundJob.id()); + return response; + } - job.run(); + packingResultDistributor = new PackingResultDistributorImpl(session); + //distribute result message both to origin session channel and request channel by CompositeResultDistributor + //ResultDistributor resultDistributor = new CompositeResultDistributorImpl(packingResultDistributor, session.getResultDistributor()); + job = this.createJob(commandLine, session, packingResultDistributor); + session.setForegroundJob(job); + updateSessionInputStatus(session, InputStatus.ALLOW_INTERRUPT); - } catch (Throwable e) { - logger.error("Exec command failed:" + e.getMessage() + ", command:" + commandLine, e); - response.setState(ApiState.FAILED).setMessage("Exec command failed:" + e.getMessage()); + job.run(); + + } catch (Throwable e) { + logger.error("Exec command failed:" + e.getMessage() + ", command:" + commandLine, e); + response.setState(ApiState.FAILED).setMessage("Exec command failed:" + e.getMessage()); + return response; + } finally { + if (session.getLock() == lock) { + session.unLock(); + } + } + + //wait for job completed or timeout + Integer timeout = apiRequest.getExecTimeout(); + if (timeout == null || timeout <= 0) { + timeout = DEFAULT_EXEC_TIMEOUT; + } + boolean timeExpired = !waitForJob(job, timeout); + if (timeExpired) { + logger.warn("Job is exceeded time limit, force interrupt it, jobId: {}", job.id()); + job.interrupt(); + response.setState(ApiState.INTERRUPTED).setMessage("The job is exceeded time limit, force interrupt"); + } else { + response.setState(ApiState.SUCCEEDED); + } + + //packing results + body.put("jobId", job.id()); + body.put("jobStatus", job.status()); + body.put("timeExpired", timeExpired); + if (timeExpired) { + body.put("timeout", timeout); + } + body.put("results", packingResultDistributor.getResults()); + + response.setSessionId(session.getSessionId()) + //.setConsumerId(consumerId) + .setBody(body); return response; } finally { - if (session.getLock() == lock) { - session.unLock(); + if (oneTimeAccess) { + sessionManager.removeSession(session.getSessionId()); } } - - //wait for job completed or timeout - Integer timeout = apiRequest.getTimeout(); - if (timeout == null || timeout <= 0) { - timeout = DEFAULT_EXEC_TIMEOUT; - } - boolean timeExpired = !waitForJob(job, timeout); - if (timeExpired) { - logger.warn("Job is exceeded time limit, force interrupt it, jobId: {}", job.id()); - job.interrupt(); - response.setState(ApiState.INTERRUPTED).setMessage("The job is exceeded time limit, force interrupt"); - } else { - response.setState(ApiState.SUCCEEDED); - } - - //packing results - body.put("jobId", job.id()); - body.put("jobStatus", job.status()); - body.put("timeExpired", timeExpired); - if (timeExpired) { - body.put("timeout", timeout); - } - body.put("results", packingResultDistributor.getResults()); - - response.setSessionId(session.getSessionId()) - //.setConsumerId(consumerId) - .setBody(body); - return response; } /** diff --git a/site/src/site/sphinx/en/http-api.md b/site/src/site/sphinx/en/http-api.md new file mode 100644 index 000000000..beb7a3c8a --- /dev/null +++ b/site/src/site/sphinx/en/http-api.md @@ -0,0 +1,711 @@ +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 + +``` +{ + "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. + +``` +{ + "action": "exec", + "command": "" +} +``` + +For example, get the Arthas version number: + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"exec", + "command":"version" +} +' +``` +The response is as follows: + +``` +{ + "state" : "SUCCEEDED", + "sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869", + "body" : { + "results" : [ + { + "type" : "version", + "version" : "3.3.8-SNAPSHOT", + "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** + +``` + [{ + "type" : "version", + "version" : "3.3.8-SNAPSHOT", + "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 + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"init_session" +} +' +``` +Response result: + +``` +{ + "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. + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"join_session", + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e" +} +' +``` +Response result: + +``` +{ + "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: + +``` +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: + +``` +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: + +``` +{ + "body" : { + "results" : [ + { + "inputStatus" : "DISABLED", + "jobId" : 0, + "type" : "input_status" + }, + { + "type" : "message", + "jobId" : 0, + "message" : "Welcome to arthas!" + }, + { + "tutorials" : "https://alibaba.github.io/arthas/arthas-tutorials", + "time" : "2020-08-06 15:56:43", + "type" : "welcome", + "jobId" : 0, + "pid" : "7909", + "wiki" : "https://alibaba.github.io/arthas", + "version" : "3.3.8-SNAPSHOT" + }, + { + "inputStatus" : "ALLOW_INPUT", + "type" : "input_status", + "jobId" : 0 + } + ] + }, + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", + "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2", + "state" : "SUCCEEDED" +} + +``` + + +#### Execute commands asynchronously + +``` +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`: + +``` +{ + "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: + +``` +{ + "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: + +``` +curl -Ss -XPOST http://localhost:8563/api -d ''' +{ + "action":"interrupt_job", + "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a" +} +''' +``` + +``` +{ + "state" : "SUCCEEDED", + "body" : { + "jobStatus" : "TERMINATED", + "jobId" : 3 + } +} +``` + +#### Close session + +Specify the session ID to close the session. + +``` +curl -Ss -XPOST http://localhost:8563/api -d ''' +{ + "action":"close_session", + "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a" +} +''' +``` + +``` +{ + "state" : "SUCCEEDED" +} +``` + +### Web UI + +A Web UI based on the Http API interface, the access address is: +[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 + + +### Special command results + +#### status + +``` +{ + "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: + +``` +{ + "jobId":3, + "message":"The argument 'class-pattern' is required", + "statusCode":-10, + "type":"status" +} +``` + +#### input_status + +``` + { + "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 + +``` + { + "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 + +``` + { + "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`. + +### Others + + +#### 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: + +``` +watch *MathGame prime* '#{ "params" : params, "returnObj" : returnObj, "throwExp": throwExp}' -x 2 -n 5 +``` + +Execute the above command in Telnet shell/WebConsole, the output result: + +``` +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: + +``` +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: + +``` +{ + "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 . diff --git a/site/src/site/sphinx/en/index.md b/site/src/site/sphinx/en/index.md index 4b94ecab1..c74b19423 100644 --- a/site/src/site/sphinx/en/index.md +++ b/site/src/site/sphinx/en/index.md @@ -46,6 +46,7 @@ Contents * [Advanced usage](advanced-use.md) * [Commands](commands.md) * [WebConsole](web-console.md) +* [Http API](http-api.md) * [Docker](docker.md) * [Arthas Spring Boot Starter](spring-boot-starter.md) * [User cases](https://github.com/alibaba/arthas/issues?q=label%3Auser-case) diff --git a/site/src/site/sphinx/http-api.md b/site/src/site/sphinx/http-api.md new file mode 100644 index 000000000..34f72d860 --- /dev/null +++ b/site/src/site/sphinx/http-api.md @@ -0,0 +1,630 @@ +Http API +======== + +### 概览 + +Http API +提供类似RESTful的交互接口,请求和响应均为JSON格式的数据。相对于Telnet/WebConsole的输出非结构化文本数据,Http +API可以提供结构化的数据,支持更复杂的交互功能,比如特定应用场景的一系列诊断操作。 + + +#### 访问地址 + +Http API接口地址为:`http://ip:port/api`,必须使用POST方式提交请求参数。如POST +`http://127.0.0.1:8563/api` 。 + +注意:telnet服务的3658端口与Chrome浏览器有兼容性问题,建议使用http端口8563来访问http接口。 + +#### 请求数据格式 + +``` +{ + "action": "exec", + "requestId": "req112" + "sessionId": "94766d3c-8b39-42d3-8596-98aee3ccbefb" + "consumerId": "955dbd1325334a84972b0f3ac19de4f7_2" + "command": "version", + "execTimeout": "10000" +} +``` +请求数据格式说明: + +* `action` : 请求的动作/行为,可选值请参考"请求Action"小节。 +* `requestId` : 可选请求ID,由客户端生成。 +* `sessionId` : Arthas会话ID,一次性命令不需要设置会话ID。 +* `consumerId` : Arthas消费者ID,用于多人共享会话。 +* `command` : Arthas command line 。 +* `execTimeout` : 命令同步执行的超时时间(ms),默认为30000。 + +注意: 不同的action使用到参数不同,根据具体的action来设置参数。 + +#### 请求Action + +目前支持的请求Action如下: + +* `exec` : 同步执行命令,命令正常结束或者超时后中断命令执行后返回命令的执行结果。 +* `async_exec` : 异步执行命令,立即返回命令的调度结果,命令执行结果通过`pull_results`获取。 +* `interrupt_job` : 中断会话当前的命令,类似Telnet `Ctrl + c`的功能。 +* `pull_results` : 获取异步执行的命令的结果,以http 长轮询(long-polling)方式重复执行 +* `init_session` : 创建会话 +* `join_session` : 加入会话,用于支持多人共享同一个Arthas会话 +* `close_session` : 关闭会话 + +#### 响应状态 + +响应中的state属性表示请求处理状态,取值如下: + +* `SCHEDULED`:异步执行命令时表示已经创建job并已提交到命令执行队列,命令可能还没开始执行或者执行中; +* `SUCCEEDED`:请求处理成功(完成状态); +* `FAILED`:请求处理失败(完成状态),通常附带message说明原因; +* `REFUSED`:请求被拒绝(完成状态),通常附带message说明原因; + +### 一次性命令 + +与执行批处理命令类似,一次性命令以同步方式执行。不需要创建会话,不需要设置`sessionId`选项。 + +``` +{ + "action": "exec", + "command": "" +} +``` + +比如获取Arthas版本号: + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"exec", + "command":"version" +} +' +``` +响应内容如下: + +``` +{ + "state" : "SUCCEEDED", + "sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869", + "body" : { + "results" : [ + { + "type" : "version", + "version" : "3.3.8-SNAPSHOT", + "jobId" : 5 + }, + { + "jobId" : 5, + "statusCode" : 0, + "type" : "status" + } + ], + "timeExpired" : false, + "command" : "version", + "jobStatus" : "TERMINATED", + "jobId" : 5 + } +} +``` +响应数据解析: + +* `state`: 请求处理状态,参考“接口响应状态”说明 +* `sessionId `: Arthas会话ID,一次性命令自动创建及销毁临时会话 +* `body.jobId`: 命令的任务ID,同一任务输出的所有Result都是相同的jobId +* `body.jobStatus`: 任务状态,同步执行正常结束为`TERMINATED ` +* `body.timeExpired`: 任务执行是否超时 +* `body/results`: 命令执行的结果列表 + +**命令结果格式说明** + +``` + [{ + "type" : "version", + "version" : "3.3.8-SNAPSHOT", + "jobId" : 5 + }, + { + "jobId" : 5, + "statusCode" : 0, + "type" : "status" + }] +``` + +* `type` : 命令结果类型,除了`status`等特殊的几个外,其它的保持与Arthas命令名称一致。请参考"[特殊命令结果](#special_command_results)"小节。 +* `jobId` : 处理命令的任务ID。 +* 其它字段为每个不同命令的数据。 + +注意:也可以使用一次性命令的方式执行watch/trace等连续输出的命令,但不能中断命令执行,可能出现长时间没有结束的问题。请参考"[watch命令输出map对象](#change_watch_value_to_map)"小节的示例。 + +请尽量按照以下方式处理: + +* 设置合理的`execTimeout`,到达超时时间后强制中断命令执行,避免长时间挂起。 +* 通过`-n`参数指定较少的执行次数。 +* 保证命令匹配的方法可以成功命中和condition-express编写正确,如果watch/trace没有命中就算指定`-n + 1`也会挂起等待到执行超时。 + +### 会话交互 + +由用户创建及管理Arthas会话,适用于复杂的交互过程。访问流程如下: + +* 创建会话 +* 加入会话(可选) +* 拉取命令结果 +* 执行一系列命令 +* 中断命令执行 +* 关闭会话 + +#### 创建会话 + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"init_session" +} +' +``` +响应结果: + +``` +{ + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", + "consumerId" : "5ae4e5fbab8b4e529ac404f260d4e2d1_1", + "state" : "SUCCEEDED" +} +``` +当前会话ID为: `b09f1353-202c-407b-af24-701b744f971e`, 当前消费者ID为:`5ae4e5fbab8b4e529ac404f260d4e2d1_1 `。 + +#### 加入会话 + +指定要加入的会话ID,服务端将分配一个新的消费者ID。多个消费者可以接收到同一个会话的命令结果。本接口用于支持多人共享同一个会话或刷新页面后重新拉取会话历史记录。 + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"join_session", + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e" +} +' +``` +响应结果: + +``` +{ + "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2", + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", + "state" : "SUCCEEDED" +} +``` +新的消费者ID为`8f7f6ad7bc2d4cb5aa57a530927a95cc_2 ` 。 + +#### 拉取命令结果 + +拉取命令结果消息的action为`pull_results`。请使用Http long-polling方式,定时循环拉取结果消息。 +消费者的超时时间为5分钟,超时后需要调用`join_session`分配新的消费者。每个消费者单独分配一个缓存队列,按顺序拉取命令结果,不会影响到其它消费者。 + +请求参数需要指定会话ID及消费者ID: + +``` +curl -Ss -XPOST http://localhost:8563/api -d ' +{ + "action":"pull_results", + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", + "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2" +} +' +``` + +用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 +``` +注: `json_pp` 工具将输出内容格式化为pretty json。 + +响应内容如下: + +``` +{ + "body" : { + "results" : [ + { + "inputStatus" : "DISABLED", + "jobId" : 0, + "type" : "input_status" + }, + { + "type" : "message", + "jobId" : 0, + "message" : "Welcome to arthas!" + }, + { + "tutorials" : "https://alibaba.github.io/arthas/arthas-tutorials", + "time" : "2020-08-06 15:56:43", + "type" : "welcome", + "jobId" : 0, + "pid" : "7909", + "wiki" : "https://alibaba.github.io/arthas", + "version" : "3.3.8-SNAPSHOT" + }, + { + "inputStatus" : "ALLOW_INPUT", + "type" : "input_status", + "jobId" : 0 + } + ] + }, + "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", + "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2", + "state" : "SUCCEEDED" +} + +``` + + +#### 异步执行命令 + +``` +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" +} +''' +``` + +`async_exec` 的结果: + +``` +{ + "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a", + "state" : "SCHEDULED", + "body" : { + "jobStatus" : "READY", + "jobId" : 3, + "command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" " + } +} +``` + +* `state` : `SCHEDULED` 状态表示已经解析命令生成任务,但未开始执行。 +* `body.jobId` : + 异步执行命令的任务ID,可以根据此任务ID来过滤在`pull_results`输出的命令结果。 +* `body.jobStatus` : 任务状态`READY`表示未开始执行。 + + +查看上面自动拉取结果消息脚本的shell输出: + +``` +{ + "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" +} +``` + +watch命令结果的`value`为watch-experss的值,上面命令中为`{params, returnObj, +throwExp}`,所以watch结果的value为一个长度为3的数组,每个元素分别对应相应顺序的表达式。 +请参考"[watch命令输出map对象](#change_watch_value_to_map)"小节。 + +#### 中断命令执行 + +中断会话正在运行的前台Job(前台任务): + +``` +curl -Ss -XPOST http://localhost:8563/api -d ''' +{ + "action":"interrupt_job", + "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a" +} +''' +``` + +``` +{ + "state" : "SUCCEEDED", + "body" : { + "jobStatus" : "TERMINATED", + "jobId" : 3 + } +} +``` + +#### 关闭会话 +指定会话ID,关闭会话。 + +``` +curl -Ss -XPOST http://localhost:8563/api -d ''' +{ + "action":"close_session", + "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a" +} +''' +``` + +``` +{ + "state" : "SUCCEEDED" +} +``` + +### Web UI + +一个基于Http API接口实现的Web UI,访问地址为: [http://127.0.0.1:8563/ui](http://127.0.0.1:8563/ui) 。 + +已实现功能: + +* 创建会话 +* 复制并打开url加入会话,多人共享会话 +* 周期性拉取会话命令结果消息 +* 刷新页面或者加入会话拉取会话历史命令消息 +* 输入命令/中断命令状态控制 + +待开发功能: + +* 改进将命令结果消息可读性 +* 命令输入支持自动完成及命令模板 +* 提供命令帮助 +* 支持个人选项设置 + + +### 特殊命令结果 + +#### status + +``` +{ + "jobId" : 5, + "statusCode" : 0, + "type" : "status" +} +``` +`type`为`status`表示命令执行状态: + +每个命令执行结束后都有唯一一个status结果。`statusCode` +为0表示执行成功,`statusCode` 为非0值表示执行失败,类似进程退出码(exit code)。 + +命令执行失败时一般会提供错误消息,如: + +``` +{ + "jobId":3, + "message":"The argument 'class-pattern' is required", + "statusCode":-10, + "type":"status" +} +``` + +#### input_status + +``` + { + "inputStatus" : "ALLOW_INPUT", + "type" : "input_status", + "jobId" : 0 + } +``` + +`type`为`input_status`表示输入状态: + +用于UI交互时控制用户输入,每次执行命令前后会发送改变的消息。 +`inputStatus` 的值说明: + +* `ALLOW_INPUT` : + 允许用户输入命令,表示会话没有在执行的前台命令,可以接受新的命令。 +* `ALLOW_INTERRUPT` : + 允许用户中断命令执行,表示当前正在执行命令,用户可以发送`interrupt_job`中断执行。 +* `DISABLED` : 禁用状态,不能输入命令也不能中断命令。 + + +#### command + +``` + { + "type" : "command", + "jobId" : 3, + "state" : "SCHEDULED", + "command" : "watch demo.MathGame primeFactors \"{params, returnObj, throwExp}\" " + } +``` +`type` 为`command`表示输入的命令数据: + +用于交互UI回显用户输入的命令,拉取的会话命令消息历史会包含`command`类型的消息,按顺序处理即可。 + + +#### enhancer + +``` + { + "success" : true, + "jobId" : 3, + "effect" : { + "listenerId" : 3, + "cost" : 24, + "classCount" : 1, + "methodCount" : 1 + }, + "type" : "enhancer" + } +``` +`type`为`enhancer`表示类增强结果: + +`trace/watch/jad/tt`等命令需要对类进行增强,会接收到这个`enhancer`结果。可能出现`enhancer`结果成功,但没有命中方法的情况,客户端可以根据`enhancer`结果提示用户。 + +### 其它 + + +#### watch命令输出map对象 + +watch的结果值由计算`watch-express` ognl表达式产生,可以通过改变ognl表达式来生成想要的值,请参考[OGNL文档](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". + +下面的命令生成map格式的值: + +``` +watch *MathGame prime* '#{ "params" : params, "returnObj" : returnObj, "throwExp": throwExp}' -x 2 -n 5 +``` + +在Telnet shell/WebConsole 中执行上面的命令,输出的结果: + +``` +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, +] +``` + +用Http api 执行上面的命令,注意对JSON双引号转义: + +``` +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 执行结果: + +``` +{ + "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": [ + ... + ] + } + } + }, + ... +} +``` + +可以看到watch结果的value变成map对象,程序可以通过key读取结果。 \ No newline at end of file diff --git a/site/src/site/sphinx/index.md b/site/src/site/sphinx/index.md index 7a3beada3..7b943ab60 100644 --- a/site/src/site/sphinx/index.md +++ b/site/src/site/sphinx/index.md @@ -37,6 +37,7 @@ Contents * [进阶使用](advanced-use.md) * [命令列表](commands.md) * [WebConsole](web-console.md) +* [Http API](http-api.md) * [Docker](docker.md) * [Arthas Spring Boot Starter](spring-boot-starter.md) * [用户案例](https://github.com/alibaba/arthas/issues?q=label%3Auser-case) From 47c2da49244d7b7b44f7bed6592172c9b2e5e6a9 Mon Sep 17 00:00:00 2001 From: gongdewei Date: Fri, 7 Aug 2020 17:12:37 +0800 Subject: [PATCH 2/8] Polish http api doc, add web ui snapshot --- .../src/site/sphinx/_static/arthas-web-ui.png | Bin 0 -> 249971 bytes site/src/site/sphinx/en/http-api.md | 60 +++++++++--------- site/src/site/sphinx/http-api.md | 56 ++++++++-------- 3 files changed, 60 insertions(+), 56 deletions(-) create mode 100644 site/src/site/sphinx/_static/arthas-web-ui.png diff --git a/site/src/site/sphinx/_static/arthas-web-ui.png b/site/src/site/sphinx/_static/arthas-web-ui.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fb25c35d4cdf236c889bb40cd55f9e24d46070 GIT binary patch literal 249971 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
Kl3u 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%0AuCBCJS%~!*tdXoO}Cy7msXdL0|A5Ltp|N% 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%0A1)ovIm{J17T)#?2YtM|6Wu{w+US~5hGWAy8LVtR zxWdGTr+prJk*n@}eX4CN$!-c+VM6!qqdAt0don|!IdYvd!TQh63gMETk(oHKW1H#} zDUnE7j{Wm^fM~Hm#zqo1SE-KO*%z0kiRq&f&79Q=E*%Hd)3#uu^XUs?fvHt5R&aUa z-WME0L*9-e(DBoxV=|x&?RsQ{r#EH#O*NKe>D`@NZs+8{K3Eu-pr=x}+TUDzPZuxP zMG}uEIYd}`gYnRW=BKsQy4m1!)S&=9LPCX4Lwr)4N5lL_bFI4Cxy=46PRVd`F%&JP zjm@|`YJIj@92{9c)(`V?Szh0Omggs08?&IUT6e=Q;uUoxwH%gj9A5~2ZdR|?>%oM5 zf-^nVa|E!GTb!j0VQzP#ax7B-j^!v6j)lIe{lQM<(x+K_Hau!Uj7OF5M& zjY;1aHVFl(DQ8b?>E+ov2@&6ElO&P|u2j#4?F+{F{($0hF%`ozGLTa=#dEk}YcX;z zk31>AqqaMB`5z-v(9(mTdjKz$Miw3u#y>Y?aR%P)G^I1c0TzGhcnI)+Fm4M z7<_;HV2c%+N^_X@>sjW*?SbLgj15*P{dIz#<2vgDUH2my4#fhSBCr0;;e2QGO|LSG zn~5vBMZh-fBhAaeabnpM^=9PAd{|~IIWhvA#$hAZC^JOW5{ce?wkLXIqdhc9T$@B!R;+UA1d_RDF`PALs3%RXbAilyxnFU_0!o0x`X zn|V1>-?X8F%Sg8TGXz(hLVw}%Q|bZVnB`cSw`4X>adR^t_0@iocodACN9F`X z_1ZQ@Zw6n*G*`O$K3gu`FH%!Xp%4#~2ryqFViRceh(uj%Y3D|c!D1ROr;)qPrYsx7 z`STYyvbeDHSl6~0X)<^f%Z0Qv{V5#I04oj~IS+$>ZzW4?vHxCds&|WWIFk%zUCnC~ zj6Mujbe)xj#hSyxKY)LQ{RsU>%}c=i|VVlyvWpmQe) x;=EAMQS5w)mz!<<6~)+ssQ{Q*X^0wEqDt$u|8k3`@h;$FYGh@Ix^&~o{{g?%Pj3JK literal 0 HcmV?d00001 diff --git a/site/src/site/sphinx/en/http-api.md b/site/src/site/sphinx/en/http-api.md index beb7a3c8a..9b2c5f728 100644 --- a/site/src/site/sphinx/en/http-api.md +++ b/site/src/site/sphinx/en/http-api.md @@ -23,7 +23,7 @@ http api. #### Request data format -``` +```json { "action": "exec", "requestId": "req112" @@ -86,7 +86,7 @@ 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": "" @@ -95,7 +95,7 @@ synchronously. No need to create a session, no need to set the For example, get the Arthas version number: -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"exec", @@ -105,7 +105,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' ``` The response is as follows: -``` +```json { "state" : "SUCCEEDED", "sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869", @@ -143,7 +143,7 @@ Response data format description: **Command result format description** -``` +```json [{ "type" : "version", "version" : "3.3.8-SNAPSHOT", @@ -196,7 +196,7 @@ interactive processes. The access process is as follows: #### Create session -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"init_session" @@ -205,7 +205,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' ``` Response result: -``` +```json { "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", "consumerId" : "5ae4e5fbab8b4e529ac404f260d4e2d1_1", @@ -224,7 +224,7 @@ 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", @@ -234,7 +234,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' ``` Response result: -``` +```json { "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2", "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", @@ -256,7 +256,7 @@ 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", @@ -268,7 +268,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' Use Bash scripts to regularly pull results messages: -``` +```bash while true; do curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"pull_results", @@ -282,7 +282,7 @@ Note: The `json_pp` tool formats the output content as pretty json. The response content is as follows: -``` +```json { "body" : { "results" : [ @@ -322,7 +322,7 @@ The response content is as follows: #### Execute commands asynchronously -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ''' { "action":"async_exec", @@ -334,7 +334,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' Response of `async_exec`: -``` +```json { "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a", "state" : "SCHEDULED", @@ -354,7 +354,7 @@ Response of `async_exec`: The shell output of the script that continuously pulls the result message: -``` +```json { "body" : { "results" : [ @@ -452,7 +452,7 @@ Please refer to the section "[Make watch command output a map object](#change_wa Interrupt the running foreground job of the session: -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ''' { "action":"interrupt_job", @@ -461,7 +461,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' ''' ``` -``` +```json { "state" : "SUCCEEDED", "body" : { @@ -475,7 +475,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' Specify the session ID to close the session. -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ''' { "action":"close_session", @@ -484,7 +484,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' ''' ``` -``` +```json { "state" : "SUCCEEDED" } @@ -492,7 +492,9 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' ### Web UI -A Web UI based on the Http API interface, the access address is: +![](../_static/arthas-web-ui.png "arthas 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: @@ -518,7 +520,7 @@ Pending function: #### status -``` +```json { "jobId" : 5, "statusCode" : 0, @@ -536,7 +538,7 @@ 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", @@ -547,7 +549,7 @@ When the command execution fails, an error message is generally provided, such a #### input_status -``` +```json { "inputStatus" : "ALLOW_INPUT", "type" : "input_status", @@ -575,7 +577,7 @@ Possible values ​​of `inputStatus`: #### command -``` +```json { "type" : "command", "jobId" : 3, @@ -591,7 +593,7 @@ of type `command`, which can be processed in order. #### enhancer -``` +```json { "success" : true, "jobId" : 3, @@ -630,13 +632,13 @@ generate the desired value, please refer to 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], @@ -652,7 +654,7 @@ ts=2020-08-06 16:57:20; [cost=0.241735ms] result=@LinkedHashMap[ 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", @@ -664,7 +666,7 @@ EOF Http api execution result: -``` +```json { "body": { ... diff --git a/site/src/site/sphinx/http-api.md b/site/src/site/sphinx/http-api.md index 34f72d860..687b22833 100644 --- a/site/src/site/sphinx/http-api.md +++ b/site/src/site/sphinx/http-api.md @@ -17,7 +17,7 @@ Http API接口地址为:`http://ip:port/api`,必须使用POST方式提交请 #### 请求数据格式 -``` +```json { "action": "exec", "requestId": "req112" @@ -63,7 +63,7 @@ Http API接口地址为:`http://ip:port/api`,必须使用POST方式提交请 与执行批处理命令类似,一次性命令以同步方式执行。不需要创建会话,不需要设置`sessionId`选项。 -``` +```json { "action": "exec", "command": "" @@ -72,7 +72,7 @@ Http API接口地址为:`http://ip:port/api`,必须使用POST方式提交请 比如获取Arthas版本号: -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"exec", @@ -82,7 +82,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' ``` 响应内容如下: -``` +```json { "state" : "SUCCEEDED", "sessionId" : "ee3bc004-4586-43de-bac0-b69d6db7a869", @@ -117,7 +117,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' **命令结果格式说明** -``` +```json [{ "type" : "version", "version" : "3.3.8-SNAPSHOT", @@ -156,7 +156,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' #### 创建会话 -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"init_session" @@ -165,7 +165,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' ``` 响应结果: -``` +```json { "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", "consumerId" : "5ae4e5fbab8b4e529ac404f260d4e2d1_1", @@ -178,7 +178,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' 指定要加入的会话ID,服务端将分配一个新的消费者ID。多个消费者可以接收到同一个会话的命令结果。本接口用于支持多人共享同一个会话或刷新页面后重新拉取会话历史记录。 -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"join_session", @@ -188,7 +188,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' ``` 响应结果: -``` +```json { "consumerId" : "8f7f6ad7bc2d4cb5aa57a530927a95cc_2", "sessionId" : "b09f1353-202c-407b-af24-701b744f971e", @@ -204,7 +204,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' 请求参数需要指定会话ID及消费者ID: -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"pull_results", @@ -216,7 +216,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ' 用Bash脚本定时拉取结果消息: -``` +```bash while true; do curl -Ss -XPOST http://localhost:8563/api -d ' { "action":"pull_results", @@ -229,7 +229,7 @@ while true; do curl -Ss -XPOST http://localhost:8563/api -d ' 响应内容如下: -``` +```json { "body" : { "results" : [ @@ -269,7 +269,7 @@ while true; do curl -Ss -XPOST http://localhost:8563/api -d ' #### 异步执行命令 -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ''' { "action":"async_exec", @@ -281,7 +281,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' `async_exec` 的结果: -``` +```json { "sessionId" : "2b085b5d-883b-4914-ab35-b2c5c1d5aa2a", "state" : "SCHEDULED", @@ -301,7 +301,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' 查看上面自动拉取结果消息脚本的shell输出: -``` +```json { "body" : { "results" : [ @@ -395,7 +395,7 @@ throwExp}`,所以watch结果的value为一个长度为3的数组,每个元 中断会话正在运行的前台Job(前台任务): -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ''' { "action":"interrupt_job", @@ -417,7 +417,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' #### 关闭会话 指定会话ID,关闭会话。 -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d ''' { "action":"close_session", @@ -426,7 +426,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' ''' ``` -``` +```json { "state" : "SUCCEEDED" } @@ -434,6 +434,8 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' ### Web UI +![](_static/arthas-web-ui.png "arthas web ui") + 一个基于Http API接口实现的Web UI,访问地址为: [http://127.0.0.1:8563/ui](http://127.0.0.1:8563/ui) 。 已实现功能: @@ -456,7 +458,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' #### status -``` +```json { "jobId" : 5, "statusCode" : 0, @@ -470,7 +472,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' 命令执行失败时一般会提供错误消息,如: -``` +```json { "jobId":3, "message":"The argument 'class-pattern' is required", @@ -481,7 +483,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' #### input_status -``` +```json { "inputStatus" : "ALLOW_INPUT", "type" : "input_status", @@ -503,7 +505,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' #### command -``` +```json { "type" : "command", "jobId" : 3, @@ -518,7 +520,7 @@ curl -Ss -XPOST http://localhost:8563/api -d ''' #### enhancer -``` +```json { "success" : true, "jobId" : 3, @@ -550,13 +552,13 @@ watch的结果值由计算`watch-express` ognl表达式产生,可以通过改 下面的命令生成map格式的值: -``` +```bash watch *MathGame prime* '#{ "params" : params, "returnObj" : returnObj, "throwExp": throwExp}' -x 2 -n 5 ``` 在Telnet shell/WebConsole 中执行上面的命令,输出的结果: -``` +```bash ts=2020-08-06 16:57:20; [cost=0.241735ms] result=@LinkedHashMap[ @String[params]:@Object[][ @Integer[1], @@ -572,7 +574,7 @@ ts=2020-08-06 16:57:20; [cost=0.241735ms] result=@LinkedHashMap[ 用Http api 执行上面的命令,注意对JSON双引号转义: -``` +```bash curl -Ss -XPOST http://localhost:8563/api -d @- << EOF { "action":"exec", @@ -584,7 +586,7 @@ EOF Http api 执行结果: -``` +```json { "body": { ... From 19ed2103bb2ccc061a2fefbb77ab22945ce2fb35 Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Aug 2020 17:42:54 +0800 Subject: [PATCH 3/8] add tt command scenario. #847 (#1381) --- site/src/site/sphinx/en/tt.md | 2 + site/src/site/sphinx/tt.md | 2 + .../katacoda/command-tt-cn/arthas-boot.md | 16 ++ .../katacoda/command-tt-cn/arthas-demo.md | 10 + tutorials/katacoda/command-tt-cn/finish.md | 12 ++ tutorials/katacoda/command-tt-cn/index.json | 35 ++++ tutorials/katacoda/command-tt-cn/intro.md | 23 +++ tutorials/katacoda/command-tt-cn/tt.md | 189 ++++++++++++++++++ .../katacoda/command-tt-en/arthas-boot.md | 16 ++ .../katacoda/command-tt-en/arthas-demo.md | 11 + tutorials/katacoda/command-tt-en/finish.md | 8 + tutorials/katacoda/command-tt-en/index.json | 35 ++++ tutorials/katacoda/command-tt-en/intro.md | 40 ++++ tutorials/katacoda/command-tt-en/tt.md | 163 +++++++++++++++ 14 files changed, 562 insertions(+) create mode 100644 tutorials/katacoda/command-tt-cn/arthas-boot.md create mode 100644 tutorials/katacoda/command-tt-cn/arthas-demo.md create mode 100644 tutorials/katacoda/command-tt-cn/finish.md create mode 100644 tutorials/katacoda/command-tt-cn/index.json create mode 100644 tutorials/katacoda/command-tt-cn/intro.md create mode 100644 tutorials/katacoda/command-tt-cn/tt.md create mode 100644 tutorials/katacoda/command-tt-en/arthas-boot.md create mode 100644 tutorials/katacoda/command-tt-en/arthas-demo.md create mode 100644 tutorials/katacoda/command-tt-en/finish.md create mode 100644 tutorials/katacoda/command-tt-en/index.json create mode 100644 tutorials/katacoda/command-tt-en/intro.md create mode 100644 tutorials/katacoda/command-tt-en/tt.md diff --git a/site/src/site/sphinx/en/tt.md b/site/src/site/sphinx/en/tt.md index e95fcb9ba..39f1740fe 100644 --- a/site/src/site/sphinx/en/tt.md +++ b/site/src/site/sphinx/en/tt.md @@ -1,6 +1,8 @@ tt == +[`tt` online tutorial](https://alibaba.github.io/arthas/arthas-tutorials?language=en&id=command-tt) + Check the `parameters`, `return values` and `exceptions` of the methods at different times. `watch` is a powerful command but due to its feasibility and complexity, it's quite hard to locate the issue effectively. diff --git a/site/src/site/sphinx/tt.md b/site/src/site/sphinx/tt.md index 7880f148d..82bfcbb4e 100644 --- a/site/src/site/sphinx/tt.md +++ b/site/src/site/sphinx/tt.md @@ -1,6 +1,8 @@ tt === +[`tt`在线教程](https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=command-tt) + > 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测 `watch` 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。 diff --git a/tutorials/katacoda/command-tt-cn/arthas-boot.md b/tutorials/katacoda/command-tt-cn/arthas-boot.md new file mode 100644 index 000000000..84ef525a2 --- /dev/null +++ b/tutorials/katacoda/command-tt-cn/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +在新的`Terminal 2`里,下载`arthas-boot.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot`是`Arthas`的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。 + +选择第一个进程,输入 `1`{{execute T2}} ,再`Enter/回车`: + +Attach成功之后,会打印Arthas LOGO。输入 `help`{{execute T2}} 可以获取到更多的帮助信息。 + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-tt-cn/arthas-demo.md b/tutorials/katacoda/command-tt-cn/arthas-demo.md new file mode 100644 index 000000000..f1136e88e --- /dev/null +++ b/tutorials/katacoda/command-tt-cn/arthas-demo.md @@ -0,0 +1,10 @@ + + + + +下载`arthas-demo.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。 diff --git a/tutorials/katacoda/command-tt-cn/finish.md b/tutorials/katacoda/command-tt-cn/finish.md new file mode 100644 index 000000000..37e614e80 --- /dev/null +++ b/tutorials/katacoda/command-tt-cn/finish.md @@ -0,0 +1,12 @@ + +在“tt”中,我们演示了了Arthas的tt命令。如果有更多的技巧或者使用疑问,欢迎在Issue里提出。 + +* Issues: https://github.com/alibaba/arthas/issues +* 文档: https://alibaba.github.io/arthas + + +如果您在使用Arthas,请让我们知道,您的使用对我们非常重要:[查看](https://github.com/alibaba/arthas/issues/111) + +欢迎关注公众号,获取Arthas项目的信息,源码分析,案例实践。 + +![Arthas公众号](/arthas/scenarios/common-resources/assets/qrcode_gongzhonghao.jpg) \ No newline at end of file diff --git a/tutorials/katacoda/command-tt-cn/index.json b/tutorials/katacoda/command-tt-cn/index.json new file mode 100644 index 000000000..892536e15 --- /dev/null +++ b/tutorials/katacoda/command-tt-cn/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas tt命令", + "description": "Arthas tt命令", + "difficulty": "精通者", + "time": "10-20 分钟", + "details": { + "steps": [ + { + "title": "启动arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "启动arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "tt命令", + "text": "tt.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-tt-cn/intro.md b/tutorials/katacoda/command-tt-cn/intro.md new file mode 100644 index 000000000..8abaaf7f1 --- /dev/null +++ b/tutorials/katacoda/command-tt-cn/intro.md @@ -0,0 +1,23 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。 + +`Arthas` 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。 + +当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: + +- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? +- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? +- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? +- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! +- 是否有一个全局视角来查看系统的运行状况? +- 有什么办法可以监控到JVM的实时运行状态? +- 怎么快速定位应用的热点,生成火焰图? + +本教程会以一个简单的应用为例,演示tt命令。 + +* Github: https://github.com/alibaba/arthas +* 文档: https://alibaba.github.io/arthas/ diff --git a/tutorials/katacoda/command-tt-cn/tt.md b/tutorials/katacoda/command-tt-cn/tt.md new file mode 100644 index 000000000..9662ad7b4 --- /dev/null +++ b/tutorials/katacoda/command-tt-cn/tt.md @@ -0,0 +1,189 @@ + +> 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测 + +`watch` 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。 + +这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。 + +于是乎,TimeTunnel 命令就诞生了。 + +### 使用参考 + +#### 记录调用 + +对于一个最基本的使用来说,就是记录下当前方法的每次调用环境现场。 + +`tt -t demo.MathGame primeFactors`{{execute T2}} + +```bash +$ tt -t demo.MathGame primeFactors +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms. + INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD +------------------------------------------------------------------------------------------------------------------------------------- + 1000 2018-12-04 11:15:38 1.096236 false true 0x4b67cf4d MathGame primeFactors + 1001 2018-12-04 11:15:39 0.191848 false true 0x4b67cf4d MathGame primeFactors + 1002 2018-12-04 11:15:40 0.069523 false true 0x4b67cf4d MathGame primeFactors + 1003 2018-12-04 11:15:41 0.186073 false true 0x4b67cf4d MathGame primeFactors + 1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors +``` + +- 命令参数解析 + + - `-t` + + tt 命令有很多个主参数,`-t` 就是其中之一。这个参数的表明希望记录下类 `*Test` 的 `print` 方法的每次执行情况。 + + - `-n 3` + + 当你执行一个调用量不高的方法时可能你还能有足够的时间用 `CTRL+C` 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。 + + 此时你可以通过 `-n` 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断tt命令的记录过程,避免人工操作无法停止的情况。 + +- 表格字段说明 + +|表格字段|字段解释| +|---|---| +|INDEX|时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。| +|TIMESTAMP|方法执行的本机时间,记录了这个时间片段所发生的本机时间| +|COST(ms)|方法执行的耗时| +|IS-RET|方法是否以正常返回的形式结束| +|IS-EXP|方法是否以抛异常的形式结束| +|OBJECT|执行对象的`hashCode()`,注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体| +|CLASS|执行的类名| +|METHOD|执行的方法名| + +- 条件表达式 + + 不知道大家是否有在使用过程中遇到以下困惑 + * Arthas 似乎很难区分出重载的方法 + * 我只需要观察特定参数,但是 tt 却全部都给我记录了下来 + + 条件表达式也是用 `OGNL` 来编写,核心的判断对象依然是 `Advice` 对象。除了 `tt` 命令之外,`watch`、`trace`、`stack` 命令也都支持条件表达式。 + +- 解决方法重载 + + `tt -t *Test print params.length==1` + + 通过制定参数个数的形式解决不同的方法签名,如果参数个数一样,你还可以这样写 + + `tt -t *Test print 'params[1] instanceof Integer'` + +- 解决指定参数 + + `tt -t *Test print params[0].mobile=="13989838402"` + +- 构成条件表达式的 `Advice` 对象 + + 前边看到了很多条件表达式中,都使用了 `params[0]`,有关这个变量的介绍,请参考[表达式核心变量](https://alibaba.github.io/arthas/advice-class.html) + +#### 检索调用记录 + +当你用 `tt` 记录了一大片的时间片段之后,你希望能从中筛选出自己需要的时间片段,这个时候你就需要对现有记录进行检索。 + +假设我们有这些记录 + +`tt -l`{{execute T2}} + +```bash +$ tt -l + INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD +------------------------------------------------------------------------------------------------------------------------------------- + 1000 2018-12-04 11:15:38 1.096236 false true 0x4b67cf4d MathGame primeFactors + 1001 2018-12-04 11:15:39 0.191848 false true 0x4b67cf4d MathGame primeFactors + 1002 2018-12-04 11:15:40 0.069523 false true 0x4b67cf4d MathGame primeFactors + 1003 2018-12-04 11:15:41 0.186073 false true 0x4b67cf4d MathGame primeFactors + 1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors + 9 + 1005 2018-12-04 11:15:43 0.4776 false true 0x4b67cf4d MathGame primeFactors +Affect(row-cnt:6) cost in 4 ms. +``` + +我需要筛选出 `primeFactors` 方法的调用信息 + +`tt -s 'method.name=="primeFactors"'`{{execute T2}} + +```bash +$ tt -s 'method.name=="primeFactors"' + INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD +------------------------------------------------------------------------------------------------------------------------------------- + 1000 2018-12-04 11:15:38 1.096236 false true 0x4b67cf4d MathGame primeFactors + 1001 2018-12-04 11:15:39 0.191848 false true 0x4b67cf4d MathGame primeFactors + 1002 2018-12-04 11:15:40 0.069523 false true 0x4b67cf4d MathGame primeFactors + 1003 2018-12-04 11:15:41 0.186073 false true 0x4b67cf4d MathGame primeFactors + 1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors + 9 + 1005 2018-12-04 11:15:43 0.4776 false true 0x4b67cf4d MathGame primeFactors +Affect(row-cnt:6) cost in 607 ms. +``` + +你需要一个 `-s` 参数。同样的,搜索表达式的核心对象依旧是 `Advice` 对象。 + +#### 查看调用信息 + +对于具体一个时间片的信息而言,你可以通过 `-i` 参数后边跟着对应的 `INDEX` 编号查看到他的详细信息。 + +`tt -i 1003`{{execute T2}} + +```bash +$ tt -i 1003 + INDEX 1003 + GMT-CREATE 2018-12-04 11:15:41 + COST(ms) 0.186073 + OBJECT 0x4b67cf4d + CLASS demo.MathGame + METHOD primeFactors + IS-RETURN false + IS-EXCEPTION true + PARAMETERS[0] @Integer[-564322413] + THROW-EXCEPTION java.lang.IllegalArgumentException: number is: -564322413, need >= 2 + at demo.MathGame.primeFactors(MathGame.java:46) + at demo.MathGame.run(MathGame.java:24) + at demo.MathGame.main(MathGame.java:16) + +Affect(row-cnt:1) cost in 11 ms. +``` + +#### 重做一次调用 + +当你稍稍做了一些调整之后,你可能需要前端系统重新触发一次你的调用,此时得求爷爷告奶奶的需要前端配合联调的同学再次发起一次调用。而有些场景下,这个调用不是这么好触发的。 + +`tt` 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 `INDEX` 编号的时间片自主发起一次调用,从而解放你的沟通成本。此时你需要 `-p` 参数。通过 `--replay-times` 指定 +调用次数,通过 `--replay-interval` 指定多次调用间隔(单位ms, 默认1000ms) + +`tt -i 1004 -p`{{execute T2}} + +```bash +$ tt -i 1004 -p + RE-INDEX 1004 + GMT-REPLAY 2018-12-04 11:26:00 + OBJECT 0x4b67cf4d + CLASS demo.MathGame + METHOD primeFactors + PARAMETERS[0] @Integer[946738738] + IS-RETURN true + IS-EXCEPTION false + COST(ms) 0.186073 + RETURN-OBJ @ArrayList[ + @Integer[2], + @Integer[11], + @Integer[17], + @Integer[2531387], + ] +Time fragment[1004] successfully replayed. +Affect(row-cnt:1) cost in 14 ms. +``` + +你会发现结果虽然一样,但调用的路径发生了变化,有原来的程序发起变成了 Arthas 自己的内部线程发起的调用了。 + +- 需要强调的点 + + 1. **ThreadLocal 信息丢失** + + 很多框架偷偷的将一些环境变量信息塞到了发起调用线程的 ThreadLocal 中,由于调用线程发生了变化,这些 ThreadLocal 线程信息无法通过 Arthas 保存,所以这些信息将会丢失。 + + 一些常见的 CASE 比如:鹰眼的 TraceId 等。 + + 2. **引用的对象** + + 需要强调的是,`tt` 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 `tt` 查看的时候将无法看到当时最准确的值。这也是为什么 `watch` 命令存在的意义。 diff --git a/tutorials/katacoda/command-tt-en/arthas-boot.md b/tutorials/katacoda/command-tt-en/arthas-boot.md new file mode 100644 index 000000000..b9f9cc04f --- /dev/null +++ b/tutorials/katacoda/command-tt-en/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +In the new `Terminal 2`, download `arthas-boot.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot` is the launcher for `Arthas`. It lists all the Java processes, and the user can select the target process to be diagnosed. + +Select the first process, type `1`{{execute T2}} ,then type `Enter`: + +After the Attach is successful, Arthas LOGO is printed. Enter `help`{{execute T2}} for more help. + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-tt-en/arthas-demo.md b/tutorials/katacoda/command-tt-en/arthas-demo.md new file mode 100644 index 000000000..7ba2cf1fa --- /dev/null +++ b/tutorials/katacoda/command-tt-en/arthas-demo.md @@ -0,0 +1,11 @@ + + + + +Download `arthas-demo.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo` is a very simple program that randomly generates integers, performs factorization, and prints the results. +If the generated random number is negative, a error message will be printed. diff --git a/tutorials/katacoda/command-tt-en/finish.md b/tutorials/katacoda/command-tt-en/finish.md new file mode 100644 index 000000000..fc74abff4 --- /dev/null +++ b/tutorials/katacoda/command-tt-en/finish.md @@ -0,0 +1,8 @@ + +The `tt Tutorial` demonstrates the usage of tt. If you have more tips or questions, please feel free to ask in Issue. + +* Issues: https://github.com/alibaba/arthas/issues +* Documentation: https://alibaba.github.io/arthas + + +If you are using Arthas, please let us know. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111) \ No newline at end of file diff --git a/tutorials/katacoda/command-tt-en/index.json b/tutorials/katacoda/command-tt-en/index.json new file mode 100644 index 000000000..9f2874844 --- /dev/null +++ b/tutorials/katacoda/command-tt-en/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas tt Command", + "description": "Arthas tt Command", + "difficulty": "master", + "time": "10-20 minutes", + "details": { + "steps": [ + { + "title": "Arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "Start arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "tt Command", + "text": "tt.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-tt-en/intro.md b/tutorials/katacoda/command-tt-en/intro.md new file mode 100644 index 000000000..16971bf6d --- /dev/null +++ b/tutorials/katacoda/command-tt-en/intro.md @@ -0,0 +1,40 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers. + +`Arthas` supports JDK 6+, supports Linux/Mac/Windows. + +## Background + +Oftentimes the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. What’s even worse, debugging in production environment is unacceptable, as it will suspend all the threads, leading to services downtime. + +Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be reproduced easily in a different environment, or even disappear once restarted. + +And if you’re thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle: test, staging, and then to production. Time is money! This approach is inefficient! Worse still, the issue may not be fixed since it might be irreproducible once the JVM is restarted, as described above. + +Arthas is built to solve these issues. A developer can troubleshoot production issues on the fly. No JVM restart, no additional code changes. Arthas works as an observer, that is, it will never suspend your running threads. + +## Key features + +- Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts) +- Decompile a class to ensure the code is running as expected. +- Check classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc. +- Check the method invocation details, e.g. method parameter, returned values, exceptions and etc. +- Check the stack trace of specified method invocation. This is useful when a developer wants to know the caller of the method. +- Trace the method invocation to find slow sub-invocations. +- Monitor method invocation statistics, e.g. QPS (Query Per Second), RT (Return Time), success rate and etc. +- Monitor system metrics, thread states and CPU usage, GC statistics and etc. +- Supports command line interactive mode, with auto-complete feature enabled. +- Supports telnet and WebSocket, which enables both local and remote diagnostics with command line and browsers. +- Supports profiler/Flame Graph +- Supports JDK 6+ +- Supports Linux/Mac/Windows + +This tutorial takes a simple application as an example to demonstrate the the usage of tt. + +* Github: https://github.com/alibaba/arthas +* Docs: https://alibaba.github.io/arthas/ + diff --git a/tutorials/katacoda/command-tt-en/tt.md b/tutorials/katacoda/command-tt-en/tt.md new file mode 100644 index 000000000..9ab905de6 --- /dev/null +++ b/tutorials/katacoda/command-tt-en/tt.md @@ -0,0 +1,163 @@ + +Check the `parameters`, `return values` and `exceptions` of the methods at different times. + +`watch` is a powerful command but due to its feasibility and complexity, it's quite hard to locate the issue effectively. + +In such difficulties, `tt` comes into play. + +With the help of `tt` (*TimeTunnel*), you can check the contexts of the methods at different times in execution history. + +### Usage + +#### Record method calls + +`tt -t demo.MathGame primeFactors`{{execute T2}} + +```bash +$ tt -t demo.MathGame primeFactors +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms. + INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD +------------------------------------------------------------------------------------------------------------------------------------- + 1000 2018-12-04 11:15:38 1.096236 false true 0x4b67cf4d MathGame primeFactors + 1001 2018-12-04 11:15:39 0.191848 false true 0x4b67cf4d MathGame primeFactors + 1002 2018-12-04 11:15:40 0.069523 false true 0x4b67cf4d MathGame primeFactors + 1003 2018-12-04 11:15:41 0.186073 false true 0x4b67cf4d MathGame primeFactors + 1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors +``` + +* `-t` + + record the calling context of the method `demo.MathGame primeFactors` + +* `-n 3` + + limit the number of the records (avoid overflow for too many records; with `-n` option, Arthas can automatically stop recording once the records reach the specified limit) + +* Property + +|Name|Specification| +|---|---| +|INDEX|the index for each call based on time| +|TIMESTAMP|time to invoke the method| +|COST(ms)|time cost of the method call| +|IS-RET|whether method exits with normal return| +|IS-EXP|whether method failed with exceptions| +|OBJECT|`hashCode()` of the object invoking the method| +|CLASS|class name of the object invoking the method| +|METHOD|method being invoked| + +* Condition expression + +Tips: +1. `tt -t *Test print params.length==1` with different amounts of parameters; +2. `tt -t *Test print 'params[1] instanceof Integer'` with different types of parameters; +3. `tt -t *Test print params[0].mobile=="13989838402"` with specified parameter. + +Advanced: +* [Critical fields in expression](https://alibaba.github.io/arthas/en/advice-class.html) +* [Special usage](https://github.com/alibaba/arthas/issues/71) +* [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html) + +#### List all records + +`tt -l`{{execute T2}} + +```bash +$ tt -l + INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD +------------------------------------------------------------------------------------------------------------------------------------- + 1000 2018-12-04 11:15:38 1.096236 false true 0x4b67cf4d MathGame primeFactors + 1001 2018-12-04 11:15:39 0.191848 false true 0x4b67cf4d MathGame primeFactors + 1002 2018-12-04 11:15:40 0.069523 false true 0x4b67cf4d MathGame primeFactors + 1003 2018-12-04 11:15:41 0.186073 false true 0x4b67cf4d MathGame primeFactors + 1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors + 9 + 1005 2018-12-04 11:15:43 0.4776 false true 0x4b67cf4d MathGame primeFactors +Affect(row-cnt:6) cost in 4 ms. +``` + + +#### Searching for records + +`tt -s 'method.name=="primeFactors"'`{{execute T2}} + +```bash +$ tt -s 'method.name=="primeFactors"' + INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD +------------------------------------------------------------------------------------------------------------------------------------- + 1000 2018-12-04 11:15:38 1.096236 false true 0x4b67cf4d MathGame primeFactors + 1001 2018-12-04 11:15:39 0.191848 false true 0x4b67cf4d MathGame primeFactors + 1002 2018-12-04 11:15:40 0.069523 false true 0x4b67cf4d MathGame primeFactors + 1003 2018-12-04 11:15:41 0.186073 false true 0x4b67cf4d MathGame primeFactors + 1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors + 9 + 1005 2018-12-04 11:15:43 0.4776 false true 0x4b67cf4d MathGame primeFactors +Affect(row-cnt:6) cost in 607 ms. +``` + +Advanced: +* [Critical fields in expression](advice-class.md) + +#### Check context of the call + +`tt -i 1003`{{execute T2}} + +Using `tt -i ` to check a specific calling details. + +```bash +$ tt -i 1003 + INDEX 1003 + GMT-CREATE 2018-12-04 11:15:41 + COST(ms) 0.186073 + OBJECT 0x4b67cf4d + CLASS demo.MathGame + METHOD primeFactors + IS-RETURN false + IS-EXCEPTION true + PARAMETERS[0] @Integer[-564322413] + THROW-EXCEPTION java.lang.IllegalArgumentException: number is: -564322413, need >= 2 + at demo.MathGame.primeFactors(MathGame.java:46) + at demo.MathGame.run(MathGame.java:24) + at demo.MathGame.main(MathGame.java:16) + +Affect(row-cnt:1) cost in 11 ms. +``` + +### Replay record + +Since Arthas stores the context of the call, you can even *replay* the method calling afterwards with extra option `-p` to replay the issue for advanced troubleshooting, option `--replay-times` +define the replay execution times, option `--replay-interval` define the interval(unit in ms,with default value 1000) of replays + +`tt -i 1004 -p`{{execute T2}} + +```bash +$ tt -i 1004 -p + RE-INDEX 1004 + GMT-REPLAY 2018-12-04 11:26:00 + OBJECT 0x4b67cf4d + CLASS demo.MathGame + METHOD primeFactors + PARAMETERS[0] @Integer[946738738] + IS-RETURN true + IS-EXCEPTION false + RETURN-OBJ @ArrayList[ + @Integer[2], + @Integer[11], + @Integer[17], + @Integer[2531387], + ] +Time fragment[1004] successfully replayed. +Affect(row-cnt:1) cost in 14 ms. +``` + +F.Y.I + +1. **Loss** of the `ThreadLocal` + + Arthas save params into an array, then invoke the method with the params again. The method execute in another thread, so the `ThreadLocal` **lost**. + +1. params may be modified + + Arthas save params into an array, they are object references. The Objects may be modified by other code. + From 70910d452aeed44f85acf998159c39678f460c7d Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Aug 2020 17:46:29 +0800 Subject: [PATCH 4/8] add trace command scenario. #847 (#1379) --- site/src/site/sphinx/en/trace.md | 2 + site/src/site/sphinx/trace.md | 2 + .../katacoda/command-trace-cn/arthas-boot.md | 16 ++ .../katacoda/command-trace-cn/arthas-demo.md | 10 + tutorials/katacoda/command-trace-cn/finish.md | 12 ++ .../katacoda/command-trace-cn/index.json | 35 ++++ tutorials/katacoda/command-trace-cn/intro.md | 23 ++ tutorials/katacoda/command-trace-cn/trace.md | 198 ++++++++++++++++++ .../katacoda/command-trace-en/arthas-boot.md | 16 ++ .../katacoda/command-trace-en/arthas-demo.md | 11 + tutorials/katacoda/command-trace-en/finish.md | 8 + .../katacoda/command-trace-en/index.json | 35 ++++ tutorials/katacoda/command-trace-en/intro.md | 40 ++++ tutorials/katacoda/command-trace-en/trace.md | 194 +++++++++++++++++ 14 files changed, 602 insertions(+) create mode 100644 tutorials/katacoda/command-trace-cn/arthas-boot.md create mode 100644 tutorials/katacoda/command-trace-cn/arthas-demo.md create mode 100644 tutorials/katacoda/command-trace-cn/finish.md create mode 100644 tutorials/katacoda/command-trace-cn/index.json create mode 100644 tutorials/katacoda/command-trace-cn/intro.md create mode 100644 tutorials/katacoda/command-trace-cn/trace.md create mode 100644 tutorials/katacoda/command-trace-en/arthas-boot.md create mode 100644 tutorials/katacoda/command-trace-en/arthas-demo.md create mode 100644 tutorials/katacoda/command-trace-en/finish.md create mode 100644 tutorials/katacoda/command-trace-en/index.json create mode 100644 tutorials/katacoda/command-trace-en/intro.md create mode 100644 tutorials/katacoda/command-trace-en/trace.md diff --git a/site/src/site/sphinx/en/trace.md b/site/src/site/sphinx/en/trace.md index e50bd541f..a95b83a96 100644 --- a/site/src/site/sphinx/en/trace.md +++ b/site/src/site/sphinx/en/trace.md @@ -1,6 +1,8 @@ trace ===== +[`trace` online tutorial](https://alibaba.github.io/arthas/arthas-tutorials?language=en&id=command-trace) + > Trace method calling path, and output the time cost for each node in the path. `trace` can track the calling path specified by `class-pattern` / `method-pattern`, and calculate the time cost on the whole path. diff --git a/site/src/site/sphinx/trace.md b/site/src/site/sphinx/trace.md index 2d02e2d32..e5b764e9c 100644 --- a/site/src/site/sphinx/trace.md +++ b/site/src/site/sphinx/trace.md @@ -1,6 +1,8 @@ trace === +[`trace`在线教程](https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=command-trace) + > 方法内部调用路径,并输出方法路径上的每个节点上耗时 `trace` 命令能主动搜索 `class-pattern`/`method-pattern` 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。 diff --git a/tutorials/katacoda/command-trace-cn/arthas-boot.md b/tutorials/katacoda/command-trace-cn/arthas-boot.md new file mode 100644 index 000000000..84ef525a2 --- /dev/null +++ b/tutorials/katacoda/command-trace-cn/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +在新的`Terminal 2`里,下载`arthas-boot.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot`是`Arthas`的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。 + +选择第一个进程,输入 `1`{{execute T2}} ,再`Enter/回车`: + +Attach成功之后,会打印Arthas LOGO。输入 `help`{{execute T2}} 可以获取到更多的帮助信息。 + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-trace-cn/arthas-demo.md b/tutorials/katacoda/command-trace-cn/arthas-demo.md new file mode 100644 index 000000000..f1136e88e --- /dev/null +++ b/tutorials/katacoda/command-trace-cn/arthas-demo.md @@ -0,0 +1,10 @@ + + + + +下载`arthas-demo.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。 diff --git a/tutorials/katacoda/command-trace-cn/finish.md b/tutorials/katacoda/command-trace-cn/finish.md new file mode 100644 index 000000000..3eb9d1f50 --- /dev/null +++ b/tutorials/katacoda/command-trace-cn/finish.md @@ -0,0 +1,12 @@ + +在“mbean”中,我们演示了了Arthas的mbean命令。如果有更多的技巧或者使用疑问,欢迎在Issue里提出。 + +* Issues: https://github.com/alibaba/arthas/issues +* 文档: https://alibaba.github.io/arthas + + +如果您在使用Arthas,请让我们知道,您的使用对我们非常重要:[查看](https://github.com/alibaba/arthas/issues/111) + +欢迎关注公众号,获取Arthas项目的信息,源码分析,案例实践。 + +![Arthas公众号](/arthas/scenarios/common-resources/assets/qrcode_gongzhonghao.jpg) \ No newline at end of file diff --git a/tutorials/katacoda/command-trace-cn/index.json b/tutorials/katacoda/command-trace-cn/index.json new file mode 100644 index 000000000..4d47397ba --- /dev/null +++ b/tutorials/katacoda/command-trace-cn/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas mbean命令", + "description": "Arthas mbean命令", + "difficulty": "精通者", + "time": "10-20 分钟", + "details": { + "steps": [ + { + "title": "启动arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "启动arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "mbean命令", + "text": "mbean.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-trace-cn/intro.md b/tutorials/katacoda/command-trace-cn/intro.md new file mode 100644 index 000000000..a06865fd7 --- /dev/null +++ b/tutorials/katacoda/command-trace-cn/intro.md @@ -0,0 +1,23 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。 + +`Arthas` 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。 + +当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: + +- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? +- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? +- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? +- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! +- 是否有一个全局视角来查看系统的运行状况? +- 有什么办法可以监控到JVM的实时运行状态? +- 怎么快速定位应用的热点,生成火焰图? + +本教程会以一个简单的应用为例,演示mbean命令。 + +* Github: https://github.com/alibaba/arthas +* 文档: https://alibaba.github.io/arthas/ diff --git a/tutorials/katacoda/command-trace-cn/trace.md b/tutorials/katacoda/command-trace-cn/trace.md new file mode 100644 index 000000000..0b5d0ee25 --- /dev/null +++ b/tutorials/katacoda/command-trace-cn/trace.md @@ -0,0 +1,198 @@ + +> 方法内部调用路径,并输出方法路径上的每个节点上耗时 + +`trace` 命令能主动搜索 `class-pattern`/`method-pattern` 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。 + +### 参数说明 + +|参数名称|参数说明| +|---:|:---| +|*class-pattern*|类名表达式匹配| +|*method-pattern*|方法名表达式匹配| +|*condition-express*|条件表达式| +|[E]|开启正则表达式匹配,默认为通配符匹配| +|`[n:]`|命令执行次数| +|`#cost`|方法执行耗时| + +这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写`"{params,returnObj}"`,只要是一个合法的 ognl 表达式,都能被正常支持。 + +观察的维度也比较多,主要体现在参数 `advice` 的数据结构上。`Advice` 参数最主要是封装了通知节点的所有信息。 + + +请参考[表达式核心变量](advice-class.md)中关于该节点的描述。 + +* 特殊用法请参考:[https://github.com/alibaba/arthas/issues/71](https://github.com/alibaba/arthas/issues/71) +* OGNL表达式官网:[https://commons.apache.org/proper/commons-ognl/language-guide.html](https://commons.apache.org/proper/commons-ognl/language-guide.html) + +很多时候我们只想看到某个方法的rt大于某个时间之后的trace结果,现在Arthas可以按照方法执行的耗时来进行过滤了,例如`trace *StringUtils isBlank '#cost>100'`表示当执行时间超过100ms的时候,才会输出trace的结果。 + +> watch/stack/trace这个三个命令都支持`#cost` + +### 注意事项 + +`trace` 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路。 + +参考:[Trace命令的实现原理](https://github.com/alibaba/arthas/issues/597) + +3.3.0 版本后,可以使用动态Trace功能,不断增加新的匹配类,参考下面的示例。 + + +### 使用参考 + +#### trace函数 + +`trace demo.MathGame run`{{execute T2}} + +```bash +$ trace demo.MathGame run +Press Q or Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 28 ms. +`---ts=2019-12-04 00:45:08;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.617465ms] demo.MathGame:run() + `---[0.078946ms] demo.MathGame:primeFactors() #24 [throws Exception] + +`---ts=2019-12-04 00:45:09;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[1.276874ms] demo.MathGame:run() + `---[0.03752ms] demo.MathGame:primeFactors() #24 [throws Exception] +``` + +#### trace次数限制 + +如果方法调用的次数很多,那么可以用`-n`参数指定捕捉结果的次数。比如下面的例子里,捕捉到一次调用就退出命令。 + +`trace demo.MathGame run -n 1`{{execute T2}} + +```bash +$ trace demo.MathGame run -n 1 +Press Q or Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 20 ms. +`---ts=2019-12-04 00:45:53;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.549379ms] demo.MathGame:run() + +---[0.059839ms] demo.MathGame:primeFactors() #24 + `---[0.232887ms] demo.MathGame:print() #25 + +Command execution times exceed limit: 1, so command will exit. You can set it with -n option. +``` + + +#### 包含jdk的函数 + +* `--skipJDKMethod ` skip jdk method trace, default value true. + +`trace --skipJDKMethod false demo.MathGame run`{{execute T2}} + +默认情况下,trace不会包含jdk里的函数调用,如果希望trace jdk里的函数,需要显式设置`--skipJDKMethod false`。 + +```bash +$ trace --skipJDKMethod false demo.MathGame run +Press Q or Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 60 ms. +`---ts=2019-12-04 00:44:41;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[1.357742ms] demo.MathGame:run() + +---[0.028624ms] java.util.Random:nextInt() #23 + +---[0.045534ms] demo.MathGame:primeFactors() #24 [throws Exception] + +---[0.005372ms] java.lang.StringBuilder:() #28 + +---[0.012257ms] java.lang.Integer:valueOf() #28 + +---[0.234537ms] java.lang.String:format() #28 + +---[min=0.004539ms,max=0.005778ms,total=0.010317ms,count=2] java.lang.StringBuilder:append() #28 + +---[0.013777ms] java.lang.Exception:getMessage() #28 + +---[0.004935ms] java.lang.StringBuilder:toString() #28 + `---[0.06941ms] java.io.PrintStream:println() #28 + +`---ts=2019-12-04 00:44:42;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[3.030432ms] demo.MathGame:run() + +---[0.010473ms] java.util.Random:nextInt() #23 + +---[0.023715ms] demo.MathGame:primeFactors() #24 [throws Exception] + +---[0.005198ms] java.lang.StringBuilder:() #28 + +---[0.006405ms] java.lang.Integer:valueOf() #28 + +---[0.178583ms] java.lang.String:format() #28 + +---[min=0.011636ms,max=0.838077ms,total=0.849713ms,count=2] java.lang.StringBuilder:append() #28 + +---[0.008747ms] java.lang.Exception:getMessage() #28 + +---[0.019768ms] java.lang.StringBuilder:toString() #28 + `---[0.076457ms] java.io.PrintStream:println() #28 +``` + +#### 据调用耗时过滤 + +`trace demo.MathGame run '#cost > 10'`{{execute T2}} + +```bash +$ trace demo.MathGame run '#cost > 10' +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 41 ms. +`---ts=2018-12-04 01:12:02;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[12.033735ms] demo.MathGame:run() + +---[0.006783ms] java.util.Random:nextInt() + +---[11.852594ms] demo.MathGame:primeFactors() + `---[0.05447ms] demo.MathGame:print() +``` + +> 只会展示耗时大于10ms的调用路径,有助于在排查问题的时候,只关注异常情况 + +- 是不是很眼熟,没错,在 JProfiler 等收费软件中你曾经见识类似的功能,这里你将可以通过命令就能打印出指定调用路径。 友情提醒下,`trace` 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。 +- [12.033735ms] 的含义,`12.033735` 的含义是:当前节点在当前步骤的耗时,单位为毫秒 +- [0,0,0ms,11]xxx:yyy() [throws Exception],对该方法中相同的方法调用进行了合并,`0,0,0ms,11` 表示方法调用耗时,`min,max,total,count`;`throws Exception` 表明该方法调用中存在异常返回 +- 这里存在一个统计不准确的问题,就是所有方法耗时加起来可能会小于该监测方法的总耗时,这个是由于 Arthas 本身的逻辑会有一定的耗时 + +#### trace多个类或者多个函数 + +trace命令只会trace匹配到的函数里的子调用,并不会向下trace多层。因为trace是代价比较贵的,多层trace可能会导致最终要trace的类和函数非常多。 + +可以用正则表匹配路径上的多个类和函数,一定程度上达到多层trace的效果。 + +```bash +trace -E com.test.ClassA|org.test.ClassB method1|method2|method3 +``` + +### 动态trace + +3.3.0 版本后支持。 + + +打开终端1,trace `run`函数,可以看到打印出 `listenerId: 1`: + +`trace demo.MathGame run`{{execute T2}} + +```bash +[arthas@59161]$ trace demo.MathGame run +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 112 ms, listenerId: 1 +`---ts=2020-07-09 16:48:11;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[1.389634ms] demo.MathGame:run() + `---[0.123934ms] demo.MathGame:primeFactors() #24 [throws Exception] + +`---ts=2020-07-09 16:48:12;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[3.716391ms] demo.MathGame:run() + +---[3.182813ms] demo.MathGame:primeFactors() #24 + `---[0.167786ms] demo.MathGame:print() #25 +``` + +现在想要深入子函数`primeFactors`,可以打开一个新终端2,使用`telnet localhost 3658`连接上arthas,再trace `primeFactors`时,指定`listenerId`。 + +`trace demo.MathGame primeFactors --listenerId 1`{{execute T2}} + +```bash +[arthas@59161]$ trace demo.MathGame primeFactors --listenerId 1 +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 34 ms, listenerId: 1 +``` + +这时终端2打印的结果,说明已经增强了一个函数:`Affect(class count: 1 , method count: 1)`,但不再打印更多的结果。 + +再查看终端1,可以发现trace的结果增加了一层,打印了`primeFactors`函数里的内容: + +```bash +`---ts=2020-07-09 16:49:29;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.492551ms] demo.MathGame:run() + `---[0.113929ms] demo.MathGame:primeFactors() #24 [throws Exception] + `---[0.061462ms] demo.MathGame:primeFactors() + `---[0.001018ms] throw:java.lang.IllegalArgumentException() #46 + +`---ts=2020-07-09 16:49:30;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.409446ms] demo.MathGame:run() + +---[0.232606ms] demo.MathGame:primeFactors() #24 + | `---[0.1294ms] demo.MathGame:primeFactors() + `---[0.084025ms] demo.MathGame:print() #25 +``` + +通过指定`listenerId`的方式动态trace,可以不断深入。另外 `watch`/`tt`/`monitor`等命令也支持类似的功能。 diff --git a/tutorials/katacoda/command-trace-en/arthas-boot.md b/tutorials/katacoda/command-trace-en/arthas-boot.md new file mode 100644 index 000000000..b9f9cc04f --- /dev/null +++ b/tutorials/katacoda/command-trace-en/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +In the new `Terminal 2`, download `arthas-boot.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot` is the launcher for `Arthas`. It lists all the Java processes, and the user can select the target process to be diagnosed. + +Select the first process, type `1`{{execute T2}} ,then type `Enter`: + +After the Attach is successful, Arthas LOGO is printed. Enter `help`{{execute T2}} for more help. + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-trace-en/arthas-demo.md b/tutorials/katacoda/command-trace-en/arthas-demo.md new file mode 100644 index 000000000..7ba2cf1fa --- /dev/null +++ b/tutorials/katacoda/command-trace-en/arthas-demo.md @@ -0,0 +1,11 @@ + + + + +Download `arthas-demo.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo` is a very simple program that randomly generates integers, performs factorization, and prints the results. +If the generated random number is negative, a error message will be printed. diff --git a/tutorials/katacoda/command-trace-en/finish.md b/tutorials/katacoda/command-trace-en/finish.md new file mode 100644 index 000000000..a455950f2 --- /dev/null +++ b/tutorials/katacoda/command-trace-en/finish.md @@ -0,0 +1,8 @@ + +The `mbean Tutorial` demonstrates the usage of mbean. If you have more tips or questions, please feel free to ask in Issue. + +* Issues: https://github.com/alibaba/arthas/issues +* Documentation: https://alibaba.github.io/arthas + + +If you are using Arthas, please let us know. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111) \ No newline at end of file diff --git a/tutorials/katacoda/command-trace-en/index.json b/tutorials/katacoda/command-trace-en/index.json new file mode 100644 index 000000000..034f70282 --- /dev/null +++ b/tutorials/katacoda/command-trace-en/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas mbean Command", + "description": "Arthas mbean Command", + "difficulty": "master", + "time": "10-20 minutes", + "details": { + "steps": [ + { + "title": "Arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "Start arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "mbean Command", + "text": "mbean.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-trace-en/intro.md b/tutorials/katacoda/command-trace-en/intro.md new file mode 100644 index 000000000..81bdd7a23 --- /dev/null +++ b/tutorials/katacoda/command-trace-en/intro.md @@ -0,0 +1,40 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers. + +`Arthas` supports JDK 6+, supports Linux/Mac/Windows. + +## Background + +Oftentimes the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. What’s even worse, debugging in production environment is unacceptable, as it will suspend all the threads, leading to services downtime. + +Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be reproduced easily in a different environment, or even disappear once restarted. + +And if you’re thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle: test, staging, and then to production. Time is money! This approach is inefficient! Worse still, the issue may not be fixed since it might be irreproducible once the JVM is restarted, as described above. + +Arthas is built to solve these issues. A developer can troubleshoot production issues on the fly. No JVM restart, no additional code changes. Arthas works as an observer, that is, it will never suspend your running threads. + +## Key features + +- Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts) +- Decompile a class to ensure the code is running as expected. +- Check classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc. +- Check the method invocation details, e.g. method parameter, returned values, exceptions and etc. +- Check the stack trace of specified method invocation. This is useful when a developer wants to know the caller of the method. +- Trace the method invocation to find slow sub-invocations. +- Monitor method invocation statistics, e.g. QPS (Query Per Second), RT (Return Time), success rate and etc. +- Monitor system metrics, thread states and CPU usage, GC statistics and etc. +- Supports command line interactive mode, with auto-complete feature enabled. +- Supports telnet and WebSocket, which enables both local and remote diagnostics with command line and browsers. +- Supports profiler/Flame Graph +- Supports JDK 6+ +- Supports Linux/Mac/Windows + +This tutorial takes a simple application as an example to demonstrate the the usage of mbean. + +* Github: https://github.com/alibaba/arthas +* Docs: https://alibaba.github.io/arthas/ + diff --git a/tutorials/katacoda/command-trace-en/trace.md b/tutorials/katacoda/command-trace-en/trace.md new file mode 100644 index 000000000..02074fb84 --- /dev/null +++ b/tutorials/katacoda/command-trace-en/trace.md @@ -0,0 +1,194 @@ + +> Trace method calling path, and output the time cost for each node in the path. + +`trace` can track the calling path specified by `class-pattern` / `method-pattern`, and calculate the time cost on the whole path. + +### Parameters + +|Name|Specification| +|---:|:---| +|*class-pattern*|pattern for the class name| +|*method-pattern*|pattern for the method name| +|*condition-express*|condition expression| +|`[E]`|enable regex match, the default behavior is wildcards match| +|`[n:]`|execution times| +|#cost|time cost| + +There's one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this `"{params,returnObj}"`. All OGNL expressions are supported as long as they are legal to the grammar. + +Thanks for `advice`'s data structure, it is possible to observe from varieties of different angles. Inside `advice` parameter, all necessary information for notification can be found. + +Pls. refer to [core parameters in expression](advice-class.md) for more details. +* Pls. also refer to [https://github.com/alibaba/arthas/issues/71](https://github.com/alibaba/arthas/issues/71) for more advanced usage +* OGNL official site: [https://commons.apache.org/proper/commons-ognl/language-guide.html](https://commons.apache.org/proper/commons-ognl/language-guide.html) + +Many times what we are interested is the exact trace result when the method call takes time over one particular period. It is possible to achieve this in Arthas, for example: `trace *StringUtils isBlank '#cost>100'` means trace result will only be output when the executing time exceeds 100ms. + + +> `watch`/`stack`/`trace`, these three commands all support `#cost`. + +### Notice + +`trace` is handy to help discovering and locating the performance flaws in your system, but pls. note Arthas can only trace the first level method call each time. + + +After version 3.3.0, you can use the Dynamic Trace feature to add new matching classes/methods, see the following example. + +### Usage + +#### Trace method + +`trace demo.MathGame run`{{execute T2}} + +```bash +$ trace demo.MathGame run +Press Q or Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 28 ms. +`---ts=2019-12-04 00:45:08;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.617465ms] demo.MathGame:run() + `---[0.078946ms] demo.MathGame:primeFactors() #24 [throws Exception] + +`---ts=2019-12-04 00:45:09;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[1.276874ms] demo.MathGame:run() + `---[0.03752ms] demo.MathGame:primeFactors() #24 [throws Exception] +``` + + +#### Trace times limit + +If the method invoked many times, use `-n` options to specify trace times. For example, the command will exit when received a trace result. + +`trace demo.MathGame run -n 1`{{execute T2}} + +```bash +$ trace demo.MathGame run -n 1 +Press Q or Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 20 ms. +`---ts=2019-12-04 00:45:53;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.549379ms] demo.MathGame:run() + +---[0.059839ms] demo.MathGame:primeFactors() #24 + `---[0.232887ms] demo.MathGame:print() #25 + +Command execution times exceed limit: 1, so command will exit. You can set it with -n option. +``` + +#### Include jdk method + +* `--skipJDKMethod ` skip jdk method trace, default value true. + +`trace --skipJDKMethod false demo.MathGame run`{{execute T2}} + +```bash +$ trace --skipJDKMethod false demo.MathGame run +Press Q or Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 60 ms. +`---ts=2019-12-04 00:44:41;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[1.357742ms] demo.MathGame:run() + +---[0.028624ms] java.util.Random:nextInt() #23 + +---[0.045534ms] demo.MathGame:primeFactors() #24 [throws Exception] + +---[0.005372ms] java.lang.StringBuilder:() #28 + +---[0.012257ms] java.lang.Integer:valueOf() #28 + +---[0.234537ms] java.lang.String:format() #28 + +---[min=0.004539ms,max=0.005778ms,total=0.010317ms,count=2] java.lang.StringBuilder:append() #28 + +---[0.013777ms] java.lang.Exception:getMessage() #28 + +---[0.004935ms] java.lang.StringBuilder:toString() #28 + `---[0.06941ms] java.io.PrintStream:println() #28 + +`---ts=2019-12-04 00:44:42;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[3.030432ms] demo.MathGame:run() + +---[0.010473ms] java.util.Random:nextInt() #23 + +---[0.023715ms] demo.MathGame:primeFactors() #24 [throws Exception] + +---[0.005198ms] java.lang.StringBuilder:() #28 + +---[0.006405ms] java.lang.Integer:valueOf() #28 + +---[0.178583ms] java.lang.String:format() #28 + +---[min=0.011636ms,max=0.838077ms,total=0.849713ms,count=2] java.lang.StringBuilder:append() #28 + +---[0.008747ms] java.lang.Exception:getMessage() #28 + +---[0.019768ms] java.lang.StringBuilder:toString() #28 + `---[0.076457ms] java.io.PrintStream:println() #28 +``` + +#### Filtering by cost + +`trace demo.MathGame run '#cost > 10'`{{execute T2}} + +```bash +$ trace demo.MathGame run '#cost > 10' +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 41 ms. +`---ts=2018-12-04 01:12:02;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[12.033735ms] demo.MathGame:run() + +---[0.006783ms] java.util.Random:nextInt() + +---[11.852594ms] demo.MathGame:primeFactors() + `---[0.05447ms] demo.MathGame:print() +``` + +> Only the call path which's time cost is higher than `10ms` will be shown. This feature is handy to focus on what's needed to focus when troubleshoot. + +* Here Arthas provides the similar functionality JProfile and other commercial software provide. Compared to these professional softwares, Arthas doesn't deduce the time cost `trace` itself takes, therefore it is not as accurate as these softwares offer. More classes and methods on the calling path, more inaccurate `trace` output is, but it is still helpful for diagnostics where the bottleneck is. +* "[12.033735ms]" means the method on the node takes `12.033735` ms. +* "[min=0.005428ms,max=0.094064ms,total=0.105228ms,count=3] demo:call()" means aggregating all same method calls into one single line. The minimum time cost is `0.005428` ms, the maximum time cost is `0.094064` ms, and the total time cost for all method calls (`3` times in total) to "demo:call()" is `0.105228ms`. If "throws Exception" appears in this line, it means some exceptions have been thrown from this method calls. +* The total time cost may not equal to the sum of the time costs each sub method call takes, this is because Arthas instrumented code takes time too. + + +#### Trace multiple classes or multiple methods + +The trace command will only trace the subcalls in the method to the trace, and will not trace down multiple layers. Because traces are expensive, multi-layer traces can lead to a lot of classes and methods that ultimately have to be traced. + +You can use the regular expression to match multiple classes and methods on the path to achieve a multi-layer trace effect to some extent. + +```bash +Trace -E com.test.ClassA|org.test.ClassB method1|method2|method3 +``` + + +#### Dynamic trace + +> Supported since version 3.3.0. + +Open terminal 1, trace the `run` method, and you can see the printout `listenerId: 1` . + +`trace demo.MathGame run`{{execute T2}} + +```bash +[arthas@59161]$ trace demo.MathGame run +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 112 ms, listenerId: 1 +`---ts=2020-07-09 16:48:11;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[1.389634ms] demo.MathGame:run() + `---[0.123934ms] demo.MathGame:primeFactors() #24 [throws Exception] + +`---ts=2020-07-09 16:48:12;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[3.716391ms] demo.MathGame:run() + +---[3.182813ms] demo.MathGame:primeFactors() #24 + `---[0.167786ms] demo.MathGame:print() #25 +``` + +Now to drill down into the sub method `primeFactors`, you can open a new terminal 2 and use the `telnet localhost 3658` connects to the arthas, then trace `primeFactors` with the specify `listenerId`. + +`trace demo.MathGame primeFactors --listenerId 1`{{execute T2}} + +```bash +[arthas@59161]$ trace demo.MathGame primeFactors --listenerId 1 +Press Q or Ctrl+C to abort. +Affect(class count: 1 , method count: 1) cost in 34 ms, listenerId: 1 +``` + +At Terminal 2 prints the results, indicating that a method has been enhanced: `Affect(class count: 1 , method count: 1)`, but no more results are printed. + +At terminal 1, you can see that the trace result has increased by one layer: + +```bash +`---ts=2020-07-09 16:49:29;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.492551ms] demo.MathGame:run() + `---[0.113929ms] demo.MathGame:primeFactors() #24 [throws Exception] + `---[0.061462ms] demo.MathGame:primeFactors() + `---[0.001018ms] throw:java.lang.IllegalArgumentException() #46 + +`---ts=2020-07-09 16:49:30;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69 + `---[0.409446ms] demo.MathGame:run() + +---[0.232606ms] demo.MathGame:primeFactors() #24 + | `---[0.1294ms] demo.MathGame:primeFactors() + `---[0.084025ms] demo.MathGame:print() #25 +``` + +Dynamic trace by specifying `listenerId`, you can go deeper and deeper. In addition, commands such as `watch`/`tt`/`monitor` also support similar functionality. \ No newline at end of file From a3e31c8eb443b6cdf02a2a20f45a29d2c45d3ed7 Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Aug 2020 17:50:16 +0800 Subject: [PATCH 5/8] add heapdump command scenario. #847 (#1373) --- site/src/site/sphinx/en/heapdump.md | 2 + site/src/site/sphinx/heapdump.md | 2 + .../command-heapdump-cn/arthas-boot.md | 16 ++++++++ .../command-heapdump-cn/arthas-demo.md | 10 +++++ .../katacoda/command-heapdump-cn/finish.md | 12 ++++++ .../katacoda/command-heapdump-cn/heapdump.md | 38 ++++++++++++++++++ .../katacoda/command-heapdump-cn/index.json | 35 ++++++++++++++++ .../katacoda/command-heapdump-cn/intro.md | 23 +++++++++++ .../command-heapdump-en/arthas-boot.md | 16 ++++++++ .../command-heapdump-en/arthas-demo.md | 11 +++++ .../katacoda/command-heapdump-en/finish.md | 8 ++++ .../katacoda/command-heapdump-en/heapdump.md | 38 ++++++++++++++++++ .../katacoda/command-heapdump-en/index.json | 35 ++++++++++++++++ .../katacoda/command-heapdump-en/intro.md | 40 +++++++++++++++++++ 14 files changed, 286 insertions(+) create mode 100644 tutorials/katacoda/command-heapdump-cn/arthas-boot.md create mode 100644 tutorials/katacoda/command-heapdump-cn/arthas-demo.md create mode 100644 tutorials/katacoda/command-heapdump-cn/finish.md create mode 100644 tutorials/katacoda/command-heapdump-cn/heapdump.md create mode 100644 tutorials/katacoda/command-heapdump-cn/index.json create mode 100644 tutorials/katacoda/command-heapdump-cn/intro.md create mode 100644 tutorials/katacoda/command-heapdump-en/arthas-boot.md create mode 100644 tutorials/katacoda/command-heapdump-en/arthas-demo.md create mode 100644 tutorials/katacoda/command-heapdump-en/finish.md create mode 100644 tutorials/katacoda/command-heapdump-en/heapdump.md create mode 100644 tutorials/katacoda/command-heapdump-en/index.json create mode 100644 tutorials/katacoda/command-heapdump-en/intro.md diff --git a/site/src/site/sphinx/en/heapdump.md b/site/src/site/sphinx/en/heapdump.md index d63809972..439b6e5ac 100644 --- a/site/src/site/sphinx/en/heapdump.md +++ b/site/src/site/sphinx/en/heapdump.md @@ -1,6 +1,8 @@ heapdump === +[`heapdump` online tutorial](https://alibaba.github.io/arthas/arthas-tutorials?language=en&id=command-heapdump) + > dump java heap in hprof binary format, like `jmap`. diff --git a/site/src/site/sphinx/heapdump.md b/site/src/site/sphinx/heapdump.md index dea922a04..784d6b2b0 100644 --- a/site/src/site/sphinx/heapdump.md +++ b/site/src/site/sphinx/heapdump.md @@ -1,6 +1,8 @@ heapdump === +[`heapdump`在线教程](https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=command-heapdump) + > dump java heap, 类似jmap命令的heap dump功能。 diff --git a/tutorials/katacoda/command-heapdump-cn/arthas-boot.md b/tutorials/katacoda/command-heapdump-cn/arthas-boot.md new file mode 100644 index 000000000..84ef525a2 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-cn/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +在新的`Terminal 2`里,下载`arthas-boot.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot`是`Arthas`的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。 + +选择第一个进程,输入 `1`{{execute T2}} ,再`Enter/回车`: + +Attach成功之后,会打印Arthas LOGO。输入 `help`{{execute T2}} 可以获取到更多的帮助信息。 + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-heapdump-cn/arthas-demo.md b/tutorials/katacoda/command-heapdump-cn/arthas-demo.md new file mode 100644 index 000000000..f1136e88e --- /dev/null +++ b/tutorials/katacoda/command-heapdump-cn/arthas-demo.md @@ -0,0 +1,10 @@ + + + + +下载`arthas-demo.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。 diff --git a/tutorials/katacoda/command-heapdump-cn/finish.md b/tutorials/katacoda/command-heapdump-cn/finish.md new file mode 100644 index 000000000..7b1032307 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-cn/finish.md @@ -0,0 +1,12 @@ + +在“heapdump”中,我们演示了了Arthas的heapdump命令。如果有更多的技巧或者使用疑问,欢迎在Issue里提出。 + +* Issues: https://github.com/alibaba/arthas/issues +* 文档: https://alibaba.github.io/arthas + + +如果您在使用Arthas,请让我们知道,您的使用对我们非常重要:[查看](https://github.com/alibaba/arthas/issues/111) + +欢迎关注公众号,获取Arthas项目的信息,源码分析,案例实践。 + +![Arthas公众号](/arthas/scenarios/common-resources/assets/qrcode_gongzhonghao.jpg) \ No newline at end of file diff --git a/tutorials/katacoda/command-heapdump-cn/heapdump.md b/tutorials/katacoda/command-heapdump-cn/heapdump.md new file mode 100644 index 000000000..f1e504347 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-cn/heapdump.md @@ -0,0 +1,38 @@ + +> dump java heap, 类似jmap命令的heap dump功能。 + + +### 使用参考 + +#### dump到指定文件 + +`heapdump /tmp/dump.hprof`{{execute T2}} + +```bash +[arthas@58205]$ heapdump /tmp/dump.hprof +Dumping heap to /tmp/dump.hprof... +Heap dump file created +``` + +#### 只dump live对象 + +`heapdump --live /tmp/dump.hprof`{{execute T2}} + +```bash +[arthas@58205]$ heapdump --live /tmp/dump.hprof +Dumping heap to /tmp/dump.hprof... +Heap dump file created +``` + +### dump到临时文件 + +`heapdump`{{execute T2}} + +```bash +[arthas@58205]$ heapdump +Dumping heap to /var/folders/my/wy7c9w9j5732xbkcyt1mb4g40000gp/T/heapdump2019-09-03-16-385121018449645518991.hprof... +Heap dump file created +``` + + + diff --git a/tutorials/katacoda/command-heapdump-cn/index.json b/tutorials/katacoda/command-heapdump-cn/index.json new file mode 100644 index 000000000..aff1d5822 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-cn/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas heapdump命令", + "description": "Arthas heapdump命令", + "difficulty": "精通者", + "time": "10-20 分钟", + "details": { + "steps": [ + { + "title": "启动arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "启动arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "heapdump命令", + "text": "heapdump.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-heapdump-cn/intro.md b/tutorials/katacoda/command-heapdump-cn/intro.md new file mode 100644 index 000000000..5357ddc74 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-cn/intro.md @@ -0,0 +1,23 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。 + +`Arthas` 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。 + +当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: + +- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? +- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? +- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? +- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! +- 是否有一个全局视角来查看系统的运行状况? +- 有什么办法可以监控到JVM的实时运行状态? +- 怎么快速定位应用的热点,生成火焰图? + +本教程会以一个简单的应用为例,演示heapdump命令。 + +* Github: https://github.com/alibaba/arthas +* 文档: https://alibaba.github.io/arthas/ diff --git a/tutorials/katacoda/command-heapdump-en/arthas-boot.md b/tutorials/katacoda/command-heapdump-en/arthas-boot.md new file mode 100644 index 000000000..b9f9cc04f --- /dev/null +++ b/tutorials/katacoda/command-heapdump-en/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +In the new `Terminal 2`, download `arthas-boot.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot` is the launcher for `Arthas`. It lists all the Java processes, and the user can select the target process to be diagnosed. + +Select the first process, type `1`{{execute T2}} ,then type `Enter`: + +After the Attach is successful, Arthas LOGO is printed. Enter `help`{{execute T2}} for more help. + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-heapdump-en/arthas-demo.md b/tutorials/katacoda/command-heapdump-en/arthas-demo.md new file mode 100644 index 000000000..7ba2cf1fa --- /dev/null +++ b/tutorials/katacoda/command-heapdump-en/arthas-demo.md @@ -0,0 +1,11 @@ + + + + +Download `arthas-demo.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo` is a very simple program that randomly generates integers, performs factorization, and prints the results. +If the generated random number is negative, a error message will be printed. diff --git a/tutorials/katacoda/command-heapdump-en/finish.md b/tutorials/katacoda/command-heapdump-en/finish.md new file mode 100644 index 000000000..b2aec4697 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-en/finish.md @@ -0,0 +1,8 @@ + +The `heapdump Tutorial` demonstrates the usage of heapdump. If you have more tips or questions, please feel free to ask in Issue. + +* Issues: https://github.com/alibaba/arthas/issues +* Documentation: https://alibaba.github.io/arthas + + +If you are using Arthas, please let us know. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111) \ No newline at end of file diff --git a/tutorials/katacoda/command-heapdump-en/heapdump.md b/tutorials/katacoda/command-heapdump-en/heapdump.md new file mode 100644 index 000000000..e6ecaeefc --- /dev/null +++ b/tutorials/katacoda/command-heapdump-en/heapdump.md @@ -0,0 +1,38 @@ + +> dump java heap in hprof binary format, like `jmap`. + + +### Usage + +#### Dump to file + +`heapdump /tmp/dump.hprof`{{execute T2}} + +```bash +[arthas@58205]$ heapdump /tmp/dump.hprof +Dumping heap to /tmp/dump.hprof... +Heap dump file created +``` + +#### Dump only live objects + +`heapdump --live /tmp/dump.hprof`{{execute T2}} + +```bash +[arthas@58205]$ heapdump --live /tmp/dump.hprof +Dumping heap to /tmp/dump.hprof... +Heap dump file created +``` + +#### Dump to tmp file + +`heapdump`{{execute T2}} + +```bash +[arthas@58205]$ heapdump +Dumping heap to /var/folders/my/wy7c9w9j5732xbkcyt1mb4g40000gp/T/heapdump2019-09-03-16-385121018449645518991.hprof... +Heap dump file created +``` + + + diff --git a/tutorials/katacoda/command-heapdump-en/index.json b/tutorials/katacoda/command-heapdump-en/index.json new file mode 100644 index 000000000..7abb7bc78 --- /dev/null +++ b/tutorials/katacoda/command-heapdump-en/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas heapdump Command", + "description": "Arthas heapdump Command", + "difficulty": "master", + "time": "10-20 minutes", + "details": { + "steps": [ + { + "title": "Arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "Start arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "heapdump Command", + "text": "heapdump.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-heapdump-en/intro.md b/tutorials/katacoda/command-heapdump-en/intro.md new file mode 100644 index 000000000..4a317e16b --- /dev/null +++ b/tutorials/katacoda/command-heapdump-en/intro.md @@ -0,0 +1,40 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers. + +`Arthas` supports JDK 6+, supports Linux/Mac/Windows. + +## Background + +Oftentimes the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. What’s even worse, debugging in production environment is unacceptable, as it will suspend all the threads, leading to services downtime. + +Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be reproduced easily in a different environment, or even disappear once restarted. + +And if you’re thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle: test, staging, and then to production. Time is money! This approach is inefficient! Worse still, the issue may not be fixed since it might be irreproducible once the JVM is restarted, as described above. + +Arthas is built to solve these issues. A developer can troubleshoot production issues on the fly. No JVM restart, no additional code changes. Arthas works as an observer, that is, it will never suspend your running threads. + +## Key features + +- Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts) +- Decompile a class to ensure the code is running as expected. +- Check classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc. +- Check the method invocation details, e.g. method parameter, returned values, exceptions and etc. +- Check the stack trace of specified method invocation. This is useful when a developer wants to know the caller of the method. +- Trace the method invocation to find slow sub-invocations. +- Monitor method invocation statistics, e.g. QPS (Query Per Second), RT (Return Time), success rate and etc. +- Monitor system metrics, thread states and CPU usage, GC statistics and etc. +- Supports command line interactive mode, with auto-complete feature enabled. +- Supports telnet and WebSocket, which enables both local and remote diagnostics with command line and browsers. +- Supports profiler/Flame Graph +- Supports JDK 6+ +- Supports Linux/Mac/Windows + +This tutorial takes a simple application as an example to demonstrate the the usage of heapdump. + +* Github: https://github.com/alibaba/arthas +* Docs: https://alibaba.github.io/arthas/ + From 3ba6451b1a023f302f982d50900468784c513369 Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Aug 2020 17:52:45 +0800 Subject: [PATCH 6/8] =?UTF-8?q?Arthas=20watch=20=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E6=95=99=E7=A8=8B=20#847=20(#1378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/src/site/sphinx/en/watch.md | 2 + site/src/site/sphinx/watch.md | 2 + .../katacoda/command-watch-cn/arthas-boot.md | 16 ++ .../katacoda/command-watch-cn/arthas-demo.md | 10 + tutorials/katacoda/command-watch-cn/finish.md | 12 + .../katacoda/command-watch-cn/index.json | 35 +++ tutorials/katacoda/command-watch-cn/intro.md | 23 ++ tutorials/katacoda/command-watch-cn/watch.md | 265 ++++++++++++++++++ .../katacoda/command-watch-en/arthas-boot.md | 16 ++ .../katacoda/command-watch-en/arthas-demo.md | 11 + tutorials/katacoda/command-watch-en/finish.md | 8 + .../katacoda/command-watch-en/index.json | 35 +++ tutorials/katacoda/command-watch-en/intro.md | 40 +++ tutorials/katacoda/command-watch-en/watch.md | 264 +++++++++++++++++ 14 files changed, 739 insertions(+) create mode 100644 tutorials/katacoda/command-watch-cn/arthas-boot.md create mode 100644 tutorials/katacoda/command-watch-cn/arthas-demo.md create mode 100644 tutorials/katacoda/command-watch-cn/finish.md create mode 100644 tutorials/katacoda/command-watch-cn/index.json create mode 100644 tutorials/katacoda/command-watch-cn/intro.md create mode 100644 tutorials/katacoda/command-watch-cn/watch.md create mode 100644 tutorials/katacoda/command-watch-en/arthas-boot.md create mode 100644 tutorials/katacoda/command-watch-en/arthas-demo.md create mode 100644 tutorials/katacoda/command-watch-en/finish.md create mode 100644 tutorials/katacoda/command-watch-en/index.json create mode 100644 tutorials/katacoda/command-watch-en/intro.md create mode 100644 tutorials/katacoda/command-watch-en/watch.md diff --git a/site/src/site/sphinx/en/watch.md b/site/src/site/sphinx/en/watch.md index 0701165e0..8b5a3bef3 100644 --- a/site/src/site/sphinx/en/watch.md +++ b/site/src/site/sphinx/en/watch.md @@ -1,6 +1,8 @@ watch ===== +[`watch` online tutorial](https://alibaba.github.io/arthas/arthas-tutorials?language=en&id=command-watch) + Monitor methods in data aspect including `return values`, `exceptions` and `parameters`. With the help of [OGNL](https://commons.apache.org/proper/commons-ognl/index.html), you can easily check the details of variables when methods being invoked. diff --git a/site/src/site/sphinx/watch.md b/site/src/site/sphinx/watch.md index e51b89f74..a878694fe 100644 --- a/site/src/site/sphinx/watch.md +++ b/site/src/site/sphinx/watch.md @@ -1,6 +1,8 @@ watch === +[`watch`在线教程](https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=command-watch) + > 方法执行数据观测 让你能方便的观察到指定方法的调用情况。能观察到的范围为:`返回值`、`抛出异常`、`入参`,通过编写 OGNL 表达式进行对应变量的查看。 diff --git a/tutorials/katacoda/command-watch-cn/arthas-boot.md b/tutorials/katacoda/command-watch-cn/arthas-boot.md new file mode 100644 index 000000000..84ef525a2 --- /dev/null +++ b/tutorials/katacoda/command-watch-cn/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +在新的`Terminal 2`里,下载`arthas-boot.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot`是`Arthas`的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。 + +选择第一个进程,输入 `1`{{execute T2}} ,再`Enter/回车`: + +Attach成功之后,会打印Arthas LOGO。输入 `help`{{execute T2}} 可以获取到更多的帮助信息。 + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-watch-cn/arthas-demo.md b/tutorials/katacoda/command-watch-cn/arthas-demo.md new file mode 100644 index 000000000..f1136e88e --- /dev/null +++ b/tutorials/katacoda/command-watch-cn/arthas-demo.md @@ -0,0 +1,10 @@ + + + + +下载`arthas-demo.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。 diff --git a/tutorials/katacoda/command-watch-cn/finish.md b/tutorials/katacoda/command-watch-cn/finish.md new file mode 100644 index 000000000..20a15848c --- /dev/null +++ b/tutorials/katacoda/command-watch-cn/finish.md @@ -0,0 +1,12 @@ + +在“watch”中,我们演示了了Arthas的watch命令。如果有更多的技巧或者使用疑问,欢迎在Issue里提出。 + +* Issues: https://github.com/alibaba/arthas/issues +* 文档: https://alibaba.github.io/arthas + + +如果您在使用Arthas,请让我们知道,您的使用对我们非常重要:[查看](https://github.com/alibaba/arthas/issues/111) + +欢迎关注公众号,获取Arthas项目的信息,源码分析,案例实践。 + +![Arthas公众号](/arthas/scenarios/common-resources/assets/qrcode_gongzhonghao.jpg) \ No newline at end of file diff --git a/tutorials/katacoda/command-watch-cn/index.json b/tutorials/katacoda/command-watch-cn/index.json new file mode 100644 index 000000000..ce57dfe31 --- /dev/null +++ b/tutorials/katacoda/command-watch-cn/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas watch命令", + "description": "Arthas watch命令", + "difficulty": "精通者", + "time": "10-20 分钟", + "details": { + "steps": [ + { + "title": "启动arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "启动arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "watch命令", + "text": "watch.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-watch-cn/intro.md b/tutorials/katacoda/command-watch-cn/intro.md new file mode 100644 index 000000000..30645b058 --- /dev/null +++ b/tutorials/katacoda/command-watch-cn/intro.md @@ -0,0 +1,23 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。 + +`Arthas` 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。 + +当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: + +- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? +- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? +- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? +- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现! +- 是否有一个全局视角来查看系统的运行状况? +- 有什么办法可以监控到JVM的实时运行状态? +- 怎么快速定位应用的热点,生成火焰图? + +本教程会以一个简单的应用为例,演示watch命令。 + +* Github: https://github.com/alibaba/arthas +* 文档: https://alibaba.github.io/arthas/ diff --git a/tutorials/katacoda/command-watch-cn/watch.md b/tutorials/katacoda/command-watch-cn/watch.md new file mode 100644 index 000000000..42044cfd1 --- /dev/null +++ b/tutorials/katacoda/command-watch-cn/watch.md @@ -0,0 +1,265 @@ + +> 方法执行数据观测 + +让你能方便的观察到指定方法的调用情况。能观察到的范围为:`返回值`、`抛出异常`、`入参`,通过编写 OGNL 表达式进行对应变量的查看。 + +### 参数说明 + +watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 + +|参数名称|参数说明| +|---:|:---| +|*class-pattern*|类名表达式匹配| +|*method-pattern*|方法名表达式匹配| +|*express*|观察表达式| +|*condition-express*|条件表达式| +|[b]|在**方法调用之前**观察| +|[e]|在**方法异常之后**观察| +|[s]|在**方法返回之后**观察| +|[f]|在**方法结束之后**(正常返回和异常返回)观察| +|[E]|开启正则表达式匹配,默认为通配符匹配| +|[x:]|指定输出结果的属性遍历深度,默认为 1| + +这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写`"{params,returnObj}"`,只要是一个合法的 ognl 表达式,都能被正常支持。 + +观察的维度也比较多,主要体现在参数 `advice` 的数据结构上。`Advice` 参数最主要是封装了通知节点的所有信息。请参考[表达式核心变量](advice-class.md)中关于该节点的描述。 + +* 特殊用法请参考:[https://github.com/alibaba/arthas/issues/71](https://github.com/alibaba/arthas/issues/71) +* OGNL表达式官网:[https://commons.apache.org/proper/commons-ognl/language-guide.html](https://commons.apache.org/proper/commons-ognl/language-guide.html) + +**特别说明**: + +* watch 命令定义了4个观察事件点,即 `-b` 方法调用前,`-e` 方法异常后,`-s` 方法返回后,`-f` 方法结束后 +* 4个观察事件点 `-b`、`-e`、`-s` 默认关闭,`-f` 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出 +* 这里要注意`方法入参`和`方法出参`的区别,有可能在中间被修改导致前后不一致,除了 `-b` 事件点 `params` 代表方法入参外,其余事件都代表方法出参 +* 当使用 `-b` 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在 + +### 使用参考 + +#### 观察方法出参和返回值 + +`watch demo.MathGame primeFactors "{params,returnObj}" -x 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. +ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ + @Object[][ + @Integer[535629513], + ], + @ArrayList[ + @Integer[3], + @Integer[19], + @Integer[191], + @Integer[49199], + ], +] +``` + +#### 观察方法入参 + +`watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 50 ms. +ts=2018-12-03 19:23:23; [cost=0.0353ms] result=@ArrayList[ + @Object[][ + @Integer[-1077465243], + ], + null, +] +``` + +* 对比前一个例子,返回值为空(事件点为方法执行前,因此获取不到返回值) + + +#### 同时观察方法调用前和方法返回后 + +`watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 46 ms. +ts=2018-12-03 19:29:54; [cost=0.01696ms] result=@ArrayList[ + @Object[][ + @Integer[1544665400], + ], + @MathGame[ + random=@Random[java.util.Random@522b408a], + illegalArgumentCount=@Integer[13038], + ], + null, +] +ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[ + @Object[][ + @Integer[1544665400], + ], + @MathGame[ + random=@Random[java.util.Random@522b408a], + illegalArgumentCount=@Integer[13038], + ], + @ArrayList[ + @Integer[2], + @Integer[2], + @Integer[2], + @Integer[5], + @Integer[5], + @Integer[73], + @Integer[241], + @Integer[439], + ], +] +``` + +* 参数里`-n 2`,表示只执行两次 + +* 这里输出结果中,第一次输出的是方法调用前的观察表达式的结果,第二次输出的是方法返回后的表达式的结果 + +* 结果的输出顺序和事件发生的先后顺序一致,和命令中 `-s -b` 的顺序无关 + +#### 调整`-x`的值,观察具体的方法参数值 + +`watch demo.MathGame primeFactors "{params,target}" -x 3`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,target}" -x 3 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 58 ms. +ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[ + @Object[][ + @Integer[47816758], + ], + @MathGame[ + random=@Random[ + serialVersionUID=@Long[3905348978240129619], + seed=@AtomicLong[3133719055989], + multiplier=@Long[25214903917], + addend=@Long[11], + mask=@Long[281474976710655], + DOUBLE_UNIT=@Double[1.1102230246251565E-16], + BadBound=@String[bound must be positive], + BadRange=@String[bound must be greater than origin], + BadSize=@String[size must be non-negative], + seedUniquifier=@AtomicLong[-3282039941672302964], + nextNextGaussian=@Double[0.0], + haveNextNextGaussian=@Boolean[false], + serialPersistentFields=@ObjectStreamField[][isEmpty=false;size=3], + unsafe=@Unsafe[sun.misc.Unsafe@2eaa1027], + seedOffset=@Long[24], + ], + illegalArgumentCount=@Integer[13159], + ], +] +``` + +* `-x`表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是1。 + + +#### 条件表达式的例子 + +`watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0" +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 68 ms. +ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[ + @Integer[-18178089], + @MathGame[demo.MathGame@41cf53f9], +] +``` + +* 只有满足条件的调用,才会有响应。 + +* `watch-express` 单个值可以不加'{}',多个值需要加'{a,b,c}'。 + +* `condition-express` 不能加'{}',可以使用逗号分隔子表达式,取表达式最后一个值来判断。 + +如果watch的方法存在同名的其它重载方法,可以通过下面的办法进行过滤: + + * 根据参数类型进行过滤 + + `watch demo.MathGame primeFactors '{params, params[0].class.name}' 'params[0].class.name == "java.lang.Integer"'`{{execute T2}} + + * 根据参数个数进行过滤 + + `watch demo.MathGame primeFactors '{params, params.length}' 'params.length==1'`{{execute T2}} + +#### 观察异常信息的例子 + +`watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 62 ms. +ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[ + @Integer[-1120397038], + java.lang.IllegalArgumentException: number is: -1120397038, need >= 2 + at demo.MathGame.primeFactors(MathGame.java:46) + at demo.MathGame.run(MathGame.java:24) + at demo.MathGame.main(MathGame.java:16) +, +] +``` + +* `-e`表示抛出异常时才触发 +* express中,表示异常信息的变量是`throwExp` + +根据异常类型或者message进行过滤: + +`watch demo.MathGame primeFactors '{params, throwExp}' '#msg=throwExp.toString(), #msg.contains("IllegalArgumentException")' -e -x 2`{{execute T2}} + +#### 按照耗时进行过滤 + +`watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms. +ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[ + @Object[][ + @Integer[2141897465], + ], + @ArrayList[ + @Integer[5], + @Integer[428379493], + ], +] +``` + +* `#cost>200`(单位是`ms`)表示只有当耗时大于200ms时才会输出,过滤掉执行时间小于200ms的调用 + + +#### 观察当前对象中的属性 + +`watch demo.MathGame primeFactors 'target'`{{execute T2}} + +如果想查看方法运行前后,当前对象中的属性,可以使用`target`关键字,代表当前对象 + +```bash +$ watch demo.MathGame primeFactors 'target' +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 52 ms. +ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[ + random=@Random[java.util.Random@522b408a], + illegalArgumentCount=@Integer[13355], +] +``` + +然后使用`target.field_name`访问当前对象的某个属性 + +`watch demo.MathGame primeFactors 'target.illegalArgumentCount'`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors 'target.illegalArgumentCount' +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 67 ms. +ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8] +ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8] +``` diff --git a/tutorials/katacoda/command-watch-en/arthas-boot.md b/tutorials/katacoda/command-watch-en/arthas-boot.md new file mode 100644 index 000000000..b9f9cc04f --- /dev/null +++ b/tutorials/katacoda/command-watch-en/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +In the new `Terminal 2`, download `arthas-boot.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar`{{execute T2}} + +`arthas-boot` is the launcher for `Arthas`. It lists all the Java processes, and the user can select the target process to be diagnosed. + +Select the first process, type `1`{{execute T2}} ,then type `Enter`: + +After the Attach is successful, Arthas LOGO is printed. Enter `help`{{execute T2}} for more help. + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/command-watch-en/arthas-demo.md b/tutorials/katacoda/command-watch-en/arthas-demo.md new file mode 100644 index 000000000..7ba2cf1fa --- /dev/null +++ b/tutorials/katacoda/command-watch-en/arthas-demo.md @@ -0,0 +1,11 @@ + + + + +Download `arthas-demo.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo` is a very simple program that randomly generates integers, performs factorization, and prints the results. +If the generated random number is negative, a error message will be printed. diff --git a/tutorials/katacoda/command-watch-en/finish.md b/tutorials/katacoda/command-watch-en/finish.md new file mode 100644 index 000000000..99f08106f --- /dev/null +++ b/tutorials/katacoda/command-watch-en/finish.md @@ -0,0 +1,8 @@ + +The `watch Tutorial` demonstrates the usage of watch. If you have more tips or questions, please feel free to ask in Issue. + +* Issues: https://github.com/alibaba/arthas/issues +* Documentation: https://alibaba.github.io/arthas + + +If you are using Arthas, please let us know. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111) \ No newline at end of file diff --git a/tutorials/katacoda/command-watch-en/index.json b/tutorials/katacoda/command-watch-en/index.json new file mode 100644 index 000000000..79fad57f6 --- /dev/null +++ b/tutorials/katacoda/command-watch-en/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas watch Command", + "description": "Arthas watch Command", + "difficulty": "master", + "time": "10-20 minutes", + "details": { + "steps": [ + { + "title": "Arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "Start arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "watch Command", + "text": "watch.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} diff --git a/tutorials/katacoda/command-watch-en/intro.md b/tutorials/katacoda/command-watch-en/intro.md new file mode 100644 index 000000000..fa468f7ab --- /dev/null +++ b/tutorials/katacoda/command-watch-en/intro.md @@ -0,0 +1,40 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers. + +`Arthas` supports JDK 6+, supports Linux/Mac/Windows. + +## Background + +Oftentimes the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. What’s even worse, debugging in production environment is unacceptable, as it will suspend all the threads, leading to services downtime. + +Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be reproduced easily in a different environment, or even disappear once restarted. + +And if you’re thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle: test, staging, and then to production. Time is money! This approach is inefficient! Worse still, the issue may not be fixed since it might be irreproducible once the JVM is restarted, as described above. + +Arthas is built to solve these issues. A developer can troubleshoot production issues on the fly. No JVM restart, no additional code changes. Arthas works as an observer, that is, it will never suspend your running threads. + +## Key features + +- Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts) +- Decompile a class to ensure the code is running as expected. +- Check classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc. +- Check the method invocation details, e.g. method parameter, returned values, exceptions and etc. +- Check the stack trace of specified method invocation. This is useful when a developer wants to know the caller of the method. +- Trace the method invocation to find slow sub-invocations. +- Monitor method invocation statistics, e.g. QPS (Query Per Second), RT (Return Time), success rate and etc. +- Monitor system metrics, thread states and CPU usage, GC statistics and etc. +- Supports command line interactive mode, with auto-complete feature enabled. +- Supports telnet and WebSocket, which enables both local and remote diagnostics with command line and browsers. +- Supports profiler/Flame Graph +- Supports JDK 6+ +- Supports Linux/Mac/Windows + +This tutorial takes a simple application as an example to demonstrate the the usage of watch. + +* Github: https://github.com/alibaba/arthas +* Docs: https://alibaba.github.io/arthas/ + diff --git a/tutorials/katacoda/command-watch-en/watch.md b/tutorials/katacoda/command-watch-en/watch.md new file mode 100644 index 000000000..4055a2a36 --- /dev/null +++ b/tutorials/katacoda/command-watch-en/watch.md @@ -0,0 +1,264 @@ + +Monitor methods in data aspect including `return values`, `exceptions` and `parameters`. + +With the help of [OGNL](https://commons.apache.org/proper/commons-ognl/index.html), you can easily check the details of variables when methods being invoked. + +### Parameters & Options + +There are four different scenarios for `watch` command, which makes it rather complicated. + +|Name|Specification| +|---:|:---| +|*class-pattern*|pattern for the class name| +|*method-pattern*|pattern for the method name| +|*expression*|expression to monitor| +|*condition-expression*|condition expression to filter| +|[b]|before method being invoked| +|[e]|when method encountering exceptions| +|[s]|when method exits normally| +|[f]|when method exits (either succeed or fail with exceptions)| +|[E]|turn on regex matching while the default is wildcard matching| +|[x:]|the depth to print the specified property with default value: 1| + +F.Y.I +1. any valid OGNL expression as `"{params,returnObj}"` supported +2. there are four *watching* points: `-b`, `-e`, `-s` and `-f` (the first three are off in default while `-f` on); +3. at the *watching* point, Arthas will use the *expression* to evaluate the variables and print them out; +4. `in parameters` and `out parameters` are different since they can be modified within the invoked methods; `params` stands for `in parameters` in `-b`while `out parameters` in other *watching* points; +5. there are no `return values` and `exceptions` when using `-b`. + + +Advanced: +* [Special usages](https://github.com/alibaba/arthas/issues/71) +* [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html) + +### Usage + +#### Check the `out parameters` and `return value` + +`watch demo.MathGame primeFactors "{params,returnObj}" -x 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. +ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ + @Object[][ + @Integer[535629513], + ], + @ArrayList[ + @Integer[3], + @Integer[19], + @Integer[191], + @Integer[49199], + ], +] +``` + +#### Check `in parameters` + +`watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 50 ms. +ts=2018-12-03 19:23:23; [cost=0.0353ms] result=@ArrayList[ + @Object[][ + @Integer[-1077465243], + ], + null, +] +``` + +Compared to the previous *check*: + +* `return value` is `null` since it's `-b`. + + +#### Check *before* and *after* at the same time + +`watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 46 ms. +ts=2018-12-03 19:29:54; [cost=0.01696ms] result=@ArrayList[ + @Object[][ + @Integer[1544665400], + ], + @MathGame[ + random=@Random[java.util.Random@522b408a], + illegalArgumentCount=@Integer[13038], + ], + null, +] +ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[ + @Object[][ + @Integer[1544665400], + ], + @MathGame[ + random=@Random[java.util.Random@522b408a], + illegalArgumentCount=@Integer[13038], + ], + @ArrayList[ + @Integer[2], + @Integer[2], + @Integer[2], + @Integer[5], + @Integer[5], + @Integer[73], + @Integer[241], + @Integer[439], + ], +] +``` + +F.Y.I + +* `-n 2`: threshold of execution times is 2. +* the first block of output is the *before watching* point; +* *the order of the output determined by the *watching* order itself (nothing to do with the order of the options `-b -s`). + +#### Use `-x` to check more details + +`watch demo.MathGame primeFactors "{params,target}" -x 3`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params,target}" -x 3 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 58 ms. +ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[ + @Object[][ + @Integer[47816758], + ], + @MathGame[ + random=@Random[ + serialVersionUID=@Long[3905348978240129619], + seed=@AtomicLong[3133719055989], + multiplier=@Long[25214903917], + addend=@Long[11], + mask=@Long[281474976710655], + DOUBLE_UNIT=@Double[1.1102230246251565E-16], + BadBound=@String[bound must be positive], + BadRange=@String[bound must be greater than origin], + BadSize=@String[size must be non-negative], + seedUniquifier=@AtomicLong[-3282039941672302964], + nextNextGaussian=@Double[0.0], + haveNextNextGaussian=@Boolean[false], + serialPersistentFields=@ObjectStreamField[][isEmpty=false;size=3], + unsafe=@Unsafe[sun.misc.Unsafe@2eaa1027], + seedOffset=@Long[24], + ], + illegalArgumentCount=@Integer[13159], + ], +] +``` + +* `-x`: Expand level of object (1 by default) + +#### Use condition expressions to locate specific call + +`watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0" +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 68 ms. +ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[ + @Integer[-18178089], + @MathGame[demo.MathGame@41cf53f9], +] +``` + +* Only calls that meet the conditions will respond. + +* `Watch Express` single value can not be added '{}', and multiple values need to be added '{a, B, C}'. + +* `condition Express` cannot add '{}', you can use commas to separate subexpressions and take the last value of the expression to judge. + +If there are other overloaded methods with the same name in the watch method, you can filter them by the following methods: + + * Filter according to parameter type + + `watch demo.MathGame primeFactors '{params, params[0].class.name}' 'params[0].class.name == "java.lang.Integer"'`{{execute T2}} + + * Filter according to the number of parameters + + `watch demo.MathGame primeFactors '{params, params.length}' 'params.length==1'`{{execute T2}} + +#### Check `exceptions` + +`watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 62 ms. +ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[ + @Integer[-1120397038], + java.lang.IllegalArgumentException: number is: -1120397038, need >= 2 + at demo.MathGame.primeFactors(MathGame.java:46) + at demo.MathGame.run(MathGame.java:24) + at demo.MathGame.main(MathGame.java:16) +, +] +``` + +* `-e`: Trigger when an exception is thrown +* `throwExp`: the exception object + +Filter according to exception type or message: + +`watch demo.MathGame primeFactors '{params, throwExp}' '#msg=throwExp.toString(), #msg.contains("IllegalArgumentException")' -e -x 2`{{execute T2}} + +#### Filter by time cost + +`watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2 +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 66 ms. +ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[ + @Object[][ + @Integer[2141897465], + ], + @ArrayList[ + @Integer[5], + @Integer[428379493], + ], +] +``` + +* `#cost>200` (`ms`) filter out all invokings that take less than `200ms`. + + +#### Check the field of the target object + +* `target` is the `this` object in java. + +`watch demo.MathGame primeFactors 'target'`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors 'target' +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 52 ms. +ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[ + random=@Random[java.util.Random@522b408a], + illegalArgumentCount=@Integer[13355], +] +``` + +* `target.field_name`: the field of the current object. + +`watch demo.MathGame primeFactors 'target.illegalArgumentCount'`{{execute T2}} + +```bash +$ watch demo.MathGame primeFactors 'target.illegalArgumentCount' +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 67 ms. +ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8] +ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8] +``` From 6c43d06ef66e8dfa68f7426c2f074a6a168a6c59 Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Aug 2020 17:59:13 +0800 Subject: [PATCH 7/8] =?UTF-8?q?Arthas=20web=20console=20=E6=A1=88=E4=BE=8B?= =?UTF-8?q?=E6=95=99=E7=A8=8B=20(#1332)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/src/site/sphinx/en/web-console.md | 1 + site/src/site/sphinx/web-console.md | 2 +- .../case-web-console-cn/arthas-boot.md | 16 +++++++++ .../case-web-console-cn/arthas-demo.md | 10 ++++++ .../katacoda/case-web-console-cn/finish.md | 10 ++++++ .../katacoda/case-web-console-cn/index.json | 35 +++++++++++++++++++ .../katacoda/case-web-console-cn/intro.md | 11 ++++++ .../case-web-console-cn/web-console.md | 19 ++++++++++ .../case-web-console-en/arthas-boot.md | 16 +++++++++ .../case-web-console-en/arthas-demo.md | 11 ++++++ .../katacoda/case-web-console-en/finish.md | 6 ++++ .../katacoda/case-web-console-en/index.json | 35 +++++++++++++++++++ .../katacoda/case-web-console-en/intro.md | 11 ++++++ .../case-web-console-en/web-console.md | 20 +++++++++++ 14 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 tutorials/katacoda/case-web-console-cn/arthas-boot.md create mode 100644 tutorials/katacoda/case-web-console-cn/arthas-demo.md create mode 100644 tutorials/katacoda/case-web-console-cn/finish.md create mode 100644 tutorials/katacoda/case-web-console-cn/index.json create mode 100644 tutorials/katacoda/case-web-console-cn/intro.md create mode 100644 tutorials/katacoda/case-web-console-cn/web-console.md create mode 100644 tutorials/katacoda/case-web-console-en/arthas-boot.md create mode 100644 tutorials/katacoda/case-web-console-en/arthas-demo.md create mode 100644 tutorials/katacoda/case-web-console-en/finish.md create mode 100644 tutorials/katacoda/case-web-console-en/index.json create mode 100644 tutorials/katacoda/case-web-console-en/intro.md create mode 100644 tutorials/katacoda/case-web-console-en/web-console.md diff --git a/site/src/site/sphinx/en/web-console.md b/site/src/site/sphinx/en/web-console.md index 740bba0b8..58742e245 100644 --- a/site/src/site/sphinx/en/web-console.md +++ b/site/src/site/sphinx/en/web-console.md @@ -1,6 +1,7 @@ Web Console === +[`Web Console` online tutorial](https://alibaba.github.io/arthas/arthas-tutorials?language=en&id=case-web-console) ### Connect arthas through the browser diff --git a/site/src/site/sphinx/web-console.md b/site/src/site/sphinx/web-console.md index 1960fda21..19264fa22 100644 --- a/site/src/site/sphinx/web-console.md +++ b/site/src/site/sphinx/web-console.md @@ -1,7 +1,7 @@ Web Console === - +[`Web Console`在线教程](https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=case-web-console) ### 通过浏览器连接arthas diff --git a/tutorials/katacoda/case-web-console-cn/arthas-boot.md b/tutorials/katacoda/case-web-console-cn/arthas-boot.md new file mode 100644 index 000000000..d53c8ff8a --- /dev/null +++ b/tutorials/katacoda/case-web-console-cn/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +在新的`Terminal 2`里,下载`arthas-boot.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar --target-ip 0.0.0.0`{{execute T2}} + +`arthas-boot`是`Arthas`的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。 + +选择第一个进程,输入 `1`{{execute T2}} ,再`Enter/回车`: + +Attach成功之后,会打印Arthas LOGO。输入 `help`{{execute T2}} 可以获取到更多的帮助信息。 + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/case-web-console-cn/arthas-demo.md b/tutorials/katacoda/case-web-console-cn/arthas-demo.md new file mode 100644 index 000000000..f1136e88e --- /dev/null +++ b/tutorials/katacoda/case-web-console-cn/arthas-demo.md @@ -0,0 +1,10 @@ + + + + +下载`arthas-demo.jar`,再用`java -jar`命令启动: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。 diff --git a/tutorials/katacoda/case-web-console-cn/finish.md b/tutorials/katacoda/case-web-console-cn/finish.md new file mode 100644 index 000000000..d3087daff --- /dev/null +++ b/tutorials/katacoda/case-web-console-cn/finish.md @@ -0,0 +1,10 @@ + +通过本教程基本掌握了Arthas Web Console。更多高级特性,可以在下面的进阶指南里继续了解。 + +* [Arthas进阶](https://alibaba.github.io/arthas/arthas-tutorials?language=cn&id=arthas-advanced) +* [Arthas Github](https://github.com/alibaba/arthas) +* [Arthas 文档](https://alibaba.github.io/arthas/) + +欢迎关注公众号,获取Arthas项目的信息,源码分析,案例实践。 + +![Arthas公众号](/arthas/scenarios/common-resources/assets/qrcode_gongzhonghao.jpg) diff --git a/tutorials/katacoda/case-web-console-cn/index.json b/tutorials/katacoda/case-web-console-cn/index.json new file mode 100644 index 000000000..534d8575d --- /dev/null +++ b/tutorials/katacoda/case-web-console-cn/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas Web Console 案例", + "description": "Arthas Web Console 案例", + "difficulty": "精通者", + "time": "10-20 分钟", + "details": { + "steps": [ + { + "title": "启动arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "启动arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "Web Console", + "text": "web-console.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} \ No newline at end of file diff --git a/tutorials/katacoda/case-web-console-cn/intro.md b/tutorials/katacoda/case-web-console-cn/intro.md new file mode 100644 index 000000000..23669532b --- /dev/null +++ b/tutorials/katacoda/case-web-console-cn/intro.md @@ -0,0 +1,11 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。 + +`Arthas` 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 `Tab` 自动补全功能,进一步方便进行问题的定位和诊断。 + +* Github: https://github.com/alibaba/arthas +* 文档: https://alibaba.github.io/arthas/ \ No newline at end of file diff --git a/tutorials/katacoda/case-web-console-cn/web-console.md b/tutorials/katacoda/case-web-console-cn/web-console.md new file mode 100644 index 000000000..dee0de410 --- /dev/null +++ b/tutorials/katacoda/case-web-console-cn/web-console.md @@ -0,0 +1,19 @@ + + +Arthas支持通过Web Socket来连接。 + + +## 教程里的Web Console + + +http://[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com/?ip=[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com&port=80 + +> 注意:教程里访问的是80端口,因为做了端口转发。在本地体验时,需要访问8563端口。 + +## 本地体验 + +当在本地启动时,可以访问 http://127.0.0.1:8563/ ,通过浏览器来使用Arthas。 + +![Arthas WebConsole](/arthas/scenarios/common-resources/assets/web-console.png) + +推荐通过“快速入门”来体验: https://alibaba.github.io/arthas/quick-start.html \ No newline at end of file diff --git a/tutorials/katacoda/case-web-console-en/arthas-boot.md b/tutorials/katacoda/case-web-console-en/arthas-boot.md new file mode 100644 index 000000000..29c6aa95e --- /dev/null +++ b/tutorials/katacoda/case-web-console-en/arthas-boot.md @@ -0,0 +1,16 @@ + + + + +In the new `Terminal 2`, download `arthas-boot.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-boot.jar +java -jar arthas-boot.jar --target-ip 0.0.0.0`{{execute T2}} + +`arthas-boot` is the launcher for `Arthas`. It lists all the Java processes, and the user can select the target process to be diagnosed. + +Select the first process, type `1`{{execute T2}} ,then type `Enter`: + +After the Attach is successful, Arthas LOGO is printed. Enter `help`{{execute T2}} for more help. + +![Arthas Boot](/arthas/scenarios/common-resources/assets/arthas-boot.png) diff --git a/tutorials/katacoda/case-web-console-en/arthas-demo.md b/tutorials/katacoda/case-web-console-en/arthas-demo.md new file mode 100644 index 000000000..7ba2cf1fa --- /dev/null +++ b/tutorials/katacoda/case-web-console-en/arthas-demo.md @@ -0,0 +1,11 @@ + + + + +Download `arthas-demo.jar` and start with the `java -jar` command: + +`wget https://alibaba.github.io/arthas/arthas-demo.jar +java -jar arthas-demo.jar`{{execute T1}} + +`arthas-demo` is a very simple program that randomly generates integers, performs factorization, and prints the results. +If the generated random number is negative, a error message will be printed. diff --git a/tutorials/katacoda/case-web-console-en/finish.md b/tutorials/katacoda/case-web-console-en/finish.md new file mode 100644 index 000000000..944cb08ac --- /dev/null +++ b/tutorials/katacoda/case-web-console-en/finish.md @@ -0,0 +1,6 @@ + +Through this tutorial, you can know how to use Arthas `Web console`. More advanced features can be found in the Advanced Guide below. + +* [Arthas Advanced](https://alibaba.github.io/arthas/arthas-tutorials?language=en&id=arthas-advanced) +* [Arthas Github](https://github.com/alibaba/arthas) +* [Arthas Documentation](https://alibaba.github.io/arthas/en) diff --git a/tutorials/katacoda/case-web-console-en/index.json b/tutorials/katacoda/case-web-console-en/index.json new file mode 100644 index 000000000..672c8e925 --- /dev/null +++ b/tutorials/katacoda/case-web-console-en/index.json @@ -0,0 +1,35 @@ +{ + "title": "Arthas Web Console", + "description": "Arthas Web Console", + "difficulty": "master", + "time": "10-20 minutes", + "details": { + "steps": [ + { + "title": "Arthas demo", + "text": "arthas-demo.md" + }, + { + "title": "Start arthas-boot", + "text": "arthas-boot.md" + }, + { + "title": "Web Console", + "text": "web-console.md" + } + ], + "intro": { + "text": "intro.md" + }, + "finish": { + "text": "finish.md" + } + }, + "environment": { + "uilayout": "terminal" + }, + "backend": { + "imageid": "java", + "environmentsprotocol": "http" + } +} \ No newline at end of file diff --git a/tutorials/katacoda/case-web-console-en/intro.md b/tutorials/katacoda/case-web-console-en/intro.md new file mode 100644 index 000000000..e45235726 --- /dev/null +++ b/tutorials/katacoda/case-web-console-en/intro.md @@ -0,0 +1,11 @@ + + + +![Arthas](https://alibaba.github.io/arthas/_images/arthas.png) + +`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers. + +`Arthas` supports JDK 6+, supports Linux/Mac/Windows. + +* Github: https://github.com/alibaba/arthas +* Documentation: https://alibaba.github.io/arthas/en \ No newline at end of file diff --git a/tutorials/katacoda/case-web-console-en/web-console.md b/tutorials/katacoda/case-web-console-en/web-console.md new file mode 100644 index 000000000..609f6ff7d --- /dev/null +++ b/tutorials/katacoda/case-web-console-en/web-console.md @@ -0,0 +1,20 @@ + + +Arthas supports connections via a Web Socket. + + +## The Web Console in the tutorial + +http://[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com/?ip=[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com&port=80 + +> Note: The 80 port is accessed in the tutorial because port forwarding. In the local, you need to access port 8563. + +## Local + + +When launching locally, you can access Arthas through a browser by visiting http://127.0.0.1:8563/. + +![Arthas WebConsole](/arthas/scenarios/common-resources/assets/web-console.png) + + +It is recommended to experience it through "Quick Start": https://alibaba.github.io/arthas/en/quick-start.html \ No newline at end of file From c315d7454d0fa67e469379592203ee8f60485a7b Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Aug 2020 18:01:03 +0800 Subject: [PATCH 8/8] Update webpage (#1385) --- .../_include_html/arthas-tutorials.html | 411 ++++++++++++++++++ 1 file changed, 411 insertions(+) diff --git a/site/src/site/sphinx/_include_html/arthas-tutorials.html b/site/src/site/sphinx/_include_html/arthas-tutorials.html index 53962b89d..80a098bc3 100644 --- a/site/src/site/sphinx/_include_html/arthas-tutorials.html +++ b/site/src/site/sphinx/_include_html/arthas-tutorials.html @@ -81,6 +81,21 @@ {{ tutorial.names[language] }} + + {{ tutorial.names[language] }} + + + + {{ tutorial.names[language] }} + + + + {{ tutorial.names[language] }} + + {{ tutorial.names[language] }} @@ -334,6 +349,30 @@ cn: "command-pwd-cn", } }, + { + id: "command-plaintext", + type: "COMMAND-BASIC", + names: { + en: "plaintext", + cn: "plaintext", + }, + ids: { + en: "command-plaintext-en", + cn: "command-plaintext-cn", + } + }, + { + id: "command-wc", + type: "COMMAND-BASIC", + names: { + en: "wc", + cn: "wc", + }, + ids: { + en: "command-wc-en", + cn: "command-wc-cn", + } + }, { id: "command-dashboard", type: "COMMAND-JVM-RELATED", @@ -417,6 +456,378 @@ en: "command-perfcounter-en", cn: "command-perfcounter-cn", } + }, + { + id: "command-logger", + type: "COMMAND-JVM-RELATED", + names: { + en: "logger", + cn: "logger", + }, + ids: { + en: "command-logger-en", + cn: "command-logger-cn", + } + }, + { + id: "command-getstatic", + type: "COMMAND-JVM-RELATED", + names: { + en: "getstatic", + cn: "getstatic", + }, + ids: { + en: "command-getstatic-en", + cn: "command-getstatic-cn", + } + }, + { + id: "command-ognl", + type: "COMMAND-JVM-RELATED", + names: { + en: "ognl", + cn: "ognl", + }, + ids: { + en: "command-ognl-en", + cn: "command-ognl-cn", + } + }, + { + id: "command-mbean", + type: "COMMAND-JVM-RELATED", + names: { + en: "mbean", + cn: "mbean", + }, + ids: { + en: "command-mbean-en", + cn: "command-mbean-cn", + } + }, + { + id: "command-heapdump", + type: "COMMAND-JVM-RELATED", + names: { + en: "heapdump", + cn: "heapdump", + }, + ids: { + en: "command-heapdump-en", + cn: "command-heapdump-cn", + } + }, + { + id: "command-sc", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "sc", + cn: "sc", + }, + ids: { + en: "command-sc-en", + cn: "command-sc-cn", + } + }, + { + id: "command-sm", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "sm", + cn: "sm", + }, + ids: { + en: "command-sm-en", + cn: "command-sm-cn", + } + }, + { + id: "command-jad", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "jad", + cn: "jad", + }, + ids: { + en: "command-jad-en", + cn: "command-jad-cn", + } + }, + { + id: "command-mc", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "mc", + cn: "mc", + }, + ids: { + en: "command-mc-en", + cn: "command-mc-cn", + } + }, + { + id: "command-redefine", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "redefine", + cn: "redefine", + }, + ids: { + en: "command-redefine-en", + cn: "command-redefine-cn", + } + }, + { + id: "command-dump", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "dump", + cn: "dump", + }, + ids: { + en: "command-dump-en", + cn: "command-dump-cn", + } + }, + { + id: "command-classloader", + type: "COMMAND-CLASS-LOADER-RELATED", + names: { + en: "classloader", + cn: "classloader", + }, + ids: { + en: "command-classloader-en", + cn: "command-classloader-cn", + } + }, + { + id: "command-monitor", + type: "COMMAND-MONITOR-RELATED", + names: { + en: "monitor", + cn: "monitor", + }, + ids: { + en: "command-monitor-en", + cn: "command-monitor-cn", + } + }, + { + id: "command-watch", + type: "COMMAND-MONITOR-RELATED", + names: { + en: "watch", + cn: "watch", + }, + ids: { + en: "command-watch-en", + cn: "command-watch-cn", + } + }, + { + id: "command-trace", + type: "COMMAND-MONITOR-RELATED", + names: { + en: "trace", + cn: "trace", + }, + ids: { + en: "command-trace-en", + cn: "command-trace-cn", + } + }, + { + id: "command-stack", + type: "COMMAND-MONITOR-RELATED", + names: { + en: "stack", + cn: "stack", + }, + ids: { + en: "command-stack-en", + cn: "command-stack-cn", + } + }, + { + id: "command-tt", + type: "COMMAND-MONITOR-RELATED", + names: { + en: "tt", + cn: "tt", + }, + ids: { + en: "command-tt-en", + cn: "command-tt-cn", + } + }, + { + id: "command-options", + type: "COMMAND-OPTIONS", + names: { + en: "options", + cn: "options", + }, + ids: { + en: "command-options-en", + cn: "command-options-cn", + } + }, + { + id: "case-web-console", + type: "USERCASE", + names: { + en: "Web Console", + cn: "Web Console", + }, + ids: { + en: "case-web-console-en", + cn: "case-web-console-cn", + } + }, + { + id: "case-save-log", + type: "USERCASE", + names: { + en: "Log the output", + cn: "执行结果存日志", + }, + ids: { + en: "case-save-log-en", + cn: "case-save-log-cn", + } + }, + { + id: "case-watch-method-exception", + type: "USERCASE", + names: { + en: "Troubleshooting method invoke exception", + cn: "排查函数调用异常", + }, + ids: { + en: "case-watch-method-exception-en", + cn: "case-watch-method-exception-cn", + } + }, + { + id: "case-thread", + type: "USERCASE", + names: { + en: "Find CPU usage Top N threads", + cn: "查找Top N线程", + }, + ids: { + en: "case-thread-en", + cn: "case-thread-cn", + } + }, + { + id: "case-ognl-update-logger-level", + type: "USERCASE", + names: { + en: "Change Logger Level", + cn: "动态更新应用Logger Level", + }, + ids: { + en: "case-ognl-update-logger-level-en", + cn: "case-ognl-update-logger-level-cn", + } + }, + { + id: "case-logger-config-problem", + type: "USERCASE", + names: { + en: "Troubleshoot logger conflicts", + cn: "排查logger冲突问题", + }, + ids: { + en: "case-logger-config-problem-en", + cn: "case-logger-config-problem-cn", + } + }, + { + id: "case-jad-mc-redefine", + type: "USERCASE", + names: { + en: "Hotswap code", + cn: "热更新代码", + }, + ids: { + en: "case-jad-mc-redefine-en", + cn: "case-jad-mc-redefine-cn", + } + }, + { + id: "case-http-404", + type: "USERCASE", + names: { + en: "Troubleshooting HTTP request returns 404", + cn: "排查HTTP请求返回404", + }, + ids: { + en: "case-http-404-en", + cn: "case-http-404-cn", + } + }, + { + id: "case-http-401", + type: "USERCASE", + names: { + en: "Troubleshooting HTTP request returns 401", + cn: "排查HTTP请求返回401", + }, + ids: { + en: "case-http-401-en", + cn: "case-http-401-cn", + } + }, + { + id: "case-get-spring-context", + type: "USERCASE", + names: { + en: "Get the Spring Context", + cn: "获取Spring Context", + }, + ids: { + en: "case-get-spring-context-en", + cn: "case-get-spring-context-cn", + } + }, + { + id: "case-classloader", + type: "USERCASE", + names: { + en: "The ClassLoaders in Spring Boot application", + cn: "理解Spring Boot应用的ClassLoader结构", + }, + ids: { + en: "case-classloader-en", + cn: "case-classloader-cn", + } + }, + { + id: "case-boot-details", + type: "USERCASE", + names: { + en: "Arthas boot supported options", + cn: " arthas-boot支持的参数", + }, + ids: { + en: "case-boot-details-en", + cn: "case-boot-details-cn", + } + }, + { + id: "case-async-jobs", + type: "USERCASE", + names: { + en: "Async in Background", + cn: "后台异步任务", + }, + ids: { + en: "case-async-jobs-en", + cn: "case-async-jobs-cn", + } } ], },