-
Notifications
You must be signed in to change notification settings - Fork 691
Description
The implementation of MicrometerHttpClientMetricsRecorder.recordDataReceivedTime accepts null values for various arguments:
void recordDataReceivedTime(SocketAddress remoteAddress, @Nullable String proxyAddress, String uri, String method, String status, Duration time) {
String address = formatSocketAddress(remoteAddress);
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(), proxyAddress,
HttpClientMeters.DataReceivedTimeTags.URI.asString(), uri,
HttpClientMeters.DataReceivedTimeTags.METHOD.asString(), method,
HttpClientMeters.DataReceivedTimeTags.STATUS.asString(), status)
.register(REGISTRY)));
if (dataReceivedTime != null) {
dataReceivedTime.record(time);
}
}
eg. remoteAddress (-> address), ...
but fails when building the tags of it - as ImmutableTag does not allow null values.
ending up in warning logs like:
2025-08-20 12:14:49.471 UTC WARN [reactor-http-epoll-2] AbstractHttpClientMetricsHandler: [4c73c666-80, L:/100.126.16.238:35740 - R:automation-server.srv.plsrv.prod2.dtp.internal.dynatrace.com/10.178.249.144:443] Exception caught while recording metrics.
java.lang.NullPointerException: null
at java.base/java.util.Objects.requireNonNull(Unknown Source)
at io.micrometer.core.instrument.ImmutableTag.<init>(ImmutableTag.java:37)
at io.micrometer.core.instrument.Tag.of(Tag.java:31)
at io.micrometer.core.instrument.Tags.of(Tags.java:367)
at io.micrometer.core.instrument.AbstractTimerBuilder.tags(AbstractTimerBuilder.java:60)
at io.micrometer.core.instrument.Timer$Builder.tags(Timer.java:362)
at reactor.netty.http.client.MicrometerHttpClientMetricsRecorder.lambda$recordDataSentTime$1(MicrometerHttpClientMetricsRecorder.java:110)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(Unknown Source)
at reactor.netty.internal.util.MapUtils.computeIfAbsent(MapUtils.java:63)
at reactor.netty.http.client.MicrometerHttpClientMetricsRecorder.recordDataSentTime(MicrometerHttpClientMetricsRecorder.java:108)
at reactor.netty.http.client.MicrometerHttpClientMetricsRecorder.recordDataSentTime(MicrometerHttpClientMetricsRecorder.java:97)
at reactor.netty.http.client.AbstractHttpClientMetricsHandler.recordWrite(AbstractHttpClientMetricsHandler.java:243)
at reactor.netty.http.client.AbstractHttpClientMetricsHandler.lambda$write$0(AbstractHttpClientMetricsHandler.java:115)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:603)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:570)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:505)
at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:649)
at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:638)
at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:118)
at io.netty.util.internal.PromiseNotificationUtil.trySuccess(PromiseNotificationUtil.java:48)
at io.netty.channel.DelegatingChannelPromiseNotifier.operationComplete(DelegatingChannelPromiseNotifier.java:52)
at io.netty.channel.DelegatingChannelPromiseNotifier.operationComplete(DelegatingChannelPromiseNotifier.java:31)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:603)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:570)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:505)
at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:649)
at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:638)
at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:118)
at io.netty.util.internal.PromiseNotificationUtil.trySuccess(PromiseNotificationUtil.java:48)
at io.netty.channel.ChannelOutboundBuffer.safeSuccess(ChannelOutboundBuffer.java:748)
at io.netty.channel.ChannelOutboundBuffer.remove(ChannelOutboundBuffer.java:303)
at io.netty.channel.ChannelOutboundBuffer.removeBytes(ChannelOutboundBuffer.java:383)
at io.netty.channel.epoll.AbstractEpollChannel.doWriteBytes(AbstractEpollChannel.java:364)
at io.netty.channel.epoll.AbstractEpollStreamChannel.writeBytes(AbstractEpollStreamChannel.java:262)
at io.netty.channel.epoll.AbstractEpollStreamChannel.doWriteSingle(AbstractEpollStreamChannel.java:473)
at io.netty.channel.epoll.AbstractEpollStreamChannel.doWrite(AbstractEpollStreamChannel.java:431)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:929)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.flush0(AbstractEpollChannel.java:557)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:893)
at io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1319)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:935)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:921)
at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:907)
at io.netty.handler.ssl.SslHandler.forceFlush(SslHandler.java:2304)
at io.netty.handler.ssl.SslHandler.wrapAndFlush(SslHandler.java:831)
at io.netty.handler.ssl.SslHandler.flush(SslHandler.java:808)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:941)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:921)
at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:907)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.flush(CombinedChannelDuplexHandler.java:531)
Expected Behavior
Method can deal with 'null' arguments
Actual Behavior
'null' arguments end up in 'null' tag values that end up in NullPointerExceptions in ImmutableTag
Steps to Reproduce
any null argument when calling the method.
Possible Solution
use NA similar as it's done for the proxyAddress
Your Environment
- Reactor version(s) used:
- Other relevant libraries versions (eg.
netty, ...): reactor-netty-http-1.2.8 - JVM version (
java -version): Java 21.0.1 - OS and version (eg.
uname -a): linux
Metadata
Metadata
Assignees
Labels
type/bugA general bugA general bug