Injected probe API

A resource document of the JProfiler MCP server. Back to the tool and resource reference.

For agent consumption, this page is also available as raw Markdown.

Content of the MCP resource jprofiler://api/probe-injected of the JProfiler MCP server, see the tool and resource reference for the full list of tools and resources.

API reference of com.jprofiler.api.probe.injected for writing injected custom probes: the @Probe annotation, the interception declarations in the interception package, the injected parameter annotations in the parameter package and the telemetry annotations. Read jprofiler://probes/custom first for the embedded/injected decision, build setup, deployment and recording.

Types

Flat alphabetical index of every type in the API. Use this when you know the qualified name and want to skip package navigation.

Qualified nameKindFile
com.jprofiler.api.probe.injected.ControlObjectNameannotationControlObjectName
com.jprofiler.api.probe.injected.PayloadinterfacePayload
com.jprofiler.api.probe.injected.ProbeannotationProbe
com.jprofiler.api.probe.injected.ProbeContextinterfaceProbeContext
com.jprofiler.api.probe.injected.ThreadStateenumThreadState
com.jprofiler.api.probe.injected.TypeCustomizerinterfaceTypeCustomizer
com.jprofiler.api.probe.injected.interception.AdditionalInterceptionannotationAdditionalInterception
com.jprofiler.api.probe.injected.interception.InterceptionannotationInterception
com.jprofiler.api.probe.injected.interception.InvocationTypeenumInvocationType
com.jprofiler.api.probe.injected.interception.MethodSpecannotationMethodSpec
com.jprofiler.api.probe.injected.interception.PayloadInterceptionannotationPayloadInterception
com.jprofiler.api.probe.injected.interception.SplitInterceptionannotationSplitInterception
com.jprofiler.api.probe.injected.parameter.DeclaringClassannotationDeclaringClass
com.jprofiler.api.probe.injected.parameter.ExceptionValueannotationExceptionValue
com.jprofiler.api.probe.injected.parameter.ParameterannotationParameter
com.jprofiler.api.probe.injected.parameter.ReturnValueannotationReturnValue
com.jprofiler.api.probe.injected.parameter.ThisValueannotationThisValue
com.jprofiler.api.probe.injected.telemetry.TelemetryannotationTelemetry
com.jprofiler.api.probe.injected.telemetry.TelemetryFormatannotationTelemetryFormat
com.jprofiler.api.probe.injected.telemetry.TelemetryUnitenumTelemetryUnit

Package com.jprofiler.api.probe.injected

Contains the classes for creating an injected probe.

Purpose of injected probes

Please read the "Probe concepts" chapter in the documentation (directory $JPROFILER_HOME/doc) for an overview on the different types of custom probes in JProfiler and the "Injected probes" chapter for an extended discussion of injected probes.

Injected probes allow you to add functionality similar to the built-in probes in JProfiler. In contrast to the "embedded" probe API, the "injected" probe API monitors software components whose source code is not under your control. If you develop software like a container or a database driver and want to make JProfiler aware of its high-level semantics, use the embedded probe API instead.

Getting started

To define an injected probe, annotate a class with Probe. Such a probe class can contain public static methods annotated with Interception, PayloadInterception, SplitInterception, AdditionalInterception, ControlObjectName and Telemetry.

To get started with writing injected probes, have a look at the $JPROFILER_HOME/api/samples/simple-injected-probe example project. Open the gradle build file build.gradle in an editor for instructions on how to run it.

JAR file and dependency

All classes in this package are contained in $JPROFILER_HOME/api/jprofiler-probe-injected.jar. The injected probe API is also available as a dependency. In the snippets below, "VERSION" should be replaced with the corresponding JProfiler version.

Maven

<dependency>
  <groupId>com.jprofiler</groupId>
  <artifactId>jprofiler-probe-injected</artifactId>
  <version>VERSION</version>
</dependency>

Gradle

dependencies {
  implementation group: 'com.jprofiler', name: 'jprofiler-probe-injected', version: 'VERSION'
}

Deployment

To load injected custom probes, pass

     -Djprofiler.probeClassPath=...

to the profiled JVM. The probe classpath can contain directories and JAR files, separated with the path separator (';' for Windows and ':' for other platforms). Note that the custom probe classes must not be on the class path. The profiling agent will scan the probe classpath and find all probe definitions.

Alternatively, you can set

     -Djprofiler.customProbes=...

to a comma-separated list of fully qualified class names that will be loaded from the class path.

License

Classes in this package and its sub-packages are licensed under the Apache License, version 2.0.

ControlObjectName

Import: import com.jprofiler.api.probe.injected.ControlObjectName;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface ControlObjectName implements Annotation

Marks an optional method in your probe that will be called for previously unknown control objects. Control objects can be specified with ProbeContext.createPayload. The method must be public and static with a single parameter of type Object and return a String.

Usually, control objects should be opened with ProbeContext.openControlObject

Payload

Import: import com.jprofiler.api.probe.injected.Payload;

interface Payload

Payload type with enhanced functionality. To use this functionality, your probe method must return instances of this type instead of String, declare a parameter with type ProbeContext to get a context instance and call ProbeContext.createPayload to create a payload that it can return.

Do not create your own subtypes.

Methods

SignatureReturnsDescription
getName()StringThe name for this payload.
getEventType()Enum<?>The type of the payload.
getControlObject()ObjectThe control object for this payload.

##### getName()

String getName()

The name for this payload.

Returns: the name or null if none was provided yet

##### getEventType()

Enum<?> getEventType()

The type of the payload. One of the enum constants of Probe.customTypes.

Returns: the type or null if none was provided

##### getControlObject()

Object getControlObject()

The control object for this payload.

Returns: the control object or null if none was provided

Probe

Import: import com.jprofiler.api.probe.injected.Probe;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@interface Probe implements Annotation

Marks a class that defines an injected probe and parametrizes the probe. The probe class will be scanned for public static methods that are annotated with Interception, PayloadInterception, SplitInterception, AdditionalInterception, ControlObjectName and Telemetry.

Elements

ElementTypeDefaultDescription
nameString—The name of the probe in the JProfiler UI.
descriptionString""An optional description of this probe.
eventsbooleantrueConfigures if this probe shows an events view in the JProfiler UI.
controlObjectsbooleanfalseConfigures if this probe shows the timeline and control objects views in the JProfiler UI.
defaultTelemetriesbooleantrueConfigures if this probe should record the "Events", "Average Duration" and - if control objects are recorded - the "Recorded Open Control Objects" telemetries.
customTypesClass<? extends Enum>java.lang.Enum.classYou can specify custom types for events.

##### name

The name of the probe in the JProfiler UI. In the JProfiler UI, this string is used for the view name in the view selector below the "JEE & probes" section.

##### description

An optional description of this probe. It is shown in the probe view below the probe name.

##### events

Configures if this probe shows an events view in the JProfiler UI.

##### controlObjects

Configures if this probe shows the timeline and control objects views in the JProfiler UI.

You must make use of ProbeContext.createPayload to associate control objects with payloads.

##### defaultTelemetries

Configures if this probe should record the "Events", "Average Duration" and - if control objects are recorded - the "Recorded Open Control Objects" telemetries.

##### customTypes

You can specify custom types for events. If control objects are recorded, the same types are used for the associated control object states. Specify an Enum class with all your states as constants. The toString() method is used for the event display name. You can further customize your events by implementing TypeCustomizer in the enum class.

ProbeContext

Import: import com.jprofiler.api.probe.injected.ProbeContext;

interface ProbeContext

An interface for enhanced probe functionality. In methods annotated with Interception, PayloadInterception, SplitInterception and AdditionalInterception, you can declare a parameter of this type in any position in order to get an instance of this interface.

Methods

SignatureReturnsDescription
openControlObject(Object, String)voidRecords an open event for a control object and assigns a name to it.
closeControlObject(Object)voidCloses a control object.
createPayload(String, Object, Enum<?>)PayloadCreates an enhanced payload object with type and control object info.
createPayloadWithDeferredName(Object, Enum<?>)PayloadCreates an enhanced payload object with type and control object info whose name you don't know yet.
getOuterPayload()PayloadRetrieves the payload information that has been created by an outer interception, either through recursion or by a different intercepted method.
restartTiming()voidIf a payload is currently recorded by an outer interception, restart timing.
restartTimingAndLocation()voidIf a payload is currently recorded by an outer interception, restart timing and set the call tree to the location of the latest PayloadInterception or the latest SplitInterception with SplitInterception.payloads set to true.
isRecording()booleanReturns the recording state of the probe.

