Package org.openjdk.jmc.flightrecorder.parser
To create a new parser extension you start by implementing the
IParserExtension
interface. This
is a (normally stateless) factory class that can create implementations of
IEventSinkFactory
. For each
loading of a Flight Recording exactly one instance of IEventSinkFactory will be created for each
implementation of IParserExtension that is passed to the loader.
Parser extensions are loaded using the Java ServiceLoader framework. To register an
implementation, add its fully qualified class name to a resource file named
org/openjdk/jmc/flightrecorder/parser/IParserExtension
that should be included in the
same jar file as the implementation.
The actual reading of the Flight Recording is then split into multiple threads that read
different parts of the recording. For every event type that is encountered a call to
IEventSinkFactory.create
is made to get an
IEventSink
instance. For every event of
that type IEventSink.addEvent
is called with the actual event values. Note that the IEventSinkFactory
instance will be shared by all read threads so the create method must be thread safe. However,
each thread will have its own IEventSink instance for every event that it has found. This means
that there will most probably be multiple instances of IEventSink for the same event type, each
one owned by a separate read thread.
When all events have been read and passed through the sinks (all read threads are finished), a
call to IEventSinkFactory.flush
will be made. This allows the factory to create any additional events
that it may need to create.
The
IParserExtension.getEventSinkFactory
method takes another IEventSinkFactory instance as an
argument. This subfactory is the next factory to pass event types and events to. This allows for
creating a chain of extensions that modify the events in different ways. The last factory in this
chain is an internal implementation that takes care of the events for use in the Mission Control.
Basically, for every call to IEventSinkfactory.create
you will get the metadata for an
event type. Inspect this metadata and call the create
method of the subfactory with the
metadata, either modified or unmodified. This will give you an IEventSink instance that you can
return immediately if you don't want to do anything with this event, or use in your own
IEventSink implementation. If you want to create additional "synthetic" event types based on this
type, then you can call create
on the subfactory multiple times.
For every call to IEventSink.addEvent
you will get the event values. You can look at
these values and do whatever you want with them. Examples are generating additional attributes
and calculating statistics. Once you have your new values you call addEvent
on the
correct sink from the subfactory. Note that the arguments to the addEvent
call (the event
values) must match the attributes specified when the IEventSink was created with the
create
call.
If you want to create events like statistics that should be created after all other events have
been read, then you can use the
IEventSinkFactory.flush
method. Create a sink for your new event type when you get the create
call for the type
that you want to calculate statistics for. Collect data during addEvent
calls and when
you get the flush
call, add the statistics events by calling addEvent
on the
statistics event sink.
-
Interface Summary Interface Description IConstantPoolExtension Interface for Flight Recorder constant pool extensions.IEventSink Event sinks are responsible for receiving and optionally modifying event data.IEventSinkFactory Event sink factories are responsible for handling event types during parsing.IParserExtension Interface for Flight Recorder parser extensions. -
Class Summary Class Description ParserExtensionRegistry Handles loading of parser extension factories using Java Service Loader.ValueField A descriptor of a value field for use inIEventSinkFactory.create
.