JDK Flight Recorderのイベントを作る

JDK Flight Recorder (JFR) のイベントを作ったときのメモ。

準備

JDK Misson Control (JMC)

ここからダウンロードしてインストールする。

ソースコード

import java.util.concurrent.TimeUnit;

import jdk.jfr.Category;
import jdk.jfr.Description;
import jdk.jfr.Event;
import jdk.jfr.Label;
import jdk.jfr.Name;

public class HelloMain {

    @Name("hirakida.Hello")
    @Label("Hello")
    @Category("JFR Demo")
    @Description("Hello Event")
    static class HelloEvent extends Event {
        @Label("Message")
        String message;
    }

    public static void main(String[] args) throws Exception {
        while (true) {
            HelloEvent event = new HelloEvent();
            event.message = "Hello!";
            event.begin();

            // eventのduration確認用
            TimeUnit.SECONDS.sleep(1);

            event.commit();
        }
    }
}

Demo

JFRを有効にしてデモアプリを実行する。

% sdk use java 15.0.2.hs-adpt  

% java -XX:StartFlightRecording:filename=hello.jfr HelloMain.java 

JMC

JMCでhello.jfrを開くと、追加したHelloイベントが確認できる。

jfrコマンド

JDK 12から追加されたjfrコマンドでも確認できる。

% jfr print --events Hello hello.jfr
hirakida.Hello {
  startTime = 01:13:44.276
  duration = 1.00 s
  message = "Hello!"
  eventThread = "main" (javaThreadId = 1)
  stackTrace = [
    com.example.HelloMain.main(String[]) line: 28
    jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
    jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Object, Object[]) line: 64
    jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
    java.lang.reflect.Method.invoke(Object, Object[]) line: 564
    ...
  ]
}

...

jsonで表示する場合

% jfr print --json --events Hello hello.jfr
{
  "recording": {
    "events": [{
      "type": "hirakida.Hello", 
      "values": {
        "startTime": "2021-01-26T01:13:44.276284035+09:00", 
        "duration": "PT1.000242742S", 
        "eventThread": {
          "osName": "main", 
          "osThreadId": 9475, 
          "javaName": "main", 
          "javaThreadId": 1, 
          "group": {
            "parent": {
              "parent": null, 
              "name": "system"
            }, 
            "name": "main"
          }
        }, 
...

参考