Skip to content

Commit

Permalink
fixes #1832 As ProxyHandler is working asynchronously, capture the me…
Browse files Browse the repository at this point in the history
…trics in callback methods (#1824)
  • Loading branch information
stevehu authored Jul 4, 2023
1 parent c846a7d commit 6d7393b
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 19 deletions.
3 changes: 2 additions & 1 deletion egress-router/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>metrics</artifactId>
<artifactId>proxy-handler</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.networknt.client.Http2Client;
import com.networknt.handler.Handler;
import com.networknt.handler.ProxyHandler;
import com.networknt.httpstring.AttachmentConstants;
import com.networknt.metrics.MetricsConfig;
import com.networknt.metrics.AbstractMetricsHandler;
import com.networknt.utility.ModuleRegistry;
Expand Down Expand Up @@ -46,7 +47,6 @@ public class RouterHandler implements HttpHandler {

protected static ProxyHandler proxyHandler;
protected static AbstractMetricsHandler metricsHandler;

public RouterHandler() {
config = RouterConfig.load();
ModuleRegistry.registerModule(RouterHandler.class.getName(), config.getMappedConfig(), null);
Expand Down Expand Up @@ -82,14 +82,18 @@ public RouterHandler() {
logger.error("An instance of MetricsHandler is not configured in the handler.yml.");
}
}

}

@Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
public void handleRequest(HttpServerExchange exchange) throws Exception {
if(logger.isDebugEnabled()) logger.debug("RouterHandler.handleRequest starts.");
long startTime = System.nanoTime();
proxyHandler.handleRequest(httpServerExchange);
if(config.isMetricsInjection() && metricsHandler != null) metricsHandler.injectMetrics(httpServerExchange, startTime, config.getMetricsName(), null);
if(metricsHandler != null) {
exchange.putAttachment(AttachmentConstants.METRICS_HANDLER, metricsHandler);
exchange.putAttachment(AttachmentConstants.DOWNSTREAM_METRICS_NAME, config.getMetricsName());
exchange.putAttachment(AttachmentConstants.DOWNSTREAM_METRICS_START, System.nanoTime());
}
proxyHandler.handleRequest(exchange);
if(logger.isDebugEnabled()) logger.debug("RouterHandler.handleRequest ends.");
}

Expand Down Expand Up @@ -126,5 +130,6 @@ public void reload() {
logger.error("An instance of MetricsHandler is not configured in the handler.yml.");
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ public class AttachmentConstants {
public static final AttachmentKey<PooledByteBuffer[]> BUFFERED_RESPONSE_DATA_KEY = AttachmentKey.create(PooledByteBuffer[].class);
public static final AttachmentKey<PooledByteBuffer[]> BUFFERED_REQUEST_DATA_KEY = AttachmentKey.create(PooledByteBuffer[].class);

public static final AttachmentKey<String> DOWNSTREAM_METRICS_NAME = AttachmentKey.create(String.class);
public static final AttachmentKey<Long> DOWNSTREAM_METRICS_START = AttachmentKey.create(Long.class);
public static final AttachmentKey<Object> METRICS_HANDLER = AttachmentKey.create(Object.class);
}
6 changes: 3 additions & 3 deletions ingress-proxy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>metrics</artifactId>
<artifactId>server</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>server</artifactId>
<artifactId>handler</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>handler</artifactId>
<artifactId>proxy-handler</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.networknt.client.Http2Client;
import com.networknt.config.JsonMapper;
import com.networknt.handler.Handler;
import com.networknt.httpstring.AttachmentConstants;
import com.networknt.metrics.MetricsConfig;
import com.networknt.metrics.AbstractMetricsHandler;
import com.networknt.utility.ModuleRegistry;
Expand Down Expand Up @@ -98,7 +99,6 @@ public LightProxyHandler() {
.setRewriteHostHeader(config.isRewriteHostHeader())
.setNext(ResponseCodeHandler.HANDLE_404)
.build();

if(config.isMetricsInjection()) {
// get the metrics handler from the handler chain for metrics registration. If we cannot get the
// metrics handler, then an error message will be logged.
Expand All @@ -111,16 +111,20 @@ public LightProxyHandler() {
}

@Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
public void handleRequest(HttpServerExchange exchange) throws Exception {
if(logger.isDebugEnabled()) logger.debug("LightProxyHandler.handleRequest starts.");
long startTime = System.nanoTime();
if(config.isForwardJwtClaims()) {
HeaderMap headerValues = httpServerExchange.getRequestHeaders();
HeaderMap headerValues = exchange.getRequestHeaders();
JwtClaims jwtClaims = extractClaimsFromJwt(headerValues);
httpServerExchange.getRequestHeaders().put(HttpString.tryFromString(CLAIMS_KEY), new ObjectMapper().writeValueAsString(jwtClaims.getClaimsMap()));
exchange.getRequestHeaders().put(HttpString.tryFromString(CLAIMS_KEY), new ObjectMapper().writeValueAsString(jwtClaims.getClaimsMap()));
}
if(metricsHandler != null) {
exchange.putAttachment(AttachmentConstants.METRICS_HANDLER, metricsHandler);
exchange.putAttachment(AttachmentConstants.DOWNSTREAM_METRICS_NAME, config.getMetricsName());
exchange.putAttachment(AttachmentConstants.DOWNSTREAM_METRICS_START, System.nanoTime());
}
proxyHandler.handleRequest(httpServerExchange);
if(config.isMetricsInjection() && metricsHandler != null) metricsHandler.injectMetrics(httpServerExchange, startTime, config.getMetricsName(), null);
proxyHandler.handleRequest(exchange);
if(logger.isDebugEnabled()) logger.debug("LightProxyHandler.handleRequest ends.");
}

Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
<module>ldap-util</module>
<module>cache-manager</module>
<module>db-provider</module>
<module>proxy-handler</module>
</modules>

<dependencyManagement>
Expand Down Expand Up @@ -444,6 +445,11 @@
<artifactId>db-provider</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>proxy-handler</artifactId>
<version>${project.version}</version>
</dependency>
<!-- External dependencies -->

<dependency>
Expand Down
90 changes: 90 additions & 0 deletions proxy-handler/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!--
~ Copyright (c) 2016 Network New Technologies Inc.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.networknt</groupId>
<artifactId>light-4j</artifactId>
<version>2.1.23-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>proxy-handler</artifactId>
<packaging>jar</packaging>
<description>A module contains proxy-handler that is shared between ingress-proxy and egress-router.</description>

<dependencies>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>config</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>utility</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>http-string</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>status</artifactId>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>metrics</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>common</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
import com.networknt.handler.config.QueryHeaderRewriteRule;
import com.networknt.handler.config.UrlRewriteRule;
import com.networknt.handler.thread.LightThreadExecutor;
import com.networknt.httpstring.AttachmentConstants;
import com.networknt.httpstring.HttpStringConstants;
import com.networknt.metrics.AbstractMetricsHandler;
import com.networknt.metrics.MetricsHandler;
import com.networknt.utility.CollectionUtils;
import com.networknt.utility.StringUtils;
import io.undertow.UndertowLogger;
Expand Down Expand Up @@ -98,7 +101,6 @@ public class ProxyHandler implements HttpHandler {
private final ProxyClient proxyClient;
private int maxRequestTime;
private final Map<String, Integer> pathPrefixMaxRequestTime;

/**
* Map of additional headers to add to the request.
*/
Expand Down Expand Up @@ -139,7 +141,6 @@ private ProxyHandler(Builder builder) {
}

public void handleRequest(final HttpServerExchange exchange) throws Exception {

this.lightThreadExecutor = new LightThreadExecutor(exchange);

final ProxyClient.ProxyTarget target = proxyClient.findTarget(exchange);
Expand Down Expand Up @@ -353,6 +354,14 @@ public void couldNotResolveBackend(HttpServerExchange ex) {

else {
ex.setStatusCode(StatusCodes.SERVICE_UNAVAILABLE);
AbstractMetricsHandler metricsHandler = (AbstractMetricsHandler) exchange.getAttachment(AttachmentConstants.METRICS_HANDLER);
if(metricsHandler != null) {
String metricsName = exchange.getAttachment(AttachmentConstants.DOWNSTREAM_METRICS_NAME);
if (metricsName != null) {
long startTime = exchange.getAttachment(AttachmentConstants.DOWNSTREAM_METRICS_START);
metricsHandler.injectMetrics(exchange, startTime, metricsName, null);
}
}
ex.endExchange();
}
}
Expand All @@ -374,6 +383,14 @@ void cancel(final HttpServerExchange exchange) {

else {
exchange.setStatusCode(StatusCodes.GATEWAY_TIME_OUT);
AbstractMetricsHandler metricsHandler = (AbstractMetricsHandler) exchange.getAttachment(AttachmentConstants.METRICS_HANDLER);
if(metricsHandler != null) {
String metricsName = exchange.getAttachment(AttachmentConstants.DOWNSTREAM_METRICS_NAME);
if (metricsName != null) {
long startTime = exchange.getAttachment(AttachmentConstants.DOWNSTREAM_METRICS_START);
metricsHandler.injectMetrics(exchange, startTime, metricsName, null);
}
}
exchange.endExchange();
}
}
Expand Down Expand Up @@ -936,9 +953,16 @@ public void completed(final ClientExchange result) {

final IoExceptionHandler handler = new IoExceptionHandler(exchange, result.getConnection());



Transfer.initiateTransfer(result.getResponseChannel(), exchange.getResponseChannel(), ChannelListeners.closingChannelListener(), new HTTPTrailerChannelListener(result, exchange, exchange, proxyClientHandler, idempotentPredicate), handler, handler, exchange.getConnection().getByteBufferPool());

AbstractMetricsHandler metricsHandler = (AbstractMetricsHandler) exchange.getAttachment(AttachmentConstants.METRICS_HANDLER);
if(metricsHandler != null) {
String metricsName = exchange.getAttachment(AttachmentConstants.DOWNSTREAM_METRICS_NAME);
if (metricsName != null) {
long startTime = exchange.getAttachment(AttachmentConstants.DOWNSTREAM_METRICS_START);
metricsHandler.injectMetrics(exchange, startTime, metricsName, null);
}
}
}

private void handleUpgradeChannelOnComplete(ClientExchange result) {
Expand Down
49 changes: 49 additions & 0 deletions proxy-handler/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016 Network New Technologies Inc.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<configuration>
<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
<Marker>PROFILER</Marker>
<!--<OnMatch>DENY</OnMatch>-->
<OnMatch>NEUTRAL</OnMatch>
</turboFilter>

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5marker %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<appender name="log" class="ch.qos.logback.core.FileAppender">
<File>target/test.log</File>
<Append>false</Append>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %class{36}:%L %M - %msg%n</Pattern>
</layout>
</appender>

<root level="trace">
<appender-ref ref="stdout" />
</root>

<logger name="com.networknt" level="trace">
<appender-ref ref="log"/>
</logger>

</configuration>

0 comments on commit 6d7393b

Please sign in to comment.