JFR Events and Wildfly

Monitoring:
After implementing jaeger tracing and the export for prometheus, Dynatrace became the new king in town. But to have a fast local monitor solution, Java Flight Recorder is the way to go(IMHO).
Here we go: I used Azul JDKs, so their “mission control” was a natural fit.

jboss-deployment-structure.xml

...
 <ear-subdeployments-isolated>true</ear-subdeployments-isolated>
  <sub-deployment name="duckhawkwebservice.war">
    <dependencies>
      <module name="deployment.ServiceAgentConnector.rar" export="true"/>
      <module name="org.apache.cxf" export="true"/>
      <module name="org.apache.cxf.impl" export="true"/>
      <module name="org.apache.httpcomponents" export="true"/>
      <module name="org.bouncycastle.bcprov" export="true"/>
      <module name="io.opentracing.opentracing-noop" export="true"/>      
      <module name="net.bytebuddy" export="true"/>
      <module name="jdk.jfr" export="true"/>
    </dependencies>
  </sub-deployment>
...
package de.codecoverage.tools.jfr;

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

public interface CCEvents 
{
	public static CCEvent createGenricEvent() {
		CCEvent event = new CCEvent();
		event.begin();
		return event;
	}
	
	public static CCEventSpecific createSpecificEvent() {
		CCEventSpecific event = new CCEventSpecific();
		event.begin();
		return event;
	}
	
	
	@Description("Simple event with a message")
	@Category({ "CC", "Events", "General" })
	@Name("CCEvent")
	public class CCEvent extends Event implements AutoCloseable
	{
		@Label("Message")
		@Description("A simple string message")
		protected /*protected: to be used in derived class*/ String message;

		public void setMessage(String message) {
			this.message = message;
		}
		
		@Override
		public void close() {
			this.commit();
		}

		protected CCEvent() {
		}

	}
	
	@Description("Simple event wich can hold a message and a value")
	@Category({ "CC", "Events", "Specific" })
	@Name("CCEventSpecific")
	@StackTrace(false)
	public class CCEventSpecific extends CCEvent
	{
		@Label("Value")
		@Description("A value")
		protected /*protected: to be used in derived class*/ long value;

		public void setValue(long value) {
			this.value = value;
		}

		protected CCEventSpecific() {
		}
	}
 
	public final class TestDriver {
		// Main class: de.codecoverage.tools.jfr.CCEvents$TestDriver		
		public static void main(String[] args) throws InterruptedException {
			stackDepth2(); // to give a stack depth
		}

		private static void stackDepth2() throws InterruptedException {
			stackDepth1();
		}

		private static void stackDepth1() throws InterruptedException {
			for (int i = 0; i < 1000; i++) {
				try (var event = CCEvents.createSpecificEvent()) {
					event.setMessage(String.valueOf(i));
					event.setValue(i);
					try (var cc = CCEvents.createGenricEvent()) {
						var str = String.valueOf(i);
						cc.setMessage(str + " - " + str);
						Thread.sleep(100);
						System.out.printf("CCEvent enabled              = %B%n", event.isEnabled());
						System.out.printf("CCEvent shouldCommit         = %B%n", event.shouldCommit());
					}
					Thread.sleep(400);
					System.out.printf("CCEventSpecific enabled      = %B%n", event.isEnabled());
					System.out.printf("CCEventSpecific shouldCommit = %B%n", event.shouldCommit());
				}
			}
		}
	}
}

isEnabled() and shouldCommit() are intentionally ignored because then the work done is roughly the same(JFR enabled).

FLR-Events

Copilot explanation:
This Java code is part of a package de.codecoverage.tools.jfr and it defines an interface CCEvents which contains two classes CCEvent and CCEventSpecific, and a TestDriver class.

The CCEvent class is a simple event with a message. It extends the Event class and implements the AutoCloseable interface. The AutoCloseable interface is used to allow the CCEvent object to be used in a try-with-resources statement, which automatically calls the close method when the try block exits. The close method in turn calls the commit method. The CCEvent class has a protected message field, which can be set using the setMessage method. The message field is annotated with @Label and @Description, which are used to provide metadata about the field for the Java Flight Recorder (JFR) framework.

The CCEventSpecific class extends CCEvent and adds an additional value field, which can be set using the setValue method. This class represents a more specific event that can hold both a message and a value. The value field is also annotated with @Label and @Description.

The CCEvents interface also provides two static methods createGenricEvent and createSpecificEvent for creating instances of CCEvent and CCEventSpecific respectively. These methods call the begin method on the newly created event before returning it.

The TestDriver class contains a main method which is the entry point of the program. The main method calls the stackDepth2 method, which in turn calls the stackDepth1 method. The stackDepth1 method creates a number of CCEventSpecific and CCEvent objects in a loop, sets their message and value fields, and checks whether they are enabled and should be committed. The Thread.sleep method is used to introduce a delay between the creation of each event. The printf method is used to print the status of the events to the console.