Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Java realizes on-line dynamic diagnosis with BTrace

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "java uses BTrace to achieve online dynamic diagnosis". The content of the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "java uses BTrace to achieve online dynamic diagnosis".

In a word, BTrace is a powerful Java online application detection tool (dynamic tracking tool), which can detect the running of the code without modifying the application code and keep applying the service, and then diagnose the problem. it is a necessary artifact in the production environment. This article will explain its use.

1 introduction

BTrace is an open source software, github address: https://github.com/btraceio/btrace, the official website is introduced by BTrace is a safe, dynamic tracing tool for the Java platform., is a secure tool for dynamic tracking java applications, that is, you can dynamically inject tracking code into the bytecode of the target application. What is dynamic? We all know that when the java application starts, the class file will be loaded into JVM to run, and the class code function is determined and static (can not be changed). If you want to modify the code, you can only modify the code, recompile, deploy, and start.

When dealing with online applications, we often need to check the running of the code, check the parameter values, return values, or add logs that we need to debug. In the development phase, there is no problem with adding logs and restarting. But it is not applicable in the production environment (the production environment generally does not shut down the service easily, and even if it can be restarted, the site where the problem may occur will be destroyed and the problem cannot be reproduced.) So is there a way to dynamically add what you want to monitor (track) while the java application is running without restarting the program? Btrace is such a dynamic tracking artifact, which can monitor the running of the application without restarting, and obtain data information when the program is running, such as method parameters, return values, global variables, stack information and so on. This paper describes the operation principle and use of BTrace.

2. Dynamic modification and replacement of 2. 1 class files in BTrace operation principle

BTrace is realized based on the dynamic tracking technology of java. For java developers, it is clear that the development process of java programs is to write java code, compile it into class files, and then load class to run in JVM. If you want to add tracking content by modifying class without stopping the application, such as adding output information to a method (method), there are two main things:

(1) modify the class that has been loaded into JVM and add custom output

(2) replace the class running in JVM`

The first step is to modify, since JVM runs class files, it is possible to modify bytecode class files directly (of course, bytecode files are far less readable than Java files), but there is already a corresponding framework to do this, that is, ASM. Using this framework, we can edit bytecode frames directly, and it also provides interfaces that allow us to easily manipulate bytecode files. Inject methods to modify the class, dynamically create a new class, and so on. Spring uses this technology to implement dynamic agents.

The second step is to replace. If you replace it, you need to use the java.lang.instrument.Instrumentation provided by java, which has two interfaces: redefineClasses and retransformClasses,redefineClasses, which provide bytecode files to replace the existing class files, and retransformClasses, which is modified and replaced on the existing bytecode files. However, it should be noted that the use of instrument is limited (existing fields and methods cannot be added, modified, deleted, method signatures cannot be changed, inheritance properties cannot be changed, etc.):

Modules and running processes of The redefinition must not add, remove or rename fields or methods, change the signatures of methods and or change inheritance2.2 BTrace

BTrace is based on the previous technology. The article "Java dynamic tracking Technology Exploration" (https://mp.weixin.qq.com/s/_hSaI5yMvPTWxvFgl-UItA) gives a detailed description of dynamic tracking technology, which is briefly described below.

2.2.1 main module

BTrace scripts: with the annotations defined by BTrace, we can easily develop scripts as needed.

Compiler: compile the BTrace script into a BTrace class file.

Client: sends the class file to Agent.

Agent: Java-based Attach API,Agent can be dynamically attached to a running JVM, and then open a BTrace Server to receive the BTrace script sent by client; parse the script, and then find the class to be modified according to the rules in the script; after modifying the bytecode, call the retransform API of Java Instrument to modify the behavior of the object and make it effective.

2.2.2 run the process

The running flow chart is as follows:

Like the java source code, first write a Btrace script (also a java file), compile (compiler), send it to agent,agent through client, add it to JVM by attach api and start agent server to receive the content sent by client, then the bottom layer is to use ASM to modify the bytecode file, and then use Java Instrument's retransform interface to replace the modified class file, and then send the output to client through agent for display.

3 BTrace installation

Now that you know how BTrace works, you can install it and practice it. The example used in this article is still java-monitor-example. BTrace is easy to install and can be used right out of the box.

Download address (the latest version is [v1.3.11.3]): https://github.com/btraceio/btrace/releases

Extract it to the server where the java application needs to be monitored

The command for btrace is in the bin directory

To be executable in any directory, you need to set btrace to the environment variable (export)

4 applicable scenarios for BTrace

Basically, BTrace is only suitable for dynamically tracking the output of classes, and cannot add attributes, delete methods, modify inheritance, and so on, which is consistent with the restrictions of Instrument mentioned earlier. Generally speaking, online application monitoring using Btrace belongs to the log output category, and most of them include the following scenarios:

View the input parameters and return values in a method

View the response time of a method

Check to see if a line of code has been executed to

Print system parameters or JVM startup parameters

Print the thread stack of the method call

Print exception information when an exception occurs

5 BTrace use

As a stand-alone tool, Btrace can only be run locally by default, that is, if you want to monitor which java application is running, you need to extract it to the corresponding server. In this example, java-monitor-example is run as a java application that needs to be monitored, and then according to the monitoring business requirements, write scripts, run scripts, and view the output.

5.1.1 Notes and BTraceUtils

The script of Btrace is the same as writing java code, but it is relatively simple, mainly using the annotations and BTraceUtils provided by Btrace. Annotations are used to tell Btrace the class to be intercepted, the timing of interception, the location of interception, and so on. BTraceUtils is used to provide the function of printing out information. For example, the example on the official website is as follows:

Package samples;import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;/** * This script traces method entry into every method of * every class in javax.swing package! Think before using * this script-- this will slow down your app significance! * / @ BTrace public class AllMethods {@ OnMethod (clazz= "/ javax\\ .swing\\.. * /", method= "/ .* /") public static void m (@ ProbeClassName String probeClass, @ ProbeMethodName String probeMethod) {print ("entered", probeClass); println (Strings.strcat (".", probeMethod));}}

The above code, which indicates that it intercepts all calls to methods that start with javax.swing, then prints out the class name and method name. You'll notice that the annotations have @ BTrace, @ OnMethod, @ ProbeClassName,@ProbeMethodName, while print,println is a static method provided by BTraceUtils. BTraceUtils also provides a number of printing methods (mentioned in the later example). Also note that trace operations need to be specified in the static method body, so the static method is required.

In addition, for the comments provided by BTrace, please refer to the official documentation (https://github.com/btraceio/btrace/wiki/BTrace-Annotations) for details. It mainly includes the following:

/ * * Class Annotations*/@com.sun.btrace.annotations.DTrace@com.sun.btrace.annotations.DTraceRef@com.sun.btrace.annotations.BTrace/**Method Annotations*/@com.sun.btrace.annotations.OnMethod@com.sun.btrace.annotations.OnTimer@com.sun.btrace.annotations.OnError@com.sun.btrace.annotations.OnExit@com.sun.btrace.annotations.OnEvent@com.sun.btrace.annotations.OnLowMemory@com.sun.btrace.annotations.OnProbe/**Argument Annotations* / @ com.sun.btrace.annotations.Self@com.sun.btrace.annotations.Return@com.sun.btrace.annotations.CalledInstance@com.sun.btrace.annotations.CalledMethod/**Field Annotations*/@com.sun.btrace.annotations.Export@com.sun.btrace.annotations.Property@com.sun.btrace.annotations.TLS

Among them, @ OnMethod is used more frequently, which needs to be emphasized. It is mainly three properties, clazz,method and location.

Clazz: the full path name of the class, such as me.mason.monitor.controller.UserController

Method: the name of the method to be monitored, such as getUsers

Location: when to intercept, use the @ Location annotation.

There are several types of @ Location:

Kind.ENTRY: called when entering a method

Kind.RETURN: it is called when the method is executed. Only if the intercept position is defined as Kind.RETURN, can you get the return result @ Return and execution time @ Duration of the method.

Kind.CALL: called when other methods are called in the

Kind.LINE: by setting line, you can monitor whether the code is executed at the specified location

Kind.ERROR, Kind.THROW, Kind.CATCH: tracking of anomalies

5.1.2 about writing

It is recommended to use the development environment of java's maven project to write, and you can use the code hint function. Write it and then put it in the corresponding server that needs to be monitored. However, when editing, you need to refer to the corresponding jar package (btrace-agent,btrace-boot,btrace-client), and the corresponding jar is in the build directory under the downloaded installation. It can be used through the introduction of pom.xml. As follows:

Com.sun.btrace btrace-agent 1.3.11.3 jar system E:/btrace-bin-1.3.11.3/build/btrace-agent.jar com.sun.btrace btrace-boot 1.3.11.3 jar system E:/btrace-bin-1.3.11.3/build/btrace-boot.jar com.sun.btrace btrace-client 1.3.11.3 jar system E:/btrace-bin-1 .3.11.3/build/btrace-client.jar5.2 script run

Print help information as follows:

Generally speaking, on the server, it is directly btrace PID btraceFile.java, and then check the output (you can also output the content to a file and then view it, such as btrace PID btraceFile.java > info.txt). If you are using a specific jar package, you need to add the parameter cp or classpath. The following example outputs the return value of the calling method:

5.3 script example

Here are a few commonly used examples to illustrate the use of the BTrace script, which is located in the btrace directory in the sample project java-monitor-example. In java-monitor-example, there is a controller and a service, which are defined by the following methods, and the following methods will be used for dynamic tracking.

/ * UserController.java * * / @ GetMapping ("/ user") public ResponseResult getUser () {User user = userService.getUser (); return ResponseResult.ok (user);} @ GetMapping ("/ users") public ResponseResult getUsers (int num) {List users = userService.getUsers (num); return ResponseResult.ok (users);} / * * UserService.java * obtain users according to ID * * @ return * / public User getUser () {return mockUser () } / * get the user array * * @ return * / public List getUsers (int num) {userList.clear (); for (int iTun0; I < num; iTunes +) {userList.add (mockUser ());} return userList;} 5.3.1 print method information

Print the parameters when the method is called (when the getUsers method of UserController is called)

@ OnMethod (clazz = "me.mason.monitor.controller.UserController", method = "getUsers", location = @ Location (Kind.ENTRY)) public static void readFunction (@ ProbeClassName String className, @ ProbeMethodName String methodName, AnyType [] args) {/ / print time BTraceUtils.println (BTraceUtils.Time.timestamp ("yyyy-MM-dd HH:mm:ss")); BTraceUtils.println ("method controller"); BTraceUtils.printArray (args) BTraceUtils.println (className + "," + methodName); BTraceUtils.println ("=");}

Print the return value when the method is called

@ OnMethod (clazz = "me.mason.monitor.service.UserService", method = "getUsers", location = @ Location (Kind.RETURN)) public static void printReturnData1 (@ Return AnyType result) {BTraceUtils.println (BTraceUtils.Time.timestamp ("yyyy-MM-dd HH:mm:ss")); BTraceUtils.printFields (result); BTraceUtils.println ("="); BTraceUtils.println (BTraceUtils.str (result)); BTraceUtils.println ("=");}

Number of rows executed (check to see if 39 lines of UserService are executed)

@ OnMethod (clazz = "me.mason.monitor.service.UserService", method = "getUsers", location = @ Location (value = Kind.LINE,line = 39)) public static void printLineData (@ ProbeClassName String className, @ ProbeMethodName String methodName,int line) {BTraceUtils.println (BTraceUtils.Time.timestamp ("yyyy-MM-dd HH:mm:ss")); BTraceUtils.println (className + "," + methodName + "," + line); BTraceUtils.println ("=");}

The time it takes to execute the method (how long does UserController's getUsers method take)

@ OnMethod (clazz = "me.mason.monitor.controller.UserController", method = "getUsers", location = @ Location (Kind.RETURN)) public static void getUsersDuration (@ Duration long duration) {BTraceUtils.println (BTraceUtils.Time.timestamp ("yyyy-MM-dd HH:mm:ss")); BTraceUtils.println ("time (ns):" + duration); BTraceUtils.println ("time (ms):" + BTraceUtils.str (duration / 1000000)) BTraceUtils.println ("time (s):" + BTraceUtils.str (duration / 1000000000)); BTraceUtils.println ("=");} 5.3.2 print system properties and JVM properties

Similar to the command line tool jinfo of JDK, jmap and jstatck can also query official examples.

@ BTracepublic class JInfo {static {println ("System Properties:"); printProperties (); println ("VM Flags:"); printVmArguments (); println ("OS Enviroment:"); printEnv (); exit (0);}} 5.3.3 print abnormal output

Java developers should know that java exceptions are divided into Error and Exception, and they are all subclasses of Throwable, that is, the parent of all exceptions in java is Throwable, so trace this constructor and print out the stack. As follows:

/ / Local variable storage exception @ TLS static Throwable currentException;// exception constructor starts @ OnMethod (clazz= "java.lang.Throwable", method= "") public static void onthrow (@ Self Throwable self) {currentException = self } / / exception constructor ends, output stack @ OnMethod (clazz= "java.lang.Throwable", method= ", location=@Location (Kind.RETURN)) public static void onthrowreturn () {if (currentException! = null) {Threads.jstack (currentException); println (" = "); currentException = null;}} 5.4 script limit

BTrace is "read-only" to JVM. What BTrace needs to do is to change the bytecode, but mainly to output the required information, which has no effect on the normal operation of the whole program. It is important to note that because the class file is replaced dynamically, the modified bytecode is not automatically restored. The official documentation also states that BTrace scripts have the following restrictions:

Creation of objects is not allowed

Creation of arrays is not allowed

Exception is not allowed

Catch exceptions are not allowed

It is not allowed to call methods of other objects or classes at will, only static methods provided in com.sun.btrace.BTraceUtils (some data processing and information output tools) are allowed.

It is not allowed to change the properties of a class

No member variables and methods are allowed, only static public void methods are allowed

Inner classes and nested classes are not allowed

Synchronization methods and synchronization blocks are not allowed

Loops are not allowed

It is not allowed to inherit other classes at will (except java.lang.Object, of course)

Implementation of interfaces is not allowed

Assert is not allowed

Class objects are not allowed

6 some experience

Set up the development environment of the maven project using java to write scripts, and introduce the corresponding jar to provide code hints.

Check out the official examples, which have been provided in the download package at btrace-bin-1.3.11.3\ samples directory

For the input parameters tracked in the BTrace script, the return value types are simple types that are directly used (such as int, float, etc.), and complex types can use AnyType, but if you are using the types in the custom package (such as User), you need to add cp or classpath parameters to specify the custom package when you run the script.

General simple type or string, directly use print or println, print object properties can use printFields, print List, can use BTraceUtils.println (BTraceUtils.str (list))

Print separations on the last line of the probe method, which is strongly recommended. It may be due to buffer delay in the output, and if the output is not delimited, the output may not be output or the content may not be separated after the output. Separation can be done with BTraceUtils.println or BTraceUtils.println ("=").

7 Summary

For online java applications, if you want to keep serving the log output to diagnose problems, dynamic tracking technology is essential, and Btrace is a powerful tool to use this technology to achieve dynamic tracking. This paper describes in detail the operation principle, installation, application scenario, script compilation and operation of Btrace, hoping to help you deepen your understanding of Btrace and solve online problems more conveniently and efficiently.

Thank you for reading, the above is the content of "java uses BTrace to achieve online dynamic diagnosis". After the study of this article, I believe you have a deeper understanding of the problem of java using BTrace to achieve online dynamic diagnosis, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report