Event Tracing

Description

Event Tracing allows to record integer based events for debugging and monitoring purposes without affecting execution performance too heavily. Basically, it gives access to Tracer objects that are named and can produce a limited number of different event types.

A record is an event type identified by an eventID and can have a list of values. It can be a single event or a period of time with a start and an end.

Event Tracing can be accessed from two APIs:

  • A Java API, provided by the Trace API module. The following dependency must be added to the build file of the MicroEJ Application project:

implementation("ej.api:trace:1.1.0")
  • A C API, provided by the Foundation Library header file named LLTRACE.h.

Event Recording

Events are recorded if and only if:

  • the Core Engine trace system is enabled,

  • and trace recording is started.

To enable the Core Engine trace system, set the Application Option named core.trace.enabled to true (see also launch configuration). The Trace system requires at last 16 bytes of Immortal heap (see Immortals Heap size).

Then, multiple ways are available to start and stop the trace recording:

Java API Usage

The detailed Trace API documentation is available here.

First, you need to instantiate a Tracer object by calling its constructor with two parameters. The first parameter, name, is a String that will represent the Tracer object group’s name. The second parameter, nbEventTypes, is an integer representing the maximum number of event types available for the group.

Tracer tracer = new Tracer("MyGroup", 10);

Then, you can record an event by calling the recordEvent(int eventId) method. The event ID needs to be in the range 0 to nbEventTypes-1 with nbEventTypes the maximum number of event types set when initializing the Tracer object. Methods named recordEvent(...) always needs the event ID as the first parameter and can have up to ten integer parameters as custom values for the event.

To record the end of an event, call the method recordEventEnd(int eventID). It will trace the duration of an event previously recorded with one of the recordEvent(int eventID) methods. The recordEventEnd(...) method can also have another integer parameter for a custom value for the event end. One can use it to trace the returned value of a method.

The Trace API also provides a String constant Tracer.TRACE_ENABLED_CONSTANT_PROPERTY representing the Constant value of core.trace.enabled option. This constant can be used to remove at build time portions of code when the trace system is disabled. To do that, just surround tracer record calls with a if statement that checks the constant’s state. When the constant is set to false, the code inside the if statement will not be embedded with the application and thus will not impact the performances.

if(Constants.getBoolean(Tracer.TRACE_ENABLED_CONSTANT_PROPERTY)) {
  // This code is not embedded if TRACE_ENABLED_CONSTANT_PROPERTY is set to false.
  tracer.recordEventEnd(0);
}

Examples:

  • Trace a single event:

    private static final Tracer tracer = new Tracer("Application", 100);
    
    public static void main(String[] args) {
      Tracer.startTrace();
      tracer.recordEvent(0);
    }
    

    Standard Output:

    MicroEJ START
    [TRACE] [1] Declare group "Application"
    [TRACE] [1] Event 0x0
    
  • Trace a method with a start event showing the parameters of the method and an end event showing the result:

    private static final Tracer tracer = new Tracer("Application", 100);
    
    public static void main(String[] args) {
      Tracer.startTrace();
      int a = 14;
      int b = 54;
      add(a, b);
    }
    
    public static int add(int a, int b) {
      tracer.recordEvent(1, a, b);
      int result = a + b;
      tracer.recordEventEnd(1, result);
      return result;
    }
    

    Standard Output:

    MicroEJ START
    [TRACE] [1] Declare group "Application"
    [TRACE] [1] Event 0x1 (14 [0xE],54 [0x36])
    [TRACE] [1] Event End 0x1 (68 [0x44])
    

VEE Port Implementation

More information about the existing implementations and how to implement the required natives are available in the section Event Tracing of the VEEPorting Guide chapter.

Advanced Event Tracing

Method invocation can be profiled.

Note

This feature requires Architecture version 7.17.0 or higher and is only available on the Core Engine, not on Simulator.

MicroEJ Corp. provides an implementation on Linux targets to profile an Application and generate a flamegraph for the Trace Compass tool.

Please contact our support team for more information about how to generate flamegraph.