diff --git a/reactor-netty-core/src/main/java/reactor/netty/Metrics.java b/reactor-netty-core/src/main/java/reactor/netty/Metrics.java index bcecf745fa..5cf3345bf8 100644 --- a/reactor-netty-core/src/main/java/reactor/netty/Metrics.java +++ b/reactor-netty-core/src/main/java/reactor/netty/Metrics.java @@ -293,6 +293,8 @@ public class Metrics { public static final String UNKNOWN = "UNKNOWN"; + public static final String NA = "na"; + @Nullable public static Observation currentObservation(ContextView contextView) { if (contextView.hasKey(OBSERVATION_KEY)) { diff --git a/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsHandler.java b/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsHandler.java index 39296a6631..ddc41fa33a 100644 --- a/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsHandler.java +++ b/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsHandler.java @@ -35,6 +35,7 @@ import static reactor.netty.Metrics.CONNECT_TIME; import static reactor.netty.Metrics.ERROR; +import static reactor.netty.Metrics.NA; import static reactor.netty.Metrics.OBSERVATION_REGISTRY; import static reactor.netty.Metrics.SUCCESS; import static reactor.netty.Metrics.TLS_HANDSHAKE_TIME; @@ -110,12 +111,7 @@ public Observation.Context get() { @Override public Timer getTimer() { - if (proxyAddress == null) { - return recorder.getConnectTimer(getName(), netPeerName + ":" + netPeerPort, status); - } - else { - return recorder.getConnectTimer(getName(), netPeerName + ":" + netPeerPort, proxyAddress, status); - } + return recorder.getConnectTimer(getName(), netPeerName + ":" + netPeerPort, proxyAddress == null ? NA : proxyAddress, status); } @Override @@ -205,13 +201,8 @@ public KeyValues getHighCardinalityKeyValues() { @Override public KeyValues getLowCardinalityKeyValues() { - if (proxyAddress == null) { - return KeyValues.of(REMOTE_ADDRESS.asString(), netPeerName + ":" + netPeerPort, STATUS.asString(), status); - } - else { - return KeyValues.of(REMOTE_ADDRESS.asString(), netPeerName + ":" + netPeerPort, - PROXY_ADDRESS.asString(), proxyAddress, STATUS.asString(), status); - } + return KeyValues.of(REMOTE_ADDRESS.asString(), netPeerName + ":" + netPeerPort, + PROXY_ADDRESS.asString(), proxyAddress == null ? NA : proxyAddress, STATUS.asString(), status); } @Override @@ -349,12 +340,12 @@ public KeyValues getHighCardinalityKeyValues() { @Override public KeyValues getLowCardinalityKeyValues() { - if (proxyAddress == null) { + if (recorder.onServer) { return KeyValues.of(REMOTE_ADDRESS.asString(), netPeerName + ':' + netPeerPort, STATUS.asString(), status); } else { return KeyValues.of(REMOTE_ADDRESS.asString(), netPeerName + ':' + netPeerPort, - PROXY_ADDRESS.asString(), proxyAddress, STATUS.asString(), status); + PROXY_ADDRESS.asString(), proxyAddress == null ? NA : proxyAddress, STATUS.asString(), status); } } @@ -375,12 +366,7 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { @Override public Timer getTimer() { - if (proxyAddress == null) { - return recorder.getTlsHandshakeTimer(getName(), netPeerName + ':' + netPeerPort, status); - } - else { - return recorder.getTlsHandshakeTimer(getName(), netPeerName + ':' + netPeerPort, proxyAddress, status); - } + return recorder.getTlsHandshakeTimer(getName(), netPeerName + ':' + netPeerPort, proxyAddress == null ? NA : proxyAddress, status); } } } diff --git a/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsRecorder.java b/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsRecorder.java index d3f607966e..1cf5bdf596 100644 --- a/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsRecorder.java +++ b/reactor-netty-core/src/main/java/reactor/netty/channel/MicrometerChannelMetricsRecorder.java @@ -36,6 +36,7 @@ import static reactor.netty.Metrics.DATA_RECEIVED; import static reactor.netty.Metrics.DATA_SENT; import static reactor.netty.Metrics.ERRORS; +import static reactor.netty.Metrics.NA; import static reactor.netty.Metrics.PROXY_ADDRESS; import static reactor.netty.Metrics.REGISTRY; import static reactor.netty.Metrics.REMOTE_ADDRESS; @@ -50,13 +51,10 @@ * @since 0.9 */ public class MicrometerChannelMetricsRecorder implements ChannelMetricsRecorder { - final ConcurrentMap dataReceivedCacheNoProxy = new ConcurrentHashMap<>(); final ConcurrentMap dataReceivedCache = new ConcurrentHashMap<>(); - final ConcurrentMap dataSentCacheNoProxy = new ConcurrentHashMap<>(); final ConcurrentMap dataSentCache = new ConcurrentHashMap<>(); - final ConcurrentMap errorsCacheNoProxy = new ConcurrentHashMap<>(); final ConcurrentMap errorsCache = new ConcurrentHashMap<>(); final ConcurrentMap connectTimeCache = new ConcurrentHashMap<>(); @@ -69,38 +67,42 @@ public class MicrometerChannelMetricsRecorder implements ChannelMetricsRecorder final String name; final String protocol; + final boolean onServer; public MicrometerChannelMetricsRecorder(String name, String protocol) { + this(name, protocol, true); + } + + public MicrometerChannelMetricsRecorder(String name, String protocol, boolean onServer) { this.name = name; this.protocol = protocol; + this.onServer = onServer; } @Override public void recordDataReceived(SocketAddress remoteAddress, long bytes) { - String address = formatSocketAddress(remoteAddress); - DistributionSummary ds = MapUtils.computeIfAbsent(dataReceivedCacheNoProxy, address, - key -> filter(DistributionSummary.builder(name + DATA_RECEIVED) - .baseUnit(ChannelMeters.DATA_RECEIVED.getBaseUnit()) - .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, - ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address) - .register(REGISTRY))); - if (ds != null) { - ds.record(bytes); - } + recordDataReceived(remoteAddress, NA, bytes); } @Override public void recordDataReceived(SocketAddress remoteAddress, SocketAddress proxyAddress, long bytes) { + recordDataReceived(remoteAddress, formatSocketAddress(proxyAddress), bytes); + } + + void recordDataReceived(SocketAddress remoteAddress, @Nullable String proxyAddress, long bytes) { String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(null, address, proxyAddr, null, null); - DistributionSummary ds = MapUtils.computeIfAbsent(dataReceivedCache, meterKey, - key -> filter(DistributionSummary.builder(name + DATA_RECEIVED) - .baseUnit(ChannelMeters.DATA_RECEIVED.getBaseUnit()) - .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, - ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address, - ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddr) - .register(REGISTRY))); + MeterKey meterKey = new MeterKey(null, address, proxyAddress, null, null); + DistributionSummary ds = MapUtils.computeIfAbsent(dataReceivedCache, meterKey, key -> { + DistributionSummary.Builder builder = + DistributionSummary.builder(name + DATA_RECEIVED) + .baseUnit(ChannelMeters.DATA_RECEIVED.getBaseUnit()) + .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, + ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address); + if (!onServer) { + builder.tag(ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddress); + } + return filter(builder.register(REGISTRY)); + }); if (ds != null) { ds.record(bytes); } @@ -108,30 +110,28 @@ public void recordDataReceived(SocketAddress remoteAddress, SocketAddress proxyA @Override public void recordDataSent(SocketAddress remoteAddress, long bytes) { - String address = formatSocketAddress(remoteAddress); - DistributionSummary ds = MapUtils.computeIfAbsent(dataSentCacheNoProxy, address, - key -> filter(DistributionSummary.builder(name + DATA_SENT) - .baseUnit(ChannelMeters.DATA_SENT.getBaseUnit()) - .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, - ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address) - .register(REGISTRY))); - if (ds != null) { - ds.record(bytes); - } + recordDataSent(remoteAddress, NA, bytes); } @Override public void recordDataSent(SocketAddress remoteAddress, SocketAddress proxyAddress, long bytes) { + recordDataSent(remoteAddress, formatSocketAddress(proxyAddress), bytes); + } + + void recordDataSent(SocketAddress remoteAddress, @Nullable String proxyAddress, long bytes) { String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(null, address, proxyAddr, null, null); - DistributionSummary ds = MapUtils.computeIfAbsent(dataSentCache, meterKey, - key -> filter(DistributionSummary.builder(name + DATA_SENT) - .baseUnit(ChannelMeters.DATA_SENT.getBaseUnit()) - .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, - ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address, - ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddr) - .register(REGISTRY))); + MeterKey meterKey = new MeterKey(null, address, proxyAddress, null, null); + DistributionSummary ds = MapUtils.computeIfAbsent(dataSentCache, meterKey, key -> { + DistributionSummary.Builder builder = + DistributionSummary.builder(name + DATA_SENT) + .baseUnit(ChannelMeters.DATA_SENT.getBaseUnit()) + .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, + ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address); + if (!onServer) { + builder.tag(ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddress); + } + return filter(builder.register(REGISTRY)); + }); if (ds != null) { ds.record(bytes); } @@ -139,28 +139,26 @@ public void recordDataSent(SocketAddress remoteAddress, SocketAddress proxyAddre @Override public void incrementErrorsCount(SocketAddress remoteAddress) { - String address = formatSocketAddress(remoteAddress); - Counter c = MapUtils.computeIfAbsent(errorsCacheNoProxy, address, - key -> filter(Counter.builder(name + ERRORS) - .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, - ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address) - .register(REGISTRY))); - if (c != null) { - c.increment(); - } + incrementErrorsCount(remoteAddress, NA); } @Override public void incrementErrorsCount(SocketAddress remoteAddress, SocketAddress proxyAddress) { + incrementErrorsCount(remoteAddress, formatSocketAddress(proxyAddress)); + } + + void incrementErrorsCount(SocketAddress remoteAddress, @Nullable String proxyAddress) { String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(null, address, proxyAddr, null, null); - Counter c = MapUtils.computeIfAbsent(errorsCache, meterKey, - key -> filter(Counter.builder(name + ERRORS) - .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, - ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address, - ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddr) - .register(REGISTRY))); + MeterKey meterKey = new MeterKey(null, address, proxyAddress, null, null); + Counter c = MapUtils.computeIfAbsent(errorsCache, meterKey, key -> { + Counter.Builder builder = Counter.builder(name + ERRORS) + .tags(ChannelMeters.ChannelMetersTags.URI.asString(), protocol, + ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address); + if (!onServer) { + builder.tag(ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddress); + } + return filter(builder.register(REGISTRY)); + }); if (c != null) { c.increment(); } @@ -168,14 +166,24 @@ public void incrementErrorsCount(SocketAddress remoteAddress, SocketAddress prox @Override public void recordTlsHandshakeTime(SocketAddress remoteAddress, Duration time, String status) { - String address = formatSocketAddress(remoteAddress); - Timer timer = getTlsHandshakeTimer(name + TLS_HANDSHAKE_TIME, address, status); + Timer timer = getTlsHandshakeTimer(name + TLS_HANDSHAKE_TIME, formatSocketAddress(remoteAddress), NA, status); if (timer != null) { timer.record(time); } } + /** + * Returns TLS handshake timer. + * + * @param name the timer name + * @param address the remote address + * @param status the status of the TLS handshake operation + * @return TLS handshake timer + * @deprecated as of 1.1.19. Prefer the {@link #getTlsHandshakeTimer(String, String, String, String)}. + * This method will be removed in version 1.3.0. + */ @Nullable + @Deprecated public final Timer getTlsHandshakeTimer(String name, @Nullable String address, String status) { MeterKey meterKey = new MeterKey(null, address, null, null, status); return MapUtils.computeIfAbsent(tlsHandshakeTimeCache, meterKey, @@ -186,57 +194,55 @@ public final Timer getTlsHandshakeTimer(String name, @Nullable String address, S @Override public void recordTlsHandshakeTime(SocketAddress remoteAddress, SocketAddress proxyAddress, Duration time, String status) { - String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - Timer timer = getTlsHandshakeTimer(name + TLS_HANDSHAKE_TIME, address, proxyAddr, status); + Timer timer = getTlsHandshakeTimer(name + TLS_HANDSHAKE_TIME, formatSocketAddress(remoteAddress), formatSocketAddress(proxyAddress), status); if (timer != null) { timer.record(time); } } + /** + * Returns TLS handshake timer. + * + * @param name the timer name + * @param remoteAddress the remote address + * @param proxyAddress the proxy address + * @param status the status of the TLS handshake operation + * @return TLS handshake timer + */ @Nullable - public final Timer getTlsHandshakeTimer(String name, @Nullable String address, @Nullable String proxyAddr, String status) { - MeterKey meterKey = new MeterKey(null, address, proxyAddr, null, status); - return MapUtils.computeIfAbsent(tlsHandshakeTimeCache, meterKey, - key -> filter(Timer.builder(name) - .tags(REMOTE_ADDRESS, address, PROXY_ADDRESS, proxyAddr, STATUS, status) - .register(REGISTRY))); + public final Timer getTlsHandshakeTimer(String name, @Nullable String remoteAddress, @Nullable String proxyAddress, String status) { + MeterKey meterKey = new MeterKey(null, remoteAddress, proxyAddress, null, status); + return MapUtils.computeIfAbsent(tlsHandshakeTimeCache, meterKey, key -> { + Timer.Builder builder = Timer.builder(name).tags(REMOTE_ADDRESS, remoteAddress, STATUS, status); + if (!onServer) { + builder.tag(PROXY_ADDRESS, proxyAddress); + } + return filter(builder.register(REGISTRY)); + }); } @Override public void recordConnectTime(SocketAddress remoteAddress, Duration time, String status) { - String address = formatSocketAddress(remoteAddress); - Timer timer = getConnectTimer(name + CONNECT_TIME, address, status); + Timer timer = getConnectTimer(name + CONNECT_TIME, formatSocketAddress(remoteAddress), NA, status); if (timer != null) { timer.record(time); } } - @Nullable - final Timer getConnectTimer(String name, @Nullable String address, String status) { - MeterKey meterKey = new MeterKey(null, address, null, null, status); - return MapUtils.computeIfAbsent(connectTimeCache, meterKey, - key -> filter(Timer.builder(name) - .tags(REMOTE_ADDRESS, address, STATUS, status) - .register(REGISTRY))); - } - @Override public void recordConnectTime(SocketAddress remoteAddress, SocketAddress proxyAddress, Duration time, String status) { - String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - Timer timer = getConnectTimer(name + CONNECT_TIME, address, proxyAddr, status); + Timer timer = getConnectTimer(name + CONNECT_TIME, formatSocketAddress(remoteAddress), formatSocketAddress(proxyAddress), status); if (timer != null) { timer.record(time); } } @Nullable - final Timer getConnectTimer(String name, @Nullable String address, @Nullable String proxyAddr, String status) { - MeterKey meterKey = new MeterKey(null, address, proxyAddr, null, status); + final Timer getConnectTimer(String name, @Nullable String remoteAddress, @Nullable String proxyAddress, String status) { + MeterKey meterKey = new MeterKey(null, remoteAddress, proxyAddress, null, status); return MapUtils.computeIfAbsent(connectTimeCache, meterKey, key -> filter(Timer.builder(name) - .tags(REMOTE_ADDRESS, address, PROXY_ADDRESS, proxyAddr, STATUS, status) + .tags(REMOTE_ADDRESS, remoteAddress, PROXY_ADDRESS, proxyAddress, STATUS, status) .register(REGISTRY))); } diff --git a/reactor-netty-core/src/main/java/reactor/netty/tcp/TcpClientConfig.java b/reactor-netty-core/src/main/java/reactor/netty/tcp/TcpClientConfig.java index bafe3dbe24..92812a43a6 100644 --- a/reactor-netty-core/src/main/java/reactor/netty/tcp/TcpClientConfig.java +++ b/reactor-netty-core/src/main/java/reactor/netty/tcp/TcpClientConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2023 VMware, Inc. or its affiliates, All Rights Reserved. + * Copyright (c) 2020-2024 VMware, Inc. or its affiliates, All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -149,7 +149,7 @@ static final class MicrometerTcpClientMetricsRecorder extends MicrometerChannelM static final MicrometerTcpClientMetricsRecorder INSTANCE = new MicrometerTcpClientMetricsRecorder(); MicrometerTcpClientMetricsRecorder() { - super(reactor.netty.Metrics.TCP_CLIENT_PREFIX, "tcp"); + super(reactor.netty.Metrics.TCP_CLIENT_PREFIX, "tcp", false); } } diff --git a/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpMetricsTests.java b/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpMetricsTests.java index 459229a8a1..caae250889 100644 --- a/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpMetricsTests.java +++ b/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpMetricsTests.java @@ -24,6 +24,8 @@ import static reactor.netty.Metrics.DATA_SENT; import static reactor.netty.Metrics.ERRORS; import static reactor.netty.Metrics.LOCAL_ADDRESS; +import static reactor.netty.Metrics.NA; +import static reactor.netty.Metrics.PROXY_ADDRESS; import static reactor.netty.Metrics.REMOTE_ADDRESS; import static reactor.netty.Metrics.STATUS; import static reactor.netty.Metrics.TCP_CLIENT_PREFIX; @@ -247,8 +249,8 @@ private void checkExpectationsPositive() { .hasTotalAmountGreaterThanOrEqualTo(5); assertCounter(registry, SERVER_ERRORS, summaryTags).isNull(); - timerTags = new String[] {REMOTE_ADDRESS, serverAddress, STATUS, "SUCCESS"}; - summaryTags = new String[] {REMOTE_ADDRESS, serverAddress, URI, "tcp"}; + timerTags = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, STATUS, "SUCCESS"}; + summaryTags = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, "tcp"}; assertTimer(registry, CLIENT_CONNECT_TIME, timerTags) .hasCountEqualTo(1) .hasTotalTimeGreaterThanOrEqualTo(0); @@ -265,9 +267,9 @@ private void checkExpectationsPositive() { private void checkExpectationsNegative(int port) { String address = "127.0.0.1:" + port; - String[] timerTags1 = new String[] {REMOTE_ADDRESS, address, STATUS, "ERROR"}; - String[] timerTags2 = new String[] {REMOTE_ADDRESS, address, STATUS, "SUCCESS"}; - String[] summaryTags = new String[] {REMOTE_ADDRESS, address, URI, "tcp"}; + String[] timerTags1 = new String[] {REMOTE_ADDRESS, address, PROXY_ADDRESS, NA, STATUS, "ERROR"}; + String[] timerTags2 = new String[] {REMOTE_ADDRESS, address, PROXY_ADDRESS, NA, STATUS, "SUCCESS"}; + String[] summaryTags = new String[] {REMOTE_ADDRESS, address, PROXY_ADDRESS, NA, URI, "tcp"}; assertTimer(registry, CLIENT_CONNECT_TIME, timerTags1) .hasCountEqualTo(1) diff --git a/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpSecureMetricsTests.java b/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpSecureMetricsTests.java index c04dadd72a..5f55ac7591 100644 --- a/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpSecureMetricsTests.java +++ b/reactor-netty-core/src/test/java/reactor/netty/tcp/TcpSecureMetricsTests.java @@ -31,6 +31,8 @@ import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; +import static reactor.netty.Metrics.NA; +import static reactor.netty.Metrics.PROXY_ADDRESS; import static reactor.netty.Metrics.REMOTE_ADDRESS; import static reactor.netty.Metrics.STATUS; import static reactor.netty.Metrics.URI; @@ -127,8 +129,8 @@ private void checkExpectationsNegative() { InetSocketAddress sa = (InetSocketAddress) disposableServer.channel().localAddress(); String serverAddress = sa.getHostString() + ":" + sa.getPort(); - timerTags = new String[] {REMOTE_ADDRESS, serverAddress, STATUS, "SUCCESS"}; - summaryTags = new String[] {REMOTE_ADDRESS, serverAddress, URI, "tcp"}; + timerTags = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, STATUS, "SUCCESS"}; + summaryTags = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, "tcp"}; assertTimer(registry, CLIENT_CONNECT_TIME, timerTags) .hasCountEqualTo(1) diff --git a/reactor-netty-http/src/main/java/reactor/netty/http/MicrometerHttpMetricsRecorder.java b/reactor-netty-http/src/main/java/reactor/netty/http/MicrometerHttpMetricsRecorder.java index 3b4eddbec7..526241cc35 100644 --- a/reactor-netty-http/src/main/java/reactor/netty/http/MicrometerHttpMetricsRecorder.java +++ b/reactor-netty-http/src/main/java/reactor/netty/http/MicrometerHttpMetricsRecorder.java @@ -55,7 +55,11 @@ public class MicrometerHttpMetricsRecorder extends MicrometerChannelMetricsRecor private final ConcurrentMap errorsCache = new ConcurrentHashMap<>(); protected MicrometerHttpMetricsRecorder(String name, String protocol) { - super(name, protocol); + this(name, protocol, true); + } + + protected MicrometerHttpMetricsRecorder(String name, String protocol, boolean onServer) { + super(name, protocol, onServer); } @Override diff --git a/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsHandler.java b/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsHandler.java index e2f7ccdea6..a57dd549a6 100644 --- a/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsHandler.java +++ b/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsHandler.java @@ -33,6 +33,7 @@ import java.util.function.Function; import java.util.function.Supplier; +import static reactor.netty.Metrics.NA; import static reactor.netty.Metrics.OBSERVATION_REGISTRY; import static reactor.netty.Metrics.RESPONSE_TIME; import static reactor.netty.Metrics.UNKNOWN; @@ -188,12 +189,7 @@ public Observation.Context get() { @Override public Timer getTimer() { - if (proxyAddress == null) { - return recorder.getResponseTimeTimer(getName(), netPeerName + ":" + netPeerPort, path, method, status); - } - else { - return recorder.getResponseTimeTimer(getName(), netPeerName + ":" + netPeerPort, proxyAddress, path, method, status); - } + return recorder.getResponseTimeTimer(getName(), netPeerName + ":" + netPeerPort, proxyAddress == null ? NA : proxyAddress, path, method, status); } @Override @@ -205,15 +201,9 @@ public KeyValues getHighCardinalityKeyValues() { @Override public KeyValues getLowCardinalityKeyValues() { - if (proxyAddress == null) { - return KeyValues.of(METHOD.asString(), method, REMOTE_ADDRESS.asString(), netPeerName + ":" + netPeerPort, - STATUS.asString(), status, URI.asString(), path); - } - else { - return KeyValues.of(METHOD.asString(), method, REMOTE_ADDRESS.asString(), netPeerName + ":" + netPeerPort, - PROXY_ADDRESS.asString(), proxyAddress, - STATUS.asString(), status, URI.asString(), path); - } + return KeyValues.of(METHOD.asString(), method, REMOTE_ADDRESS.asString(), netPeerName + ":" + netPeerPort, + PROXY_ADDRESS.asString(), proxyAddress == null ? NA : proxyAddress, + STATUS.asString(), status, URI.asString(), path); } } } diff --git a/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsRecorder.java b/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsRecorder.java index 1fcc8475c1..ce1479093e 100644 --- a/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsRecorder.java +++ b/reactor-netty-http/src/main/java/reactor/netty/http/client/MicrometerHttpClientMetricsRecorder.java @@ -37,6 +37,7 @@ import static reactor.netty.Metrics.ERRORS; import static reactor.netty.Metrics.HTTP_CLIENT_PREFIX; import static reactor.netty.Metrics.METHOD; +import static reactor.netty.Metrics.NA; import static reactor.netty.Metrics.PROXY_ADDRESS; import static reactor.netty.Metrics.REGISTRY; import static reactor.netty.Metrics.REMOTE_ADDRESS; @@ -62,34 +63,26 @@ final class MicrometerHttpClientMetricsRecorder extends MicrometerHttpMetricsRec private final ConcurrentMap errorsCache = new ConcurrentHashMap<>(); private MicrometerHttpClientMetricsRecorder() { - super(HTTP_CLIENT_PREFIX, "http"); + super(HTTP_CLIENT_PREFIX, "http", false); } @Override public void recordDataReceivedTime(SocketAddress remoteAddress, String uri, String method, String status, Duration time) { - String address = formatSocketAddress(remoteAddress); - MeterKey meterKey = new MeterKey(uri, address, null, method, status); - Timer dataReceivedTime = MapUtils.computeIfAbsent(dataReceivedTimeCache, meterKey, - key -> filter(Timer.builder(name() + DATA_RECEIVED_TIME) - .tags(HttpClientMeters.DataReceivedTimeTags.REMOTE_ADDRESS.asString(), address, - HttpClientMeters.DataReceivedTimeTags.URI.asString(), uri, - HttpClientMeters.DataReceivedTimeTags.METHOD.asString(), method, - HttpClientMeters.DataReceivedTimeTags.STATUS.asString(), status) - .register(REGISTRY))); - if (dataReceivedTime != null) { - dataReceivedTime.record(time); - } + recordDataReceivedTime(remoteAddress, NA, uri, method, status, time); } @Override public void recordDataReceivedTime(SocketAddress remoteAddress, SocketAddress proxyAddress, String uri, String method, String status, Duration time) { + recordDataReceivedTime(remoteAddress, formatSocketAddress(proxyAddress), uri, method, status, time); + } + + void recordDataReceivedTime(SocketAddress remoteAddress, @Nullable String proxyAddress, String uri, String method, String status, Duration time) { String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(uri, address, proxyAddr, method, status); + MeterKey meterKey = new MeterKey(uri, address, proxyAddress, method, status); Timer dataReceivedTime = MapUtils.computeIfAbsent(dataReceivedTimeCache, meterKey, key -> filter(Timer.builder(name() + DATA_RECEIVED_TIME) .tags(HttpClientMeters.DataReceivedTimeTags.REMOTE_ADDRESS.asString(), address, - HttpClientMeters.DataReceivedTimeTags.PROXY_ADDRESS.asString(), proxyAddr, + HttpClientMeters.DataReceivedTimeTags.PROXY_ADDRESS.asString(), proxyAddress, HttpClientMeters.DataReceivedTimeTags.URI.asString(), uri, HttpClientMeters.DataReceivedTimeTags.METHOD.asString(), method, HttpClientMeters.DataReceivedTimeTags.STATUS.asString(), status) @@ -101,28 +94,21 @@ public void recordDataReceivedTime(SocketAddress remoteAddress, SocketAddress pr @Override public void recordDataSentTime(SocketAddress remoteAddress, String uri, String method, Duration time) { - String address = formatSocketAddress(remoteAddress); - MeterKey meterKey = new MeterKey(uri, address, null, method, null); - Timer dataSentTime = MapUtils.computeIfAbsent(dataSentTimeCache, meterKey, - key -> filter(Timer.builder(name() + DATA_SENT_TIME) - .tags(HttpClientMeters.DataSentTimeTags.REMOTE_ADDRESS.asString(), address, - HttpClientMeters.DataSentTimeTags.URI.asString(), uri, - HttpClientMeters.DataSentTimeTags.METHOD.asString(), method) - .register(REGISTRY))); - if (dataSentTime != null) { - dataSentTime.record(time); - } + recordDataSentTime(remoteAddress, NA, uri, method, time); } @Override public void recordDataSentTime(SocketAddress remoteAddress, SocketAddress proxyAddress, String uri, String method, Duration time) { + recordDataSentTime(remoteAddress, formatSocketAddress(proxyAddress), uri, method, time); + } + + void recordDataSentTime(SocketAddress remoteAddress, @Nullable String proxyAddress, String uri, String method, Duration time) { String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(uri, address, proxyAddr, method, null); + MeterKey meterKey = new MeterKey(uri, address, proxyAddress, method, null); Timer dataSentTime = MapUtils.computeIfAbsent(dataSentTimeCache, meterKey, key -> filter(Timer.builder(name() + DATA_SENT_TIME) .tags(HttpClientMeters.DataSentTimeTags.REMOTE_ADDRESS.asString(), address, - HttpClientMeters.DataSentTimeTags.PROXY_ADDRESS.asString(), proxyAddr, + HttpClientMeters.DataSentTimeTags.PROXY_ADDRESS.asString(), proxyAddress, HttpClientMeters.DataSentTimeTags.URI.asString(), uri, HttpClientMeters.DataSentTimeTags.METHOD.asString(), method) .register(REGISTRY))); @@ -133,51 +119,47 @@ public void recordDataSentTime(SocketAddress remoteAddress, SocketAddress proxyA @Override public void recordResponseTime(SocketAddress remoteAddress, String uri, String method, String status, Duration time) { - String address = formatSocketAddress(remoteAddress); - Timer responseTime = getResponseTimeTimer(name() + RESPONSE_TIME, address, uri, method, status); + Timer responseTime = getResponseTimeTimer(name() + RESPONSE_TIME, formatSocketAddress(remoteAddress), NA, uri, method, status); if (responseTime != null) { responseTime.record(time); } } - @Nullable - final Timer getResponseTimeTimer(String name, @Nullable String address, String uri, String method, String status) { - MeterKey meterKey = new MeterKey(uri, address, null, method, status); - return MapUtils.computeIfAbsent(responseTimeCache, meterKey, - key -> filter(Timer.builder(name) - .tags(REMOTE_ADDRESS, address, URI, uri, METHOD, method, STATUS, status) - .register(REGISTRY))); - } - @Override public void recordResponseTime(SocketAddress remoteAddress, SocketAddress proxyAddress, String uri, String method, String status, Duration time) { - String address = formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - Timer responseTime = getResponseTimeTimer(name() + RESPONSE_TIME, address, proxyAddr, uri, method, status); + Timer responseTime = getResponseTimeTimer(name() + RESPONSE_TIME, formatSocketAddress(remoteAddress), formatSocketAddress(proxyAddress), uri, method, status); if (responseTime != null) { responseTime.record(time); } } @Nullable - final Timer getResponseTimeTimer(String name, @Nullable String address, @Nullable String proxyAddress, String uri, String method, String status) { - MeterKey meterKey = new MeterKey(uri, address, proxyAddress, method, status); + Timer getResponseTimeTimer(String name, @Nullable String remoteAddress, @Nullable String proxyAddress, String uri, String method, String status) { + MeterKey meterKey = new MeterKey(uri, remoteAddress, proxyAddress, method, status); return MapUtils.computeIfAbsent(responseTimeCache, meterKey, key -> filter(Timer.builder(name) - .tags(REMOTE_ADDRESS, address, PROXY_ADDRESS, proxyAddress, URI, uri, METHOD, method, STATUS, status) + .tags(REMOTE_ADDRESS, remoteAddress, PROXY_ADDRESS, proxyAddress, URI, uri, METHOD, method, STATUS, status) .register(REGISTRY))); } + @Override + public void recordDataReceived(SocketAddress remoteAddress, String uri, long bytes) { + recordDataReceived(remoteAddress, NA, uri, bytes); + } + @Override public void recordDataReceived(SocketAddress remoteAddress, SocketAddress proxyAddress, String uri, long bytes) { + recordDataReceived(remoteAddress, formatSocketAddress(proxyAddress), uri, bytes); + } + + void recordDataReceived(SocketAddress remoteAddress, @Nullable String proxyAddress, String uri, long bytes) { String address = Metrics.formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(uri, address, proxyAddr, null, null); + MeterKey meterKey = new MeterKey(uri, address, proxyAddress, null, null); DistributionSummary dataReceived = MapUtils.computeIfAbsent(dataReceivedCache, meterKey, key -> filter(DistributionSummary.builder(name() + DATA_RECEIVED) .baseUnit(ChannelMeters.DATA_RECEIVED.getBaseUnit()) .tags(ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address, - ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddr, + ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddress, ChannelMeters.ChannelMetersTags.URI.asString(), uri) .register(REGISTRY))); if (dataReceived != null) { @@ -185,16 +167,24 @@ public void recordDataReceived(SocketAddress remoteAddress, SocketAddress proxyA } } + @Override + public void recordDataSent(SocketAddress remoteAddress, String uri, long bytes) { + recordDataSent(remoteAddress, NA, uri, bytes); + } + @Override public void recordDataSent(SocketAddress remoteAddress, SocketAddress proxyAddress, String uri, long bytes) { + recordDataSent(remoteAddress, formatSocketAddress(proxyAddress), uri, bytes); + } + + void recordDataSent(SocketAddress remoteAddress, @Nullable String proxyAddress, String uri, long bytes) { String address = Metrics.formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(uri, address, proxyAddr, null, null); + MeterKey meterKey = new MeterKey(uri, address, proxyAddress, null, null); DistributionSummary dataSent = MapUtils.computeIfAbsent(dataSentCache, meterKey, key -> filter(DistributionSummary.builder(name() + DATA_SENT) .baseUnit(ChannelMeters.DATA_SENT.getBaseUnit()) .tags(ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address, - ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddr, + ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddress, ChannelMeters.ChannelMetersTags.URI.asString(), uri) .register(REGISTRY))); if (dataSent != null) { @@ -202,15 +192,23 @@ public void recordDataSent(SocketAddress remoteAddress, SocketAddress proxyAddre } } + @Override + public void incrementErrorsCount(SocketAddress remoteAddress, String uri) { + incrementErrorsCount(remoteAddress, NA, uri); + } + @Override public void incrementErrorsCount(SocketAddress remoteAddress, SocketAddress proxyAddress, String uri) { + incrementErrorsCount(remoteAddress, formatSocketAddress(proxyAddress), uri); + } + + void incrementErrorsCount(SocketAddress remoteAddress, @Nullable String proxyAddress, String uri) { String address = Metrics.formatSocketAddress(remoteAddress); - String proxyAddr = formatSocketAddress(proxyAddress); - MeterKey meterKey = new MeterKey(uri, address, proxyAddr, null, null); + MeterKey meterKey = new MeterKey(uri, address, proxyAddress, null, null); Counter errors = MapUtils.computeIfAbsent(errorsCache, meterKey, key -> filter(Counter.builder(name() + ERRORS) .tags(ChannelMeters.ChannelMetersTags.REMOTE_ADDRESS.asString(), address, - ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddr, + ChannelMeters.ChannelMetersTags.PROXY_ADDRESS.asString(), proxyAddress, ChannelMeters.ChannelMetersTags.URI.asString(), uri) .register(REGISTRY))); if (errors != null) { diff --git a/reactor-netty-http/src/test/java/reactor/netty/http/HttpMetricsHandlerTests.java b/reactor-netty-http/src/test/java/reactor/netty/http/HttpMetricsHandlerTests.java index e3c50cf656..f68c939b5c 100644 --- a/reactor-netty-http/src/test/java/reactor/netty/http/HttpMetricsHandlerTests.java +++ b/reactor-netty-http/src/test/java/reactor/netty/http/HttpMetricsHandlerTests.java @@ -106,6 +106,8 @@ import static reactor.netty.Metrics.HTTP_SERVER_PREFIX; import static reactor.netty.Metrics.LOCAL_ADDRESS; import static reactor.netty.Metrics.METHOD; +import static reactor.netty.Metrics.NA; +import static reactor.netty.Metrics.PROXY_ADDRESS; import static reactor.netty.Metrics.REMOTE_ADDRESS; import static reactor.netty.Metrics.RESPONSE_TIME; import static reactor.netty.Metrics.STATUS; @@ -741,7 +743,7 @@ void testServerConnectionsMicrometerConnectionClose(HttpProtocol[] serverProtoco assertGauge(registry, SERVER_CONNECTIONS_TOTAL, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(0); assertGauge(registry, SERVER_CONNECTIONS_ACTIVE, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(0); // https://github.com/reactor/reactor-netty/issues/3060 - assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/6").hasCountGreaterThanOrEqualTo(1); + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, PROXY_ADDRESS, NA, URI, "/6").hasCountGreaterThanOrEqualTo(1); } else { // make sure the client stream is closed on the server side before checking server metrics @@ -749,7 +751,7 @@ void testServerConnectionsMicrometerConnectionClose(HttpProtocol[] serverProtoco assertGauge(registry, SERVER_CONNECTIONS_TOTAL, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(1); assertGauge(registry, SERVER_STREAMS_ACTIVE, URI, HTTP, LOCAL_ADDRESS, address).hasValueEqualTo(0); // https://github.com/reactor/reactor-netty/issues/3060 - assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/6").hasCountGreaterThanOrEqualTo(1); + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, PROXY_ADDRESS, NA, URI, "/6").hasCountGreaterThanOrEqualTo(1); // in case of H2, the tearDown method will ensure client socket is closed on the server side } } @@ -865,7 +867,7 @@ void testServerConnectionsRecorderConnectionClose(HttpProtocol[] serverProtocols assertThat(ServerRecorder.INSTANCE.onActiveConnectionsLocalAddr.get()).isEqualTo(address); assertThat(ServerRecorder.INSTANCE.onInactiveConnectionsLocalAddr.get()).isEqualTo(address); // https://github.com/reactor/reactor-netty/issues/3060 - assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/7").hasCountGreaterThanOrEqualTo(1); + assertCounter(registry, CLIENT_ERRORS, PROXY_ADDRESS, NA, REMOTE_ADDRESS, address, URI, "/7").hasCountGreaterThanOrEqualTo(1); } else { assertThat(StreamCloseHandler.INSTANCE.awaitClientClosedOnServer()).as("awaitClientClosedOnServer timeout").isTrue(); @@ -874,7 +876,7 @@ void testServerConnectionsRecorderConnectionClose(HttpProtocol[] serverProtocols assertThat(ServerRecorder.INSTANCE.onActiveConnectionsLocalAddr.get()).isEqualTo(address); assertThat(ServerRecorder.INSTANCE.onInactiveConnectionsLocalAddr.get()).isEqualTo(address); // https://github.com/reactor/reactor-netty/issues/3060 - assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, URI, "/7").hasCountGreaterThanOrEqualTo(1); + assertCounter(registry, CLIENT_ERRORS, REMOTE_ADDRESS, address, PROXY_ADDRESS, NA, URI, "/7").hasCountGreaterThanOrEqualTo(1); // in case of H2, the tearDown method will ensure client socket is closed on the server side } } @@ -924,7 +926,7 @@ void testIssue896() throws Exception { InetSocketAddress sa = (InetSocketAddress) disposableServer.channel().localAddress(); String serverAddress = sa.getHostString() + ":" + sa.getPort(); - String[] summaryTags = new String[]{REMOTE_ADDRESS, serverAddress, URI, "unknown"}; + String[] summaryTags = new String[]{REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, "unknown"}; assertCounter(registry, CLIENT_ERRORS, summaryTags).hasCountGreaterThanOrEqualTo(2); } @@ -1068,7 +1070,7 @@ void testIssue3060ConnectTimeoutException(HttpProtocol[] serverProtocols, HttpPr assertThat(latch.await(30, TimeUnit.SECONDS)).as("latch await").isTrue(); - String[] summaryTags = new String[]{REMOTE_ADDRESS, "1.1.1.1:11111", STATUS, ERROR}; + String[] summaryTags = new String[]{REMOTE_ADDRESS, "1.1.1.1:11111", PROXY_ADDRESS, NA, STATUS, ERROR}; assertTimer(registry, CLIENT_CONNECT_TIME, summaryTags).hasCountEqualTo(1); } @@ -1223,11 +1225,11 @@ private void checkExpectationsExisting(String uri, String serverAddress, int con .hasTotalAmountGreaterThanOrEqualTo(12); assertCounter(registry, SERVER_ERRORS, summaryTags1).isNull(); - timerTags1 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri, METHOD, "POST", STATUS, "200"}; - timerTags2 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri, METHOD, "POST"}; - String[] timerTags3 = new String[] {REMOTE_ADDRESS, serverAddress, STATUS, "SUCCESS"}; - summaryTags1 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri}; - String[] summaryTags2 = new String[] {REMOTE_ADDRESS, serverAddress, URI, "http"}; + timerTags1 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri, METHOD, "POST", STATUS, "200"}; + timerTags2 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri, METHOD, "POST"}; + String[] timerTags3 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, STATUS, "SUCCESS"}; + summaryTags1 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri}; + String[] summaryTags2 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, "http"}; assertTimer(registry, CLIENT_RESPONSE_TIME, timerTags1) .hasCountEqualTo(1) @@ -1283,11 +1285,11 @@ private void checkExpectationsNonExisting(String serverAddress, int connIndex, i .hasTotalAmountGreaterThanOrEqualTo(0); assertCounter(registry, SERVER_ERRORS, summaryTags1).isNull(); - timerTags1 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri, METHOD, "GET", STATUS, "404"}; - timerTags2 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri, METHOD, "GET"}; - String[] timerTags3 = new String[] {REMOTE_ADDRESS, serverAddress, STATUS, "SUCCESS"}; - summaryTags1 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri}; - String[] summaryTags2 = new String[] {REMOTE_ADDRESS, serverAddress, URI, "http"}; + timerTags1 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri, METHOD, "GET", STATUS, "404"}; + timerTags2 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri, METHOD, "GET"}; + String[] timerTags3 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, STATUS, "SUCCESS"}; + summaryTags1 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri}; + String[] summaryTags2 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, "http"}; assertTimer(registry, CLIENT_RESPONSE_TIME, timerTags1) .hasCountEqualTo(index) @@ -1334,11 +1336,11 @@ private void checkExpectationsBadRequest(String serverAddress, boolean checkTls) .hasTotalAmountGreaterThanOrEqualTo(0); assertCounter(registry, SERVER_ERRORS, summaryTags1).isNull(); - timerTags1 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri, METHOD, "GET", STATUS, "431"}; - String[] timerTags2 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri, METHOD, "GET"}; - String[] timerTags3 = new String[] {REMOTE_ADDRESS, serverAddress, STATUS, "SUCCESS"}; - summaryTags1 = new String[] {REMOTE_ADDRESS, serverAddress, URI, uri}; - String[] summaryTags2 = new String[] {REMOTE_ADDRESS, serverAddress, URI, "http"}; + timerTags1 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri, METHOD, "GET", STATUS, "431"}; + String[] timerTags2 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri, METHOD, "GET"}; + String[] timerTags3 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, STATUS, "SUCCESS"}; + summaryTags1 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, uri}; + String[] summaryTags2 = new String[] {REMOTE_ADDRESS, serverAddress, PROXY_ADDRESS, NA, URI, "http"}; assertTimer(registry, CLIENT_RESPONSE_TIME, timerTags1) .hasCountEqualTo(1)