Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quarkus-jfr can cause a NullPointerException #44976

Closed
andrewazores opened this issue Dec 6, 2024 · 17 comments · Fixed by #45059
Closed

quarkus-jfr can cause a NullPointerException #44976

andrewazores opened this issue Dec 6, 2024 · 17 comments · Fixed by #45059
Labels
area/metrics kind/bug Something isn't working
Milestone

Comments

@andrewazores
Copy link

andrewazores commented Dec 6, 2024

2024-12-06 21:58:32,293 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (vert.x-eventloop-thread-16) HTTP Request to /api/v4/rules failed, error id: c731be49-d8e0-4302-b088-dff3270a1194-2: java.lang.NullPointerException: Cannot invoke "io.quarkus.jfr.runtime.http.rest.RestPeriodEvent.end()" because "this.durationEvent" is null
	at io.quarkus.jfr.runtime.http.rest.ServerRecorder.endPeriodEvent(ServerRecorder.java:57)
	at io.quarkus.jfr.runtime.http.rest.ReactiveServerRecorderProducer_ProducerMethod_create_vtLSqoQNMKpnFmkr1mT_AIw4_cQ_ClientProxy.endPeriodEvent(Unknown Source)
	at io.quarkus.jfr.runtime.http.rest.JfrReactiveServerFilter.responseFilter(JfrReactiveServerFilter.java:33)
	at io.quarkus.jfr.runtime.http.rest.JfrReactiveServerFilter$GeneratedServerResponseFilter$responseFilter.filter(Unknown Source)
	at io.quarkus.jfr.runtime.http.rest.JfrReactiveServerFilter$GeneratedServerResponseFilter$responseFilter_ClientProxy.filter(Unknown Source)
	at org.jboss.resteasy.reactive.server.handlers.ResourceResponseFilterHandler.handle(ResourceResponseFilterHandler.java:25)
	at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:150)
	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
	at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:48)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:23)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:10)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$8.handle(VertxHttpRecorder.java:610)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$8.handle(VertxHttpRecorder.java:604)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:62)
	at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:40)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.undertow.websockets.vertx.VertxWebSocketHandler.handle(VertxWebSocketHandler.java:128)
	at io.undertow.websockets.vertx.VertxWebSocketHandler.handle(VertxWebSocketHandler.java:54)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveRecorder$13.handle(ResteasyReactiveRecorder.java:358)
	at io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveRecorder$13.handle(ResteasyReactiveRecorder.java:347)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.quarkus.vertx.http.runtime.filters.accesslog.AccessLogHandler.handle(AccessLogHandler.java:164)
	at io.quarkus.vertx.http.runtime.filters.accesslog.AccessLogHandler.handle(AccessLogHandler.java:94)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1285)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:68)
	at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:37)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:517)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:514)
	at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$2.handle(HttpServerCommonHandlers.java:86)
	at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$2.handle(HttpServerCommonHandlers.java:69)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$1.handle(VertxHttpRecorder.java:182)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$1.handle(VertxHttpRecorder.java:158)
	at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:67)
	at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:30)
	at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:328)
	at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:164)
	at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:174)
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:159)
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
	at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.onHttpRequestChannelRead(WebSocketServerExtensionHandler.java:158)
	at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:82)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
	at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:333)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:455)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
	at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:799)
	at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:501)
	at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:399)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:1583)

2024-12-06 21:58:32,293 INFO  [io.qua.htt.access-log] (vert.x-eventloop-thread-16) 10.89.73.7 - - [06/Dec/2024:21:58:32 +0000] "POST /api/v4/rules HTTP/1.1" 500 72

This is happening during an integration test run, which looks like this:

@QuarkusIntegrationTest
@TestMethodOrder(OrderAnnotation.class)
class RulesPostJsonIT extends StandardSelfTest {

    // trimmed

    @Test
    @Order(2)
    void testAddRuleThrowsWhenMimeUnsupported() throws Exception {
        CompletableFuture<JsonObject> response = new CompletableFuture<>();

        webClient
                .post("/api/v4/rules")
                .putHeader(HttpHeaders.CONTENT_TYPE.toString(), "text/plain")
                .sendJsonObject(
                        testRule,
                        ar -> {
                            assertRequestStatus(ar, response);
                        });
        ExecutionException ex =
                Assertions.assertThrows(
                        ExecutionException.class, () -> response.get(10, TimeUnit.SECONDS));
        MatcherAssert.assertThat(
                ((HttpException) ex.getCause()).getStatusCode(), Matchers.equalTo(415));
        MatcherAssert.assertThat(
                ex.getCause().getMessage(), Matchers.equalTo("Unsupported Media Type"));
    }

    // trimmed
}

The REST endpoint class is like this:

@Path("/api/v4/rules")
public class Rules {

    @Inject EventBus bus;

    @Transactional
    @POST
    @RolesAllowed("write")
    @Consumes(MediaType.APPLICATION_JSON)
    public RestResponse<Rule> create(@Context UriInfo uriInfo, Rule rule) {
        // TODO validate the incoming rule
        if (rule == null) {
            throw new BadRequestException("POST body was null");
        }
        boolean ruleExists = Rule.getByName(rule.name) != null;
        if (ruleExists) {
            throw new EntityExistsException("Rule", rule.name);
        }
        if (rule.description == null) {
            rule.description = "";
        }
        rule.persist();

        return ResponseBuilder.<Rule>created(
                        uriInfo.getAbsolutePathBuilder().path(Long.toString(rule.id)).build())
                .entity(rule)
                .build();
    }

    @Transactional
    @POST
    @RolesAllowed("write")
    @Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED})
    public RestResponse<Rule> create(
            @Context UriInfo uriInfo,
            @RestForm String name,
            @RestForm String description,
            @RestForm String matchExpression,
            @RestForm String eventSpecifier,
            @RestForm int archivalPeriodSeconds,
            @RestForm int initialDelaySeconds,
            @RestForm int preservedArchives,
            @RestForm int maxAgeSeconds,
            @RestForm int maxSizeBytes,
            @RestForm boolean enabled) {
        MatchExpression expr = new MatchExpression(matchExpression);
        expr.persist();
        Rule rule = new Rule();
        rule.name = name;
        rule.description = description;
        rule.matchExpression = expr;
        rule.eventSpecifier = eventSpecifier;
        rule.archivalPeriodSeconds = archivalPeriodSeconds;
        rule.initialDelaySeconds = initialDelaySeconds;
        rule.preservedArchives = preservedArchives;
        rule.maxAgeSeconds = maxAgeSeconds;
        rule.maxSizeBytes = maxSizeBytes;
        rule.enabled = enabled;

        if (Rule.getByName(rule.name) != null) {
            return ResponseBuilder.<Rule>create(RestResponse.Status.CONFLICT).entity(rule).build();
        }

        rule.persist();

        return ResponseBuilder.<Rule>created(
                        uriInfo.getAbsolutePathBuilder().path(Long.toString(rule.id)).build())
                .entity(rule)
                .build();
    }

If I simply remove the quarkus-jfr dependency from the project's pom.xml, then this test goes back to passing as normal (as in, the application responds with 415 rather than 500).

Quarkus version: 3.15.2

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-vertx</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-netty</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-openapi</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-graphql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.smallrye.reactive</groupId>
      <artifactId>smallrye-mutiny-vertx-web-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkiverse.quinoa</groupId>
      <artifactId>quarkus-quinoa</artifactId>
      <version>${quarkus-quinoa.version}</version>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-container-image-docker</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-websockets</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-cache</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-quartz</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm-panache</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-validator</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jdbc-postgresql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkiverse.amazonservices</groupId>
      <artifactId>quarkus-amazon-s3</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-kubernetes-client</artifactId>
    </dependency>


    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-flyway</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jfr</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5-mockito</artifactId>
      <scope>test</scope>
    </dependency>
@andrewazores
Copy link
Author

andrewazores commented Dec 6, 2024

#37900

@brunobat @chiroito ^

@gsmet
Copy link
Member

gsmet commented Dec 7, 2024

I think the problem is here:

private boolean isRecordable(ContainerResponseContext responseContext) {
return responseContext.getStatus() != Response.Status.NOT_FOUND.getStatusCode();
}

There are probably a lot more cases than just the 404 for which we don't start the event. My preference would be to not try to mimic Quarkus REST behavior but just test if the durationEvent has been set.

@chiroito can you check the above make sense and implement a fix ^

@gsmet gsmet added the kind/bug Something isn't working label Dec 7, 2024
@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

@andrewazores do you have the sample project you used to surface this problem?

I would very much like to run it and see the issue in action because as @gsmet says, this issue is likely more general than just 404 handling

@andrewazores
Copy link
Author

@geoand I ran into this in cryostatio/cryostat#733 , but I have prepared a minimal reproducer here:

https://github.com/andrewazores/quarkus-jfr-npe-reproducer

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

Thanks!

I'll have a look soon

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

Your reproducer is great, thanks a lot @andrewazores!

There is a quick and dirty fix for this, but there is also a way to make this for all HTTP requests and I prefer to handle it like this.
I try and put aside some time to handle the issue this week.

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

After looking into it a little more here is the issue we are facing with the way these JFR events are currently designed:

  • If an incoming HTTP request cannot be mapped to JAX-RS / Jakarta REST Resource method, the request is not traced at all
    • Furthermore, RestStartEvent aren't really start events, they are "processing started after resource method matched" events
  • I can make make Quarkus REST trace before a request is matched (so a true start event), but in that case it won't have information about the resource class and method.

My question to @andrewazores and @chiroito is whether it is valid in JFR to have an event created at some point and commited at another. If that is valid I can make Quarkus REST always create a start event, update it if the mapping was successful (and then commit it) or when no mapping was possible also commit it.
For RestEndEvent , nothing would change.

@andrewazores
Copy link
Author

My question to @andrewazores and @chiroito is whether it is valid in JFR to have an event created at some point and commited at another.

I think the specifics of "at some point" are critical here. It's certainly valid for the event to be created, then some time to pass, and then the event to be committed. Even if the reference to that event gets passed around to different places it should be OK.

What I don't know about is whether that's true if the event creation and commit might happen on different threads (physical or virtual). Maybe @roberttoyonaga would know?

@roberttoyonaga
Copy link
Contributor

roberttoyonaga commented Dec 10, 2024

@geoand and @andrewazores

Like Andrew says, its perfectly fine for the event to be created and committed in different places (different functions or after some time etc.).

To my knowledge, it is not ok for events to be created and committed by different threads. The thread specified in the JFR event field "event thread" should be the one that begins and commits each event. However, it is fine for one thread to create and commit an event on behalf of another thread when that event type has a "thread" field in addition to a n "event thread" field. (some periodic events are like this). But even in that case it is a singe thread creating and committing the event.

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

Thanks folks, very helpful information!

@andrewazores
Copy link
Author

The thread specified in the JFR event field "event thread" should be the one that begins and commits each event.

That's what I was thinking.

So for Quarkus purposes I think this has implications for the various processors and filters, and the behaviour of the Blocking annotation or Mutiny async.

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

Right, we'll have to examine that

@roberttoyonaga
Copy link
Contributor

roberttoyonaga commented Dec 10, 2024

@geoand @andrewazores
I was mistaken. I tried out creating and committing an event from different threads and it works. See toy example code here.

The result of running the code:
Image

So the "event thread" field is populated by whichever thread called commit. Hotspot code for writing "event thread".

As far as I'm aware, this doesn't happen with any of the built-in events. But it seems like nothing is stopping you from doing this at the application level.

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

Excellent, thanks a lot @roberttoyonaga !

@andrewazores
Copy link
Author

Another example I threw together, trying to make sure it still works as expected with a little more concurrency and processing happening:

https://github.com/andrewazores/jfr-multithread-processing/blob/main/Main.java

$ jfr summary out.jfr 

 Version: 2.1
 Chunks: 1
 Start: 2024-12-10 19:18:51 (UTC)
 Duration: 2 s

 Event Type                              Count  Size (bytes) 
=============================================================
 Main$CustomEvent                          331         19177
 jdk.Checkpoint                             60         16444
 Main$CollectionSizeEvent                    3            36
 jdk.Metadata                                1        103840
...
$ jfr print --events 'Main$CollectionSizeEvent' out.jfr
Main$CollectionSizeEvent {
  startTime = 14:18:51.360 (2024-12-10)
  size = 0
  eventThread = "pool-1-thread-1" (javaThreadId = 89)
  stackTrace = [
    Main.lambda$run$2() line: 73
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.runAndReset() line: 358
    java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run() line: 305
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
  ]
}

Main$CollectionSizeEvent {
  startTime = 14:18:52.329 (2024-12-10)
  size = 0
  eventThread = "pool-1-thread-1" (javaThreadId = 89)
  stackTrace = [
    Main.lambda$run$2() line: 73
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.runAndReset() line: 358
    java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run() line: 305
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
  ]
}

Main$CollectionSizeEvent {
  startTime = 14:18:53.329 (2024-12-10)
  size = 70
  eventThread = "pool-1-thread-1" (javaThreadId = 89)
  stackTrace = [
    Main.lambda$run$2() line: 73
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.runAndReset() line: 358
    java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run() line: 305
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
  ]
}
Main$CustomEvent {
  startTime = 14:18:51.361 (2024-12-10)
  duration = 0.00516 ms
  id = "7ab11bda-266f-49b1-9d15-c67a713c6e9d"
  dispatcher = "pool-1-thread-1" (javaThreadId = 89)
  executor = "pool-1-thread-1" (javaThreadId = 89)
  idx = 1
  blocking = false
  fib = 1
  eventThread = "pool-1-thread-1" (javaThreadId = 89)
  stackTrace = [
    Main.lambda$run$1() line: 65
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.runAndReset() line: 358
    java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run() line: 305
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
  ]
}

Main$CustomEvent {
  startTime = 14:18:51.361 (2024-12-10)
  duration = 0.0236 ms
  id = "1e96e1bd-a80b-4e46-8598-0e261c7526bd"
  dispatcher = "pool-1-thread-1" (javaThreadId = 89)
  executor = "pool-2-thread-3" (javaThreadId = 59)
  idx = 11
  blocking = true
  fib = 89
  eventThread = "pool-2-thread-3" (javaThreadId = 59)
  stackTrace = [
    Main.lambda$run$0() line: 45
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.run() line: 317
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
    java.util.concurrent.ThreadPoolExecutor$Worker.run() line: 642
  ]
}

Main$CustomEvent {
  startTime = 14:18:51.361 (2024-12-10)
  duration = 0.0182 ms
  id = "4ba37e08-b4d2-40e7-a4a1-1116371eba78"
  dispatcher = "pool-1-thread-1" (javaThreadId = 89)
  executor = "pool-2-thread-5" (javaThreadId = 61)
  idx = 7
  blocking = true
  fib = 13
  eventThread = "pool-2-thread-5" (javaThreadId = 61)
  stackTrace = [
    Main.lambda$run$0() line: 45
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.run() line: 317
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
    java.util.concurrent.ThreadPoolExecutor$Worker.run() line: 642
  ]
}

Main$CustomEvent {
  startTime = 14:18:51.361 (2024-12-10)
  duration = 0.000780 ms
  id = "005835b7-c342-4191-8e0a-915910c65ca1"
  dispatcher = "pool-1-thread-1" (javaThreadId = 89)
  executor = "pool-1-thread-1" (javaThreadId = 89)
  idx = 0
  blocking = false
  fib = 0
  eventThread = "pool-1-thread-1" (javaThreadId = 89)
  stackTrace = [
    Main.lambda$run$1() line: 65
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.runAndReset() line: 358
    java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run() line: 305
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
  ]
}

Main$CustomEvent {
  startTime = 14:18:51.361 (2024-12-10)
  duration = 0.302 ms
  id = "2794666e-6164-43bc-9ad2-79b0d4f4cb46"
  dispatcher = "pool-1-thread-1" (javaThreadId = 89)
  executor = "pool-2-thread-2" (javaThreadId = 58)
  idx = 26
  blocking = true
  fib = 121393
  eventThread = "pool-2-thread-2" (javaThreadId = 58)
  stackTrace = [
    Main.lambda$run$0() line: 45
    java.util.concurrent.Executors$RunnableAdapter.call() line: 572
    java.util.concurrent.FutureTask.run() line: 317
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1144
    java.util.concurrent.ThreadPoolExecutor$Worker.run() line: 642
  ]
}

Everything looks good there too.

@geoand
Copy link
Contributor

geoand commented Dec 10, 2024

🙏

@geoand
Copy link
Contributor

geoand commented Dec 11, 2024

#45059 is what I have in mind

@geoand geoand closed this as completed in 21a9657 Dec 16, 2024
geoand added a commit that referenced this issue Dec 16, 2024
Improve JFR integration in Quarkus REST
@quarkus-bot quarkus-bot bot added this to the 3.18 - main milestone Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/metrics kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants