7 動的イベント

動的イベントを使用すると、注釈やフィールドも含め、ランタイムのイベントを定義できます。

ノート:

動的イベントは、アプリケーションを実行するまで、イベントのレイアウトがわからない場合にのみ使用します。

DynamicSample.javaの例では、名前がランダム文字列であるフィールドを含むcom.oracle.RandomStringという動的イベントが作成されます:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import jdk.jfr.AnnotationElement;
import jdk.jfr.Category;
import jdk.jfr.Description;
import jdk.jfr.Event;
import jdk.jfr.EventFactory;
import jdk.jfr.Label;
import jdk.jfr.Name;
import jdk.jfr.ValueDescriptor;

public class DynamicSample {

    private static String randomString(int n) {

        var ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var builder = new StringBuilder();
        while (n-- != 0) {
            int character = (int) (Math.random()
                * ALPHA_NUMERIC_STRING.length());
            builder.append(ALPHA_NUMERIC_STRING.charAt(character));
        }
        return builder.toString();
    }

    public static void main(String[] args) {

        String[] category = { "Demonstration", "Tutorial" };
        var eventAnnotations = new ArrayList<AnnotationElement>();
        eventAnnotations
            .add(new AnnotationElement(
                Name.class, "com.oracle.RandomString"));
        eventAnnotations.add(new AnnotationElement(Label.class,
            "Field Named with Random String"));
        eventAnnotations.add(new AnnotationElement(Description.class,
            "Demonstrates how to create a dynamic event"));
        eventAnnotations.add(new AnnotationElement(
            Category.class, category));

        var fields = new ArrayList<ValueDescriptor>();
        var messageAnnotations = Collections
            .singletonList(new AnnotationElement(Label.class, "Message"));
        var randomFieldName = DynamicSample.randomString(8);
        fields.add(new ValueDescriptor(String.class, randomFieldName,
            messageAnnotations));
        var numberAnnotations = Collections
            .singletonList(new AnnotationElement(Label.class, "Number"));
        fields.add(new ValueDescriptor(
            int.class, "number", numberAnnotations));

        var f = EventFactory.create(eventAnnotations, fields);

        Event event = f.newEvent();
        event.set(0, "hello, world!");
        event.set(1, 100);
        event.commit();
    }
}

次のコマンドを使用して、DynamicSampleを実行します:

java -XX:StartFlightRecording:filename=d.jfr DynamicSample.java
jfr print --events RandomString d.jfr

最後のコマンドでは、次のような出力が表示されます:

com.oracle.RandomString {
  startTime = 12:56:32.782
  ZZEIUMTG = "hello, world!"
  number = 100
  ...
}

動的イベントを作成するには、静的メソッドEventFactory.create<List<AnnotationElement>, List<ValueDescriptor>)を呼び出します:

var f = EventFactory.create(eventAnnotations, fields);

1つ目の引数はイベントの注釈のリストで、@Name@Descriptionなど、組込みの注釈が含まれます。

2つ目の引数は、イベントのフィールドのリストです。これらは、ValueDescriptorクラスを使用して定義します。