Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTrace support for custom JFR events #429

Merged
merged 20 commits into from
Nov 28, 2020
Merged

BTrace support for custom JFR events #429

merged 20 commits into from
Nov 28, 2020

Conversation

jbachorik
Copy link
Collaborator

Summary

With the (almost) ubiquitous availability of JFR APIs in the current JDKs it makes sense to have the means to produce JFR events directly from BTrace probes.

The JFR API provides a convenient way to create and register custom event types via its EventFactory and BTrace will utilise this. Both requestable and periodical event types are supported.

Usage

Requestable events

Working with requestable events is mimicking the workflow typical for the JFR API.

1. Register custom event factory by annotating a filed of type JfrEvent.Factory

@Event(
        name = "CustomReuestableEvent",
        label = "Custom Requestable Event",
        description = "Demo Requestable Event",
        fields = {
            @Event.Field(type = Event.FieldType.INT, name = "a", kind = @Event.Field.Kind(name = Event.FieldKind.TIMESTAMP))),
            @Event.Field(type = Event.FieldType.STRING, name = "b")
        },
       stacktrace = true
    )
    private static JfrEvent.Factory customEventFactory;

name, label, description and stacktrace attributes are self descriptive and of them only name is required, the rest is optional.
The fields attribute is an array of event field definitions - each field must have its name and type defined (where the type is restricted to the subset of primitive, class, thread and string). A field can have an optional kind associated with it with the supported kinds being enumerated in FieldKind enumeration.

2. Create a new event instance

JfrEvent event = BTraceUtils.Jfr.prepareEvent(customEventFactory);

3. Check whether the event instance is committable

if (BTraceUtils.Jfr.shouldCommit(event)) {
...
}

4. Set event fields

BTraceUtils.Jfr.setEventField(event, "b", "Hello World!);
BTraceUtils.Jfr.setEventField(event, "a", 1234567);

5. Commit event

BTraceUtils.Jfr.commit(event);

Periodical events

1. Register periodical event handler by annotating a method taking exactly one argument of type JfrEvent. The event argument will get automatically injected by BTrace to contain a valid instance of the defined event type.

@PeriodicEvent(name = "PeriodicEvent", fields = @Event.Field(type = Event.FieldType.INT, name = "ts", kind = @Event.Field.Kind(name = Event.FieldKind.TIMESTAMP)), period = "1 s")
public static void onPeriod(JfrEvent event) {
...
}

The attributes of @PeriodicEvent annotation are the same as for @Event annotation with the additional attribute of period which defines the periodicity of the event. Allowed values are beforeChunk, afterChunk, eachChunk and time period specification in form number unit (eg. 10 s or 150 ms etc.). The meaning of those values as well as the allowed time units are taken directly from the JFR API so they are not going to be explained here.
Also, it is not possible to request stacktrace for periodical events since it would make not much sense, all the periodical events being emitted by internal JFR threads.

2. Write the event handling code

The periodic event handling is 100% equivalent to emitting a requestable event.

if (BTraceUtils.Jfr.shouldCommit(event)) {
    BTraceUtils.Jfr.setEventField(event, "ts", 1);
    BTraceUtils.Jfr.commit(event);
}

Compatibility

JFR support requires (of course) the JFR APIs being available in JDK. Currently this means JDK 11 and newer (although JFR support is already in JDK 8u272 this implementation is not supporting that yet) and all the JFR related BTrace code will be silently ignored for non-compatible Java versions.

jbachorik and others added 19 commits October 17, 2020 22:54
Added @JfrPeriodicEventHandler and @JfrBlock annotations to allow emitting JFR events in safe mode (eg. passing both compilation and runtime verifier).
# Conflicts:
#	btrace-compiler/src/test/resources/JfrEventsProbe.java
#	btrace-core/src/main/java/org/openjdk/btrace/core/BTraceUtils.java
#	btrace-core/src/main/java/org/openjdk/btrace/core/jfr/JfrEvent.java
#	btrace-instr/src/main/java/org/openjdk/btrace/instr/Preprocessor.java
#	btrace-instr/src/test/btrace/JfrTest.java
#	btrace-instr/src/test/java/org/openjdk/btrace/BTraceFunctionalTests.java
#	btrace-runtime/src/main/java/org/openjdk/btrace/runtime/BTraceRuntimeImpl_7.java
#	btrace-runtime/src/main/java11/org/openjdk/btrace/runtime/BTraceRuntimeImpl_11.java
#	btrace-runtime/src/main/java11/org/openjdk/btrace/runtime/JfrEventFactoryImpl.java
#	btrace-runtime/src/main/java9/org/openjdk/btrace/runtime/BTraceRuntimeImpl_9.java
@jbachorik jbachorik added this to the 2.1.0 milestone Nov 22, 2020
@jbachorik jbachorik merged commit 903c2d2 into develop Nov 28, 2020
@jbachorik jbachorik deleted the jfr_events branch November 28, 2020 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant