/reactor-netty-http/src/main/java/reactor/netty/http/MicrometerHttpMetricsRecorder.java
https://github.com/reactor/reactor-netty · Java · 126 lines · 86 code · 19 blank · 21 comment · 6 complexity · 67fef6a24075c5ae9c5ff57c1d3ad245 MD5 · raw file
- /*
- * Copyright (c) 2011-Present 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.
- * You may obtain a copy of the License at
- *
- * https://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.
- */
- package reactor.netty.http;
- import io.micrometer.core.instrument.Counter;
- import io.micrometer.core.instrument.DistributionSummary;
- import io.micrometer.core.instrument.Timer;
- import io.netty.util.internal.PlatformDependent;
- import reactor.netty.Metrics;
- import reactor.netty.channel.MeterKey;
- import reactor.netty.channel.MicrometerChannelMetricsRecorder;
- import java.net.SocketAddress;
- import java.util.concurrent.ConcurrentMap;
- import static reactor.netty.Metrics.DATA_RECEIVED;
- import static reactor.netty.Metrics.DATA_RECEIVED_TIME;
- import static reactor.netty.Metrics.DATA_SENT;
- import static reactor.netty.Metrics.DATA_SENT_TIME;
- import static reactor.netty.Metrics.ERRORS;
- import static reactor.netty.Metrics.REGISTRY;
- import static reactor.netty.Metrics.REMOTE_ADDRESS;
- import static reactor.netty.Metrics.RESPONSE_TIME;
- import static reactor.netty.Metrics.URI;
- /**
- * An {@link HttpMetricsRecorder} implementation for integration with Micrometer.
- *
- * @author Violeta Georgieva
- * @since 0.9
- */
- public class MicrometerHttpMetricsRecorder extends MicrometerChannelMetricsRecorder implements HttpMetricsRecorder {
- protected final Timer.Builder dataReceivedTimeBuilder;
- protected final ConcurrentMap<MeterKey, Timer> dataReceivedTimeCache = PlatformDependent.newConcurrentHashMap();
- protected final Timer.Builder dataSentTimeBuilder;
- protected final ConcurrentMap<MeterKey, Timer> dataSentTimeCache = PlatformDependent.newConcurrentHashMap();
- protected final Timer.Builder responseTimeBuilder;
- protected final ConcurrentMap<MeterKey, Timer> responseTimeCache = PlatformDependent.newConcurrentHashMap();
- protected final DistributionSummary.Builder dataReceivedBuilder;
- protected final ConcurrentMap<MeterKey, DistributionSummary> dataReceivedCache = PlatformDependent.newConcurrentHashMap();
- protected final DistributionSummary.Builder dataSentBuilder;
- protected final ConcurrentMap<MeterKey, DistributionSummary> dataSentCache = PlatformDependent.newConcurrentHashMap();
- protected final Counter.Builder errorsBuilder;
- protected final ConcurrentMap<MeterKey, Counter> errorsCache = PlatformDependent.newConcurrentHashMap();
- protected MicrometerHttpMetricsRecorder(String name, String protocol) {
- super(name, protocol);
- this.dataReceivedTimeBuilder =
- Timer.builder(name + DATA_RECEIVED_TIME)
- .description("Time spent in consuming incoming data");
- this.dataSentTimeBuilder =
- Timer.builder(name + DATA_SENT_TIME)
- .description("Time spent in sending outgoing data");
- this.responseTimeBuilder =
- Timer.builder(name + RESPONSE_TIME)
- .description("Total time for the request/response");
- this.dataReceivedBuilder =
- DistributionSummary.builder(name + DATA_RECEIVED)
- .baseUnit("bytes")
- .description("Amount of the data received, in bytes");
- this.dataSentBuilder =
- DistributionSummary.builder(name + DATA_SENT)
- .baseUnit("bytes")
- .description("Amount of the data sent, in bytes");
- this.errorsBuilder =
- Counter.builder(name + ERRORS)
- .description("Number of errors that occurred");
- }
- @Override
- public void recordDataReceived(SocketAddress remoteAddress, String uri, long bytes) {
- String address = Metrics.formatSocketAddress(remoteAddress);
- DistributionSummary dataReceived = dataReceivedCache.computeIfAbsent(new MeterKey(uri, address, null, null),
- key -> filter(dataReceivedBuilder.tags(REMOTE_ADDRESS, address, URI, uri)
- .register(REGISTRY)));
- if (dataReceived != null) {
- dataReceived.record(bytes);
- }
- }
- @Override
- public void recordDataSent(SocketAddress remoteAddress, String uri, long bytes) {
- String address = Metrics.formatSocketAddress(remoteAddress);
- DistributionSummary dataSent = dataSentCache.computeIfAbsent(new MeterKey(uri, address, null, null),
- key -> filter(dataSentBuilder.tags(REMOTE_ADDRESS, address, URI, uri)
- .register(REGISTRY)));
- if (dataSent != null) {
- dataSent.record(bytes);
- }
- }
- @Override
- public void incrementErrorsCount(SocketAddress remoteAddress, String uri) {
- String address = Metrics.formatSocketAddress(remoteAddress);
- Counter errors = errorsCache.computeIfAbsent(new MeterKey(uri, address, null, null),
- key -> filter(errorsBuilder.tags(REMOTE_ADDRESS, address, URI, uri)
- .register(REGISTRY)));
- if (errors != null) {
- errors.increment();
- }
- }
- }