Search code examples
jfr

How to configure the interval of a custom JFR event


I am implementing a custom JFR event that samples a counter at a certain interval. It would be awesome if this event and interval could be configured in a .jfc configuration file like the built-in events. For that to work I need programmatic access to the configured value. Through EventFactory if have access to the SettingDescriptor but this gives me only the default value, not the current value.

I had a look at jdk.jfr.internal.settings.PeriodSetting but this is an internal class.


Solution

  • Custom events can be configured in a .jfc file.

    <event name="Foo">
      <setting name="enabled">true</setting>
      <setting name="period">5 s</setting>
    </event>
    

    or programmatically with a Map:

     Recording r = new Recording();
     Map<String, String> settings = new HashMap<>();
     settings.put("Foo#enabled", "true");
     settings.put("Foo#period", "5 s");
     r.setSettings(settings);
     r.start();
    

    or using fluent API:

     r.enable("Foo").withPeriod(Duration.ofSeconds(5));
    

    The time when events are emitted is determined by the framework:

    FlightRecorder.addPeriodicEvent(Foo.class, ()-> {
      Foo foo = new Foo();
      foo.bar = Sampler.sample();
      foo.commit();
    });
    

    If the field layout of the event is unknown at compile time, so you have to use the EventFactory, you can do:

      final EventFactory factory = ...
      Event event = factory.newEvent();
      Class<Event> eventClass = event.getClass();
      FlightRecorder.addPeriodicEvent(eventClass, ()-> {
        Event foo = factory.newEvent();
        foo.set(0, Sampler.sample());
        foo.commit();
      });