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

Lazy Load TracingLogger to track MATCH_RESOURCE_METHOD #5628

Merged
merged 1 commit into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -34,6 +34,9 @@
import javax.ws.rs.core.UriBuilder;

import org.glassfish.jersey.internal.util.collection.ImmutableMultivaluedMap;
import org.glassfish.jersey.internal.util.collection.LazyValue;
import org.glassfish.jersey.internal.util.collection.Value;
import org.glassfish.jersey.internal.util.collection.Values;
import org.glassfish.jersey.message.internal.TracingLogger;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.internal.ServerTraceEvent;
Expand Down Expand Up @@ -66,7 +69,7 @@ public class UriRoutingContext implements RoutingContext {
private final LinkedList<ResourceMethod> matchedLocators = new LinkedList<>();
private final LinkedList<Resource> locatorSubResources = new LinkedList<>();

private final TracingLogger tracingLogger;
private final LazyValue<TracingLogger> tracingLogger;

private volatile ResourceMethod matchedResourceMethod = null;
private volatile Throwable mappedThrowable = null;
Expand All @@ -86,7 +89,8 @@ public class UriRoutingContext implements RoutingContext {
*/
public UriRoutingContext(final ContainerRequest requestContext) {
this.requestContext = requestContext;
this.tracingLogger = TracingLogger.getInstance(requestContext);
// Tracing Logger is initialized after UriContext before pushMatchedResource
this.tracingLogger = Values.lazy((Value<TracingLogger>) () -> TracingLogger.getInstance(requestContext));
}

// RoutingContext
Expand All @@ -97,7 +101,7 @@ public void pushMatchResult(final MatchResult matchResult) {

@Override
public void pushMatchedResource(final Object resource) {
tracingLogger.log(ServerTraceEvent.MATCH_RESOURCE, resource);
tracingLogger.get().log(ServerTraceEvent.MATCH_RESOURCE, resource);
matchedResources.push(resource);
}

Expand All @@ -108,7 +112,7 @@ public Object peekMatchedResource() {

@Override
public void pushMatchedLocator(final ResourceMethod resourceLocator) {
tracingLogger.log(ServerTraceEvent.MATCH_LOCATOR, resourceLocator.getInvocable().getHandlingMethod());
tracingLogger.get().log(ServerTraceEvent.MATCH_LOCATOR, resourceLocator.getInvocable().getHandlingMethod());
matchedLocators.push(resourceLocator);
}

Expand Down Expand Up @@ -189,14 +193,14 @@ public Endpoint getEndpoint() {

@Override
public void setMatchedResourceMethod(final ResourceMethod resourceMethod) {
tracingLogger.log(ServerTraceEvent.MATCH_RESOURCE_METHOD, resourceMethod.getInvocable().getHandlingMethod());
tracingLogger.get().log(ServerTraceEvent.MATCH_RESOURCE_METHOD, resourceMethod.getInvocable().getHandlingMethod());
this.matchedResourceMethod = resourceMethod;
}

@Override
public void pushMatchedRuntimeResource(final RuntimeResource runtimeResource) {
if (tracingLogger.isLogEnabled(ServerTraceEvent.MATCH_RUNTIME_RESOURCE)) {
tracingLogger.log(ServerTraceEvent.MATCH_RUNTIME_RESOURCE,
if (tracingLogger.get().isLogEnabled(ServerTraceEvent.MATCH_RUNTIME_RESOURCE)) {
tracingLogger.get().log(ServerTraceEvent.MATCH_RUNTIME_RESOURCE,
runtimeResource.getResources().get(0).getPath(),
runtimeResource.getResources().get(0).getPathPattern().getRegex(),
matchResults.peek().group()
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/tracing-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,25 @@
<artifactId>jersey-test-framework-provider-external</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<java.util.logging.config.file>${project.build.testOutputDirectory}/logging.properties</java.util.logging.config.file>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.tests.integration.tracing;

import org.glassfish.jersey.message.internal.TracingLogger;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.TracingConfig;
import org.glassfish.jersey.server.internal.ServerTraceEvent;
import org.glassfish.jersey.test.JerseyTest;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.stream.Collectors;

public class TracingMatchResourceMethodTest extends JerseyTest {
GatheringHandler handler = new GatheringHandler();
Logger logger;

@Path("/echo")
public static class TracingMatchResourceMethodResource {
@Path("echo")
@POST
public String echo(String entity) {
return entity;
}
}

@Override
protected Application configure() {
return new ResourceConfig(TracingMatchResourceMethodResource.class)
.property(ServerProperties.TRACING, TracingConfig.ALL.name())
.property(ServerProperties.TRACING_THRESHOLD, TracingLogger.Level.VERBOSE.name());
}

@Test
public void testEcho() {
logger = Logger.getLogger("org.glassfish.jersey.tracing.general");
logger.addHandler(handler);

try (Response r = target("echo").path("echo").request().post(Entity.entity("ECHO", MediaType.TEXT_PLAIN_TYPE))) {
MatcherAssert.assertThat(r.getStatus(), Matchers.equalTo(200));
MatcherAssert.assertThat(r.readEntity(String.class), Matchers.equalTo("ECHO"));
}

List<LogRecord> matched = handler.logRecords.stream()
.filter(logRecord -> logRecord.getMessage().startsWith(ServerTraceEvent.MATCH_RESOURCE_METHOD.name()))
.collect(Collectors.toList());
MatcherAssert.assertThat(matched.size(), Matchers.equalTo(1));
}

private static class GatheringHandler extends Handler {

List<LogRecord> logRecords = new ArrayList<>();

@Override
public void publish(LogRecord record) {
logRecords.add(record);
}

@Override
public void flush() {
}

@Override
public void close() throws SecurityException {
}
}
}