Agent Extensions

The Flopsar Agent can operate as a standalone solution or be extended with user-defined custom code. It is a robust engine that supports extensibility through plugins. These extensions consist of additional JAR files containing user-defined POJO (Plain Old Java Object) classes. The JAR files can be uploaded directly to the Flopsar server, enabling the agent's capabilities to be extended.

This extensibility mechanism allows users to enhance application diagnostics and trace data flow more effectively, making Flopsar an open and adaptable tool. With the plugin system, users can process data within instrumented methods, providing deeper insights and custom processing capabilities.

There are two types of extensions, which can be used: standard and custom.

Standard

The standard extension is embedded in the agent. This extension will execute the following method on each argument it gets:

public static java.lang.String valueOf(java.lang.Object);

and return a result in a form of concatenated pairs of parameter identifiers and the corresponding valueOf function result. The following parameters are returned (in order of appearance):

  • THIS : If the instrumented method is static, this parameter is null, otherwise a class instance the method is executed on.

  • ARGS : List of all arguments of the instrumented method.

  • RET: Only if the instrumented method does not return void and the instrumentation is performed at the method exit.

Custom

If you are not satisfied with standard extension and you want to extract some additional information (or make some preprocessing) you must implement your own, custom extension. In order to take advantage of this feature, all you have to do is set up a configuration, create a simple POJO class and implement a single method:

public static java.lang.String myFormatter(java.lang.Object[] args)

You can give any name to the above method but the signature of the method must be preserved. Otherwise, it will not work.

The args argument of the extension method is an array of the instrumented method arguments delivered to your method. These are your original application objects, not clones. When you set up the configuration correctly, the agent will inject your code into the instrumented methods during the instrumentation. It can be injected in one of the two places, i.e. at the beginning or the end of the method. Note, your formatter code is executed inside your instrumented method, so make sure your formatter code generates minimal overhead. The argument args is an array of the following objects (in order of appearance):

  • args[0] If the instrumented method is static this element is null, otherwise it is a reference to a class instance the instrumented method is executed on.

  • args[1..N] List of all arguments of the instrumented method in the same order as they appear in the method signature. These are the references to your original application objects, not some clones.

  • args[N+1] It is a reference to the object instance this method returns. Please note, this argument is passed to the formatter if and only if the instrumentation is performed at the end of the method.

where N is the number of the instrumented method arguments.

When you set up the configuration correctly, the agent will inject your formatter code into the instrumented methods during the instrumentation. It can be injected in one of the two places, i.e. at the beginning or the end of the method. Note, your extension code is executed inside your instrumented method, so make sure your code generates minimal overhead.

In fact, it is up to you what extra features the agent will have. You can even extend your agent installation to cover a distributed transaction tracing.

Use U+001E as a separator in your code. Otherwise, the result will not be formatted properly in the workstation.

Your result should always consist of pairs of keys and values. U+001E separates each entry in the result, which means you should always have an odd number of separators. The resulting string size cannot be greater than 8192 B, otherwise it will be truncated.

There are some tips, you should take into account when writing extensions:

  • Design and implement extensions with performance in mind. If your code performs poorly, obviously the instrumented methods will perform poorly as well.

  • Use try-catch block to protect your application from any errors you can make in your extension implementation. Otherwise, any errors inside the extension code can interfere with your application processing.

  • Do not modify arguments delivered to your extension since they are your genuine application objects. Make sure that whatever you do with them will not cause any problem to your application flow.

  • Try not to use reflections, unless there is no other way.

  • Try not to create too many new objects, otherwise you risk increased GC overhead.

  • Deploy your extension classes into separate jar files. This can save you a lot of trouble when dealing with class loading issues.

  • Your extension code should be stateless.

Example

Suppose, you have some method:

public FooBar foo(foo.bar.Object1, foo.bar.Object2, ...);

and you are interested in some additional information extracted from the first and second arguments. Your extension implementation can look like the one below:

public static java.lang.String myFormatter(java.lang.Object[] args){

        final char SEPARATOR = 0x1E;

        try {
                foo.bar.Object0 _this = (foo.bar.Object0)args[0];
                foo.bar.Object1 obj1 = (foo.bar.Object1)args[1];
                foo.bar.Object2 obj2 = (foo.bar.Object2)args[2];
                /*
                 implement your logic here
                 to produce string output.
                */
                String output1 = some_logic1(obj1);
                String output2 = some_logic2(obj2);

                return "Object1"+SEPARATOR+output1+SEPARATOR+"Object2"+SEPARATOR+output2;

        } catch(Throwable ex){
                return "Error"+SEPARATOR+ex.getMessage();
        }
}

Flopsar Technology cannot be held accountable for any damage done by badly written user's extensions.

Last updated