Micrometer注册表开发:如何显式设置JFR事件时长?
Great question! Let's break down your options for setting JFR event durations without relying on the standard start()/end() pattern, especially since Micrometer requires explicit duration values.
Option 1: Use JFR's Built-in setStartTime() and setEndTime() Methods
JFR events have a native duration field that’s automatically calculated from the event’s start and end timestamps. Instead of calling start() and end() to let the JVM capture these timestamps, you can manually set them using the Event class’s public methods:
void setStartTime(long startTimeNanos): Sets the event’s start time (in nanoseconds, matching the output ofSystem.nanoTime())void setEndTime(long endTimeNanos): Sets the event’s end time (same nanosecond format)
Here’s how you’d apply this to your Micrometer Timer scenario:
// Convert Micrometer's recorded duration to nanoseconds long durationNanos = TimeUnit.NANOSECONDS.convert(recordedDuration, recordedUnit); long currentTimeNanos = System.nanoTime(); // Calculate start time by subtracting duration from current time long startTimeNanos = currentTimeNanos - durationNanos; // Apply timestamps to your JFR event yourJfrEvent.setStartTime(startTimeNanos); yourJfrEvent.setEndTime(currentTimeNanos);
Pros of This Approach
- Uses JFR’s native
durationfield, so tools like JDK Mission Control (JMC) will automatically recognize and visualize it as a duration (no extra configuration needed) - Aligns with JFR’s event model, avoiding custom fields that might confuse users of your registry
- No need to define extra event schema elements
Cons
- Requires converting Micrometer’s duration value into start/end timestamps (though this is a trivial calculation)
Option 2: Add a Custom Duration Field to Your JFR Event
If you want full control over how the duration is stored (e.g., keeping it in the original TimeUnit from Micrometer, or adding extra context), you can define a custom field in your JFR event schema.
For a pre-defined event class, this would look like:
@Category("Micrometer") @Label("Timer Event") public class MicrometerTimerEvent extends Event { @Label("Recorded Duration") @Setting(description = "Duration recorded by Micrometer, in nanoseconds") private long durationNanos; // Getters/setters or use EventFactory indexes if using dynamic events }
Then, in your registry, use Event#set(int, Object) to populate this field directly with the Micrometer-provided duration (converted to your desired unit):
// Get the index of your custom duration field (from EventFactory) int durationFieldIndex = eventFactory.getFieldIndex("durationNanos"); yourJfrEvent.set(durationFieldIndex, TimeUnit.NANOSECONDS.convert(recordedDuration, recordedUnit));
Pros of This Approach
- Full flexibility to store durations in any unit or add additional metadata tied to the duration
- No need to calculate timestamps — just pass the raw duration value from Micrometer
Cons
- JMC won’t automatically treat this field as a "duration" by default; users will need to manually configure display formats in JMC
- Adds extra complexity to your event schema
Which Should You Choose?
If you want seamless integration with JFR’s native tooling and don’t need custom duration handling, Option 1 is the way to go — it lets you leverage JFR’s built-in duration field without calling start()/end(). Only opt for Option 2 if you need to deviate from JFR’s standard duration model for specific use cases.
内容的提问来源于stack exchange,提问作者Philippe Marschall