##### openControlObject(Object, String)

void openControlObject(Object controlObject, String name)

Records an open event for a control object and assigns a name to it. The control object will be displayed in the control objects view and the timeline. You must set Probe.controlObjects to true to enable control object recording as a capability for the probe.

If you don't use this method and a previously unknown control object is used in a ProbeContext.createPayload call and you have annotated a method in your probe class with ControlObjectName, that method will be called to create a name for the new control object. No open event will be created in the events view in that case.

Parameters:

  • controlObject — the control object
  • name — the name of the control object

##### closeControlObject(Object)

void closeControlObject(Object controlObject)

Closes a control object. If the control object is not currently open, this method has no effect.

Parameters:

  • controlObject — the control object

##### createPayload(String, Object, Enum<?>)

Payload createPayload(String name, Object controlObject, Enum<?> type)

Creates an enhanced payload object with type and control object info. You can use the created object in

If you don't want to assign states or control objects, you can just return the name as a String directly.

Parameters:

  • name — the name of the recorded payload. If null, the payload recording will be discarded.
  • type — the payload type. Must be an object of your custom enum class registered with Probe.customTypes or null.
  • controlObject — the control object this payload belongs to or null. If control objects should be recorded, you have to set Probe.controlObjects to true.

Returns: a Payload instance to be returned by your interception method

##### createPayloadWithDeferredName(Object, Enum<?>)

Payload createPayloadWithDeferredName(Object controlObject, Enum<?> type)

Creates an enhanced payload object with type and control object info whose name you don't know yet. You can use the created object in a method returning a Payload that is annotated with PayloadInterception and where PayloadInterception.invokeOn is set to InvocationType.ENTER.

To supply the name at a later point, you have to define a method right below the current method, annotate it with AdditionalInterception and return a String.

If you don't want to assign states or control objects, you can set PayloadInterception.invokeOn to InvocationType.EXIT and return the name as a String directly.

Parameters:

  • type — the payload type. Must be an object of your custom enum class registered with Probe.customTypes or null.
  • controlObject — the control object this payload belongs to or null. If control objects should be recorded, you have to set Probe.controlObjects to true.

Returns: a Payload instance to be returned by your interception method

##### getOuterPayload()

Payload getOuterPayload()

Retrieves the payload information that has been created by an outer interception, either through recursion or by a different intercepted method.

If your inner interception method is annotated with PayloadInterception, you can return this payload to keep the payload information unchanged. A SplitInterception won't change an outer payload, so this does not apply for nested splits.

Returns: the current payload or null if there is no current payload defined.

##### restartTiming()

void restartTiming()

If a payload is currently recorded by an outer interception, restart timing.

##### restartTimingAndLocation()

void restartTimingAndLocation()

If a payload is currently recorded by an outer interception, restart timing and set the call tree to the location of the latest PayloadInterception or the latest SplitInterception with SplitInterception.payloads set to true.

##### isRecording()

boolean isRecording()

Returns the recording state of the probe.

Methods annotated with PayloadInterception are only called when probe recording is turned on. Methods annotated with SplitInterception are called when CPU or allocation recording is turned on. If SplitInterception.payloads is set to true, they are also called when only probe recording is turned on. Methods annotated with Interception are always called.

Returns: true if your probe is being recorded

ThreadState

Import: import com.jprofiler.api.probe.injected.ThreadState;

public final enum ThreadState

Allows you to override the thread state recorded in JProfiler.

You can nest calls to ThreadState.enter and ThreadState.exit, but only the outermost call is used for recording.

It is very important that a matching ThreadState.exit is always called, so if you call ThreadState.enter in an Interception with Interception.invokeOn set to InvocationType.ENTER, you must always define a method right below it that is annotated with AdditionalInterception with AdditionalInterception.value set to InvocationType.EXIT where you call ThreadState.exit.

Constants

##### RUNNABLE

The current thread is runnable.

##### WAITING

The current thread is waiting.

##### BLOCKED

The current thread is blocked on a monitor.

##### NETIO

The current thread is in a Net IO operation.

Methods

SignatureReturnsDescription
values()ThreadState[]
valueOf(String)ThreadState
enter()voidEnters a thread state.
exit()voidExits the current override state and resets the state to the value reported by the JVM.

##### values()

public static ThreadState[] values()

##### valueOf(String)

public static ThreadState valueOf(String name)

##### enter()

public void enter()

Enters a thread state. This state will be recorded until the matching exit is called.

##### exit()

public static void exit()

Exits the current override state and resets the state to the value reported by the JVM.

TypeCustomizer

Import: import com.jprofiler.api.probe.injected.TypeCustomizer;

interface TypeCustomizer

Interface to further customize event enums configured with Probe.customTypes. Your enum class can implement this interface to customize the color of your types.

Methods

SignatureReturnsDescription
getColor()intThe color of your enum constant.

##### getColor()

int getColor()

The color of your enum constant.

Returns: the RGB int value of a color, for example 0xCCAA00

Package com.jprofiler.api.probe.injected.interception

Contains the annotations for specifying which methods should be intercepted.

AdditionalInterception

Import: import com.jprofiler.api.probe.injected.interception.AdditionalInterception;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface AdditionalInterception implements Annotation

Marks a probe method to be called at an additional point of the previously declared interception. The source file method order will be used to determine the previous interception that this additional interception belongs to.

The annotated method must be public and static. If the main interception is a PayloadInterception that returns Payload, the probe method annotated with AdditionalInterception can return a String to update the payload name. Otherwise, the probe method must return void.

You can get information from the intercepted method like parameter values, the instance or the return value by declaring parameters annotated with the annotations from the com.jprofiler.api.probe.injected.parameter package. You can also declare a parameter of type ProbeContext to open or close control objects or check if the probe is currently being recorded.

Elements

ElementTypeDefaultDescription
valueInvocationType—The point at which the annotated probe method is invoked.

##### value

The point at which the annotated probe method is invoked.

Interception

Import: import com.jprofiler.api.probe.injected.interception.Interception;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface Interception implements Annotation

Declares an interception that does not split the call tree or create a payload. The annotated probe method must be public and static and return void.

You can get information from the intercepted method like parameter values, the instance or the return value by declaring parameters annotated with the annotations from the com.jprofiler.api.probe.injected.parameter package. You can also declare a parameter of type ProbeContext to open or close control objects or check if the probe is currently being recorded.

Elements

ElementTypeDefaultDescription
invokeOnInvocationType—The point at which the annotated probe method is invoked.
methodMethodSpec—Specifies the method that should be intercepted.
reentrantbooleantrueIndicates if your interception is reentrant.

##### invokeOn

The point at which the annotated probe method is invoked.

##### method

Specifies the method that should be intercepted.

##### reentrant

Indicates if your interception is reentrant. If false, the probe method will not be called for recursive invocations of the intercepted method.

InvocationType

Import: import com.jprofiler.api.probe.injected.interception.InvocationType;

public final enum InvocationType

Specifies the point at which the probe method is invoked.

Constants

##### ENTER

The probe method will be called before any code of the intercepted method is called. You cannot use ReturnValue or ExceptionValue parameters for methods of this type.

##### EXIT

The probe method will be called when the intercepted method exits, either by returning normally or by throwing an exception. You can use both ReturnValue and ExceptionValue parameters for methods of this type. If the intercepted method returns normally, the ExceptionValue parameter will be null. If the method throws an exception, the ReturnValue parameter will be null.

This type cannot be used for constructors.

##### RETURN

The probe method will be called when the intercepted method returns normally. You can use a ReturnValue parameter, but no ExceptionValue parameter for methods of this type.

##### EXCEPTION

The probe method will be called when the intercepted method throws an exception. You can use an ExceptionValue parameter, but no ReturnValue parameter for methods of this type.

This type cannot be used for constructors.

Methods

SignatureReturnsDescription
values()InvocationType[]
valueOf(String)InvocationType

##### values()

public static InvocationType[] values()

##### valueOf(String)

public static InvocationType valueOf(String name)

MethodSpec

Import: import com.jprofiler.api.probe.injected.interception.MethodSpec;

@interface MethodSpec implements Annotation

Specification of the intercepted method.

Elements

ElementTypeDefaultDescription
classNameString—The fully qualified name of the highest type in the class hierarchy where the method is implemented.
methodNameString—The name of the method.
parameterTypesString[]—The array of all parameter types that the method declares.
returnTypeString—The return type that the method declares.
subtypesbooleanfalseIf false, only the method contained in MethodSpec.className will be instrumented, but not in derived classes.

##### className

The fully qualified name of the highest type in the class hierarchy where the method is implemented. Can be an empty string if you would like to instrument all methods with the given name and signature. Packages are separated with dots, inner classes with '$'.

##### methodName

The name of the method. If you would like to instrument a constructor, use <init>.

##### parameterTypes

The array of all parameter types that the method declares. The types must be fully qualified. Packages are separated with dots, inner classes with '$'. Arrays are specified with a trailing '[]'. Generic types must be erased (java.util.List<T> -> java.util.List). Type parameters must be replaced by their upper bounds (java.lang.Object for <T>, java.util.List for <T extends List<U>>).

##### returnType

The return type that the method declares. The type must be fully qualified. Packages are separated with dots, inner classes with '$'. Arrays are specified with a trailing '[]'. Generic types must be erased (java.util.List<T> -> java.util.List). Type parameters must be replaced by their upper bounds (java.lang.Object for <T>, java.util.List for <T extends List<U>>).

##### subtypes

If false, only the method contained in MethodSpec.className will be instrumented, but not in derived classes. If true, the matching methods in MethodSpec.className and all its subtypes will be instrumented.

PayloadInterception

Import: import com.jprofiler.api.probe.injected.interception.PayloadInterception;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface PayloadInterception implements Annotation

Declares an interception that creates a payload. The annotated probe method must be public and static and return String or Payload.

You can get information from the intercepted method like parameter values, the instance or the return value by declaring parameters annotated with the annotations from the com.jprofiler.api.probe.injected.parameter package. You can also declare a parameter of type ProbeContext to open or close control objects or create payloads with enhanced functionality.

If you return a Payload to specify control objects or custom event types, you must declare a parameter of type ProbeContext and create the returned object with ProbeContext.createPayload or ProbeContext.createPayloadWithDeferredName. The PayloadInterception.invokeOn argument must be set to InvocationType.ENTER in that case.

If you create a Payload with a deferred name because the payload name cannot be determined at method entry, you must declare a method directly below the current interception method, annotate it with AdditionalInterception where AdditionalInterception.value is set to InvocationType.EXIT and return a String from that method.

If you don't want to create a payload for the current invocation, the probe method can return null.

Elements

ElementTypeDefaultDescription
invokeOnInvocationType—The point at which the annotated probe method is invoked.
methodMethodSpec—Specifies the method that should be intercepted.
reentrantbooleanfalseIndicates if your interception is reentrant.
exceptionPayloadsbooleanfalseIf payloads should also be recorded if the method throws an exception.

##### invokeOn

The point at which the annotated probe method is invoked.

##### method

Specifies the method that should be intercepted.

##### reentrant

Indicates if your interception is reentrant. If false, the probe method will not be called for recursive invocations of the intercepted method.

If true, the payload name (and the other information in Payload) returned by the subsequent inner calls will be used, but timing and call tree location will be used from the outermost call. You can use ProbeContext.restartTiming and ProbeContext.restartTimingAndLocation to customize this behavior. If you want to retain the name from outer calls you can use ProbeContext.getOuterPayload.

##### exceptionPayloads

If payloads should also be recorded if the method throws an exception. If PayloadInterception.invokeOn is set to InvocationType.EXCEPTION or InvocationType.EXIT, JProfiler will always record payloads for exceptional exits.

SplitInterception

Import: import com.jprofiler.api.probe.injected.interception.SplitInterception;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface SplitInterception implements Annotation

Declares an interception that creates a split in the call tree and optionally an associated payload. The annotated probe method must be public and static and return String or Payload.

You can get information from the intercepted method like parameter values or the instance by declaring parameters annotated with the annotations from the com.jprofiler.api.probe.injected.parameter package. You can also declare a parameter of type ProbeContext to open or close control objects or check if the probe is currently being recorded.

If you return a Payload to specify control objects or custom event types, you must declare a parameter of type ProbeContext and create the returned object with ProbeContext.createPayload.

If you don't want to create a split for the current invocation, the probe method can return null.

Elements

ElementTypeDefaultDescription
methodMethodSpec—Specifies the method that should be intercepted.
payloadsbooleantrueIf payloads should be created in addition to the call tree split.
reentrantbooleanfalseIndicates if your interception is reentrant.
exceptionPayloadsbooleanfalseIf payloads should also be recorded if the method throws an exception.

##### method

Specifies the method that should be intercepted.

##### payloads

If payloads should be created in addition to the call tree split.

##### reentrant

Indicates if your interception is reentrant. If false, the probe method will not be called for recursive invocations of the intercepted method and only one split will be created.

If true, splits will be nested, but only one payload will be created for the outermost call.

##### exceptionPayloads

If payloads should also be recorded if the method throws an exception.

Package com.jprofiler.api.probe.injected.parameter

Contains the annotations for specifying the parameters of interception methods.

With the annotations in this package, methods annotated with Interception, PayloadInterception, SplitInterception and AdditionalInterception can declare parameters to receive further information from the intercepted method.

DeclaringClass

Import: import com.jprofiler.api.probe.injected.parameter.DeclaringClass;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
@interface DeclaringClass implements Annotation

Assigns the class of the intercepted method to a parameter of a probe method. The probe method can be annotated with Interception, PayloadInterception, SplitInterception or AdditionalInterception. The type of the annotated parameter must be Class.

ExceptionValue

Import: import com.jprofiler.api.probe.injected.parameter.ExceptionValue;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
@interface ExceptionValue implements Annotation

Assigns the exception thrown by the intercepted method to a parameter of a probe method. The probe method can be annotated with Interception, PayloadInterception or AdditionalInterception whose invocation type is set to InvocationType.EXIT or InvocationType.EXCEPTION. The type of the annotated parameter must be Throwable.

If the invocation type is set to InvocationType.EXIT and the instrumented method returns normally, the argument will be null.

Parameter

Import: import com.jprofiler.api.probe.injected.parameter.Parameter;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
@interface Parameter implements Annotation

Assigns the argument with index Parameter.value of the intercepted method to a parameter of a probe method. The probe method can be annotated with Interception, PayloadInterception, SplitInterception or AdditionalInterception. The type of the annotated parameter must be Object or the declared type of the parameter of the instrumented method. The declared type can only be used if it can be resolved by the system class loader.

Elements

ElementTypeDefaultDescription
valueint—The zero-based index of the parameter

##### value

The zero-based index of the parameter

ReturnValue

Import: import com.jprofiler.api.probe.injected.parameter.ReturnValue;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
@interface ReturnValue implements Annotation

Assigns the return value of the instrumented method to a parameter of a probe method. The probe method can be annotated with Interception, PayloadInterception or AdditionalInterception whose invocation type is set to InvocationType.EXIT or InvocationType.RETURN. The type of the annotated parameter must be Object or the declared return type of the instrumented method. The declared type can only be used if it can be resolved by the system class loader.

If the invocation type is set to InvocationType.EXIT and the instrumented method throws an exception, the argument will be null.

ThisValue

Import: import com.jprofiler.api.probe.injected.parameter.ThisValue;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
@interface ThisValue implements Annotation

Assigns the instance that the instrumented method was invoked on to a parameter of a probe method. The probe method can be annotated with Interception, PayloadInterception, SplitInterception or AdditionalInterception. The type of the annotated parameter must be Object or the type given in MethodSpec.className. The declared type can only be used if it can be resolved by the system class loader.

If the instrumented method is a static method, the argument will be null. If the instrumented method is a constructor, the value will be null for InvocationType.ENTER because the super constructor has not been invoked yet.

Package com.jprofiler.api.probe.injected.telemetry

Contains the classes for adding custom telemetries to an injected probe.

The Telemetry annotation contains further information.

Telemetry

Import: import com.jprofiler.api.probe.injected.telemetry.Telemetry;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@interface Telemetry implements Annotation

Create a custom telemetry from the numeric return value of the annotated static method in a probe class.

Only public static parameterless methods can be used for creating custom telemetries, annotating instance methods or non-public static methods will cause an error when the probe is registered. The method must return a numeric value, either a primitive value like int or double, a java.math.BigDecimal or a primitive wrapper instance like java.lang.Integer or java.lang.Double.

The method is called periodically on a dedicated thread. This may have implications for the requirements of thread safety in your code. If the numeric value is calculated on the fly, access to the data structures must be made thread-safe by making access to those data structures synchronized. Alternatively, you could calculate a cached value when convenient and save it to a volatile atomic value, like an int or a class from the java.util.concurrent.atomic package.

For example, the following code snippet defines a custom telemetry with the name "Connection count":

&#064;Telemetry("Connection count")
    public static int getConnectionCount() {
        return connectionCount;
    }

Multiple lines in a single custom telemetry

If you want to compare several measurements in the same telemetry, you can annotate multiple methods with the same Telemetry.value for the telemetry name, but with a different Telemetry.line parameter.

For example:

&#064;Telemetry(value = "Queries", line = "Successful queries")
    public static int getSuccessCount() {
        return successCount;
    }
    &#064;Telemetry(value = "Queries", line = "Failed queries")
    public static int getErrorCount() {
        return errorCount;
    }

This will create a single custom telemetry with the name "Queries" and two data lines named "Successful queries" and "Failed queries".

Elements

ElementTypeDefaultDescription
valueString—The name of the telemetry.
lineString""The optional line name of the telemetry.
formatTelemetryFormat@com.jprofiler.api.probe.injected.telemetry.TelemetryFormatOptional display options for the telemetry.

##### value

The name of the telemetry. Give different names to different telemetries. Reuse the same name when annotating different methods if you are creating a custom telemetry with multiple lines. If only a single line is used, you can omit the "value" parameter name, as in

&#064;Telemetry("Connection count")

##### line

The optional line name of the telemetry. Only specify this parameter if you're creating a telemetry with multiple lines. See Telemetry for an example.

##### format

Optional display options for the telemetry.

TelemetryFormat

Import: import com.jprofiler.api.probe.injected.telemetry.TelemetryFormat;

@interface TelemetryFormat implements Annotation

Display options for a Telemetry annotation. This annotation is used by the Telemetry.format parameter.

Elements

ElementTypeDefaultDescription
valueTelemetryUnitPLAINThe unit of the recorded values.
scaleint0A scaling factor for the telemetry.
stackedbooleanfalseDetermines whether multiple lines in a telemetry should be stacked into an area graph.

##### value

The unit of the recorded values. By default, telemetries are unitless.

##### scale

A scaling factor for the telemetry. In the UI, recorded values will be multiplied with 10^-scale.

In JProfiler, probe telemetry data is stored in 32-bit ints. So this is especially useful for telemetries that will show higher values than 2^31. For example, if you use the TelemetryUnit.BYTES you can return kB instead and set the scale to -3.

This is also useful to show fractional values. For example, if you want to show a percentage with two decimal digits, the returned value should be the percentage times 100 and the scale parameter should be set to 2.

##### stacked

Determines whether multiple lines in a telemetry should be stacked into an area graph. By default, multiple telemetry lines are not stacked. An example of a stacked graph is the "Heap usage" telemetry.

TelemetryUnit

Import: import com.jprofiler.api.probe.injected.telemetry.TelemetryUnit;

public final enum TelemetryUnit

Telemetry unit used in the TelemetryFormat annotation.

Constants

##### PLAIN

The telemetry value is a unitless number.

##### PER_SECOND

The telemetry value has the unit "per second".

##### PERCENT

The telemetry value has the unit "percent".

##### MILLISECONDS

The telemetry value has the unit "milliseconds". Conversion into higher unit prefixes such as seconds is done automatically as required.

##### MICROSECONDS

The telemetry value has the unit "microseconds". Conversion into higher unit prefixes such as seconds is done automatically as required.

##### BYTES

The telemetry value has the unit "bytes". Conversion into higher unit prefixes such as kB, MB or GB is done automatically as required.

In JProfiler, probe telemetry data is stored in 32-bit ints. If you expect higher values than 2^31 bytes, you can for example return kB instead and set TelemetryFormat.scale to -3.

Methods

SignatureReturnsDescription
values()TelemetryUnit[]
valueOf(String)TelemetryUnit

##### values()

public static TelemetryUnit[] values()

##### valueOf(String)

public static TelemetryUnit valueOf(String name)