From 6dc905201f8f240891f111f9451dd1179cee0d51 Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Tue, 26 Sep 2023 17:37:51 -0400 Subject: [PATCH 01/10] Add request size metrics channel --- dialogue-clients/metrics.md | 1 + .../core/RequestSizeMetricsChannel.java | 141 ++++++++++++++++++ .../main/metrics/dialogue-core-metrics.yml | 4 + .../core/RequestSizeMetricsChannelTest.java | 119 +++++++++++++++ 4 files changed, 265 insertions(+) create mode 100644 dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java create mode 100644 dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java diff --git a/dialogue-clients/metrics.md b/dialogue-clients/metrics.md index 98b3ab547..518563b4d 100644 --- a/dialogue-clients/metrics.md +++ b/dialogue-clients/metrics.md @@ -71,6 +71,7 @@ Dialogue-specific metrics that are not necessarily applicable to other client im - `dialogue.client.request.queued.time` tagged `channel-name` (timer): Time spent waiting in the queue before execution. - `dialogue.client.request.endpoint.queued.time` tagged `channel-name`, `service-name`, `endpoint` (timer): Time spent waiting in the queue before execution on a specific endpoint due to server QoS. - `dialogue.client.request.sticky.queued.time` tagged `channel-name` (timer): Time spent waiting in the sticky queue before execution attempt. +- `dialogue.client.requests.size` tagged `service-name`, `endpoint` (histogram): Size of requests - `dialogue.client.create` tagged `client-name`, `client-type` (meter): Marked every time a new client is created. ### dialogue.concurrencylimiter diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java new file mode 100644 index 000000000..e444ab658 --- /dev/null +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java @@ -0,0 +1,141 @@ +/* + * (c) Copyright 2023 Palantir Technologies Inc. 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 + * + * 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. + */ + +package com.palantir.dialogue.core; + +import com.codahale.metrics.Histogram; +import com.google.common.util.concurrent.ListenableFuture; +import com.palantir.conjure.java.client.config.ClientConfiguration; +import com.palantir.dialogue.Endpoint; +import com.palantir.dialogue.EndpointChannel; +import com.palantir.dialogue.Request; +import com.palantir.dialogue.RequestBody; +import com.palantir.dialogue.Response; +import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Optional; + +final class RequestSizeMetricsChannel implements EndpointChannel { + private final EndpointChannel delegate; + private final Histogram requestSize; + + static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpoint) { + ClientConfiguration clientConf = cf.clientConf(); + return new RequestSizeMetricsChannel(channel, endpoint, clientConf.taggedMetricRegistry()); + } + + RequestSizeMetricsChannel(EndpointChannel delegate, Endpoint endpoint, TaggedMetricRegistry registry) { + this.delegate = delegate; + DialogueClientMetrics dialogueClientMetrics = DialogueClientMetrics.of(registry); + this.requestSize = dialogueClientMetrics + .requestsSize() + .serviceName(endpoint.serviceName()) + .endpoint(endpoint.endpointName()) + .build(); + } + + @Override + public ListenableFuture execute(Request request) { + Request augmentedRequest = wrap(request); + return delegate.execute(augmentedRequest); + } + + private Request wrap(Request request) { + Optional body = request.body(); + if (body.isEmpty()) { + // No need to record empty bodies + return request; + } + + return Request.builder() + .from(request) + .body(new RequestSizeRecordingRequestBody(body.get(), this.requestSize)) + .build(); + } + + private class RequestSizeRecordingRequestBody implements RequestBody { + private final RequestBody delegate; + private final Histogram size; + private SizeTrackingOutputStream out; + + RequestSizeRecordingRequestBody(RequestBody requestBody, Histogram size) { + this.delegate = requestBody; + this.size = size; + // we'll never actually write to this output stream, but is safe to perform all operations on in case a + // client closes without calling write. + this.out = new SizeTrackingOutputStream(OutputStream.nullOutputStream(), size); + } + + @Override + public void writeTo(OutputStream output) throws IOException { + out = new SizeTrackingOutputStream(output, size); + delegate.writeTo(out); + } + + @Override + public String contentType() { + return delegate.contentType(); + } + + @Override + public boolean repeatable() { + return delegate.repeatable(); + } + + @Override + public void close() { + try { + out.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + delegate.close(); + } + + /** + * {@link SizeTrackingOutputStream} records the total number of bytes written to the output stream. + */ + private final class SizeTrackingOutputStream extends FilterOutputStream { + private final Histogram size; + private long writes = 0; + + SizeTrackingOutputStream(OutputStream delegate, Histogram size) { + super(delegate); + this.size = size; + } + + @Override + public void write(byte[] buffer, int off, int len) throws IOException { + writes += len; + out.write(buffer, off, len); + } + + @Override + public void write(int value) throws IOException { + writes += 1; + out.write(value); + } + + @Override + public void close() throws IOException { + this.size.update(writes); + super.close(); + } + } + } +} diff --git a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml index 40cebfb6f..45cd910ef 100644 --- a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml +++ b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml @@ -56,6 +56,10 @@ namespaces: type: timer tags: [ channel-name ] docs: Time spent waiting in the sticky queue before execution attempt. + requests.size: + type: histogram + tags: [service-name, endpoint] + docs: Size of requests # Note: the 'dialogue.client.create' metric is also defined in the apache metrics. create: type: meter diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java new file mode 100644 index 000000000..1a814d114 --- /dev/null +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java @@ -0,0 +1,119 @@ +/* + * (c) Copyright 2023 Palantir Technologies Inc. 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 + * + * 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. + */ + +package com.palantir.dialogue.core; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.codahale.metrics.Snapshot; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.palantir.conjure.java.client.config.ClientConfiguration; +import com.palantir.dialogue.EndpointChannel; +import com.palantir.dialogue.Request; +import com.palantir.dialogue.RequestBody; +import com.palantir.dialogue.Response; +import com.palantir.dialogue.TestConfigurations; +import com.palantir.dialogue.TestEndpoint; +import com.palantir.dialogue.TestResponse; +import com.palantir.tritium.metrics.registry.DefaultTaggedMetricRegistry; +import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.OptionalLong; +import java.util.concurrent.ExecutionException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class RequestSizeMetricsChannelTest { + @Mock + DialogueChannelFactory factory; + + @Test + public void records_request_size_metrics() throws ExecutionException, InterruptedException { + TaggedMetricRegistry registry = DefaultTaggedMetricRegistry.getDefault(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] expected = "test request body".getBytes(StandardCharsets.UTF_8); + Request request = Request.builder() + .body(new RequestBody() { + @Override + public void writeTo(OutputStream output) throws IOException { + output.write(expected); + } + + @Override + public String contentType() { + return "text/plain"; + } + + @Override + public boolean repeatable() { + return true; + } + + @Override + public OptionalLong contentLength() { + return OptionalLong.of(expected.length); + } + + @Override + public void close() {} + }) + .build(); + + EndpointChannel channel = RequestSizeMetricsChannel.create( + config(ClientConfiguration.builder() + .from(TestConfigurations.create("https://foo:10001")) + .taggedMetricRegistry(registry) + .build()), + r -> { + try { + RequestBody body = r.body().get(); + body.writeTo(baos); + body.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return Futures.immediateFuture(new TestResponse().code(200)); + }, + TestEndpoint.GET); + ListenableFuture response = channel.execute(request); + + assertThat(response.get().code()).isEqualTo(200); + Snapshot snapshot = DialogueClientMetrics.of(registry) + .requestsSize() + .serviceName("service") + .endpoint("endpoint") + .build() + .getSnapshot(); + assertThat(snapshot.size()).isEqualTo(1); + assertThat(snapshot.get99thPercentile()).isEqualTo(expected.length); + } + + private ImmutableConfig config(ClientConfiguration rawConfig) { + return ImmutableConfig.builder() + .channelName("channelName") + .channelFactory(factory) + .rawConfig(rawConfig) + .build(); + } +} From 05829925247d97bf5b0eba907faea0f6fce930b8 Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Thu, 28 Sep 2023 12:10:58 -0400 Subject: [PATCH 02/10] Don't throw on close exception --- .../palantir/dialogue/core/RequestSizeMetricsChannel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java index e444ab658..a7c49d448 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java @@ -24,6 +24,8 @@ import com.palantir.dialogue.Request; import com.palantir.dialogue.RequestBody; import com.palantir.dialogue.Response; +import com.palantir.logsafe.logger.SafeLogger; +import com.palantir.logsafe.logger.SafeLoggerFactory; import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; import java.io.FilterOutputStream; import java.io.IOException; @@ -31,6 +33,7 @@ import java.util.Optional; final class RequestSizeMetricsChannel implements EndpointChannel { + private static final SafeLogger log = SafeLoggerFactory.get(RequestSizeMetricsChannel.class); private final EndpointChannel delegate; private final Histogram requestSize; @@ -102,7 +105,7 @@ public void close() { try { out.close(); } catch (IOException e) { - throw new RuntimeException(e); + log.warn("Failed to close tracking output stream", e); } delegate.close(); } From 28dcb36697d61467c2d5f1a4f702d6bc9538a718 Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Thu, 28 Sep 2023 15:11:46 -0400 Subject: [PATCH 03/10] PR feedback --- dialogue-clients/metrics.md | 2 +- .../core/RequestSizeMetricsChannel.java | 69 +++++-------------- .../main/metrics/dialogue-core-metrics.yml | 2 +- 3 files changed, 20 insertions(+), 53 deletions(-) diff --git a/dialogue-clients/metrics.md b/dialogue-clients/metrics.md index 518563b4d..78f66dde9 100644 --- a/dialogue-clients/metrics.md +++ b/dialogue-clients/metrics.md @@ -71,7 +71,7 @@ Dialogue-specific metrics that are not necessarily applicable to other client im - `dialogue.client.request.queued.time` tagged `channel-name` (timer): Time spent waiting in the queue before execution. - `dialogue.client.request.endpoint.queued.time` tagged `channel-name`, `service-name`, `endpoint` (timer): Time spent waiting in the queue before execution on a specific endpoint due to server QoS. - `dialogue.client.request.sticky.queued.time` tagged `channel-name` (timer): Time spent waiting in the sticky queue before execution attempt. -- `dialogue.client.requests.size` tagged `service-name`, `endpoint` (histogram): Size of requests +- `dialogue.client.requests.size` tagged `channel-name`, `service-name`, `endpoint`, `retryable` (histogram): Size of requests - `dialogue.client.create` tagged `client-name`, `client-type` (meter): Marked every time a new client is created. ### dialogue.concurrencylimiter diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java index a7c49d448..b6cf07784 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java @@ -17,6 +17,7 @@ package com.palantir.dialogue.core; import com.codahale.metrics.Histogram; +import com.google.common.io.CountingOutputStream; import com.google.common.util.concurrent.ListenableFuture; import com.palantir.conjure.java.client.config.ClientConfiguration; import com.palantir.dialogue.Endpoint; @@ -27,7 +28,6 @@ import com.palantir.logsafe.logger.SafeLogger; import com.palantir.logsafe.logger.SafeLoggerFactory; import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; -import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Optional; @@ -35,21 +35,25 @@ final class RequestSizeMetricsChannel implements EndpointChannel { private static final SafeLogger log = SafeLoggerFactory.get(RequestSizeMetricsChannel.class); private final EndpointChannel delegate; - private final Histogram requestSize; + private final Histogram retryableRequestSize; + private final Histogram nonretryableRequestSize; static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpoint) { ClientConfiguration clientConf = cf.clientConf(); - return new RequestSizeMetricsChannel(channel, endpoint, clientConf.taggedMetricRegistry()); + return new RequestSizeMetricsChannel(channel, cf.channelName(), endpoint, clientConf.taggedMetricRegistry()); } - RequestSizeMetricsChannel(EndpointChannel delegate, Endpoint endpoint, TaggedMetricRegistry registry) { + RequestSizeMetricsChannel( + EndpointChannel delegate, String channelName, Endpoint endpoint, TaggedMetricRegistry registry) { this.delegate = delegate; DialogueClientMetrics dialogueClientMetrics = DialogueClientMetrics.of(registry); - this.requestSize = dialogueClientMetrics + DialogueClientMetrics.RequestsSizeBuilderRetryableStage requestSize = dialogueClientMetrics .requestsSize() + .channelName(channelName) .serviceName(endpoint.serviceName()) - .endpoint(endpoint.endpointName()) - .build(); + .endpoint(endpoint.endpointName()); + this.retryableRequestSize = requestSize.retryable("true").build(); + this.nonretryableRequestSize = requestSize.retryable("false").build(); } @Override @@ -64,30 +68,29 @@ private Request wrap(Request request) { // No need to record empty bodies return request; } + Histogram requestSizeHistogram = + body.get().repeatable() ? this.retryableRequestSize : this.nonretryableRequestSize; return Request.builder() .from(request) - .body(new RequestSizeRecordingRequestBody(body.get(), this.requestSize)) + .body(new RequestSizeRecordingRequestBody(body.get(), requestSizeHistogram)) .build(); } - private class RequestSizeRecordingRequestBody implements RequestBody { + private static class RequestSizeRecordingRequestBody implements RequestBody { private final RequestBody delegate; private final Histogram size; - private SizeTrackingOutputStream out; RequestSizeRecordingRequestBody(RequestBody requestBody, Histogram size) { this.delegate = requestBody; this.size = size; - // we'll never actually write to this output stream, but is safe to perform all operations on in case a - // client closes without calling write. - this.out = new SizeTrackingOutputStream(OutputStream.nullOutputStream(), size); } @Override public void writeTo(OutputStream output) throws IOException { - out = new SizeTrackingOutputStream(output, size); - delegate.writeTo(out); + CountingOutputStream countingOut = new CountingOutputStream(output); + delegate.writeTo(countingOut); + size.update(countingOut.getCount()); } @Override @@ -102,43 +105,7 @@ public boolean repeatable() { @Override public void close() { - try { - out.close(); - } catch (IOException e) { - log.warn("Failed to close tracking output stream", e); - } delegate.close(); } - - /** - * {@link SizeTrackingOutputStream} records the total number of bytes written to the output stream. - */ - private final class SizeTrackingOutputStream extends FilterOutputStream { - private final Histogram size; - private long writes = 0; - - SizeTrackingOutputStream(OutputStream delegate, Histogram size) { - super(delegate); - this.size = size; - } - - @Override - public void write(byte[] buffer, int off, int len) throws IOException { - writes += len; - out.write(buffer, off, len); - } - - @Override - public void write(int value) throws IOException { - writes += 1; - out.write(value); - } - - @Override - public void close() throws IOException { - this.size.update(writes); - super.close(); - } - } } } diff --git a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml index 45cd910ef..1d9bf5633 100644 --- a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml +++ b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml @@ -58,7 +58,7 @@ namespaces: docs: Time spent waiting in the sticky queue before execution attempt. requests.size: type: histogram - tags: [service-name, endpoint] + tags: [channel-name, service-name, endpoint, retryable] docs: Size of requests # Note: the 'dialogue.client.create' metric is also defined in the apache metrics. create: From 4084d82a69b62a812bdf58eabf22a0784c4d5c1f Mon Sep 17 00:00:00 2001 From: svc-changelog Date: Thu, 28 Sep 2023 19:12:43 +0000 Subject: [PATCH 04/10] Add generated changelog entries --- changelog/@unreleased/pr-2023.v2.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelog/@unreleased/pr-2023.v2.yml diff --git a/changelog/@unreleased/pr-2023.v2.yml b/changelog/@unreleased/pr-2023.v2.yml new file mode 100644 index 000000000..2bf5988c3 --- /dev/null +++ b/changelog/@unreleased/pr-2023.v2.yml @@ -0,0 +1,6 @@ +type: feature +feature: + description: Add a request size metric channel, which records the size of payloads + written by the client. + links: + - https://github.com/palantir/dialogue/pull/2023 From 638a1a2abb2cf8524fd50f16cd63ea6f076a0b47 Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Thu, 28 Sep 2023 15:23:35 -0400 Subject: [PATCH 05/10] fix checks and tests --- .../dialogue/core/RequestSizeMetricsChannel.java | 15 +++++++++++---- .../core/RequestSizeMetricsChannelTest.java | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java index b6cf07784..b7c1a0c58 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java @@ -47,13 +47,20 @@ static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpo EndpointChannel delegate, String channelName, Endpoint endpoint, TaggedMetricRegistry registry) { this.delegate = delegate; DialogueClientMetrics dialogueClientMetrics = DialogueClientMetrics.of(registry); - DialogueClientMetrics.RequestsSizeBuilderRetryableStage requestSize = dialogueClientMetrics + this.retryableRequestSize = dialogueClientMetrics .requestsSize() .channelName(channelName) .serviceName(endpoint.serviceName()) - .endpoint(endpoint.endpointName()); - this.retryableRequestSize = requestSize.retryable("true").build(); - this.nonretryableRequestSize = requestSize.retryable("false").build(); + .endpoint(endpoint.endpointName()) + .retryable("true") + .build(); + this.nonretryableRequestSize = dialogueClientMetrics + .requestsSize() + .channelName(channelName) + .serviceName(endpoint.serviceName()) + .endpoint(endpoint.endpointName()) + .retryable("false") + .build(); } @Override diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java index 1a814d114..ff03e20d9 100644 --- a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java @@ -101,8 +101,10 @@ public void close() {} assertThat(response.get().code()).isEqualTo(200); Snapshot snapshot = DialogueClientMetrics.of(registry) .requestsSize() + .channelName("channelName") .serviceName("service") .endpoint("endpoint") + .retryable("true") .build() .getSnapshot(); assertThat(snapshot.size()).isEqualTo(1); From 880b94cb0b2c191745a95289471564c12866c32e Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Mon, 2 Oct 2023 10:50:50 -0400 Subject: [PATCH 06/10] PR feedback --- .../dialogue/core/DialogueChannel.java | 6 +- .../core/RequestSizeMetricsChannel.java | 26 ++++--- .../core/RequestSizeMetricsChannelTest.java | 74 ++++++++++++++++++- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/DialogueChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/DialogueChannel.java index fe06676d2..e39d2a8dd 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/DialogueChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/DialogueChannel.java @@ -92,6 +92,7 @@ public Builder clientConfiguration(ClientConfiguration value) { /** * Please use {@link #factory(DialogueChannelFactory)}. + * * @deprecated prefer {@link #factory(DialogueChannelFactory)} */ @Deprecated @@ -185,6 +186,7 @@ public DialogueChannel build() { channel = new RangeAcceptsIdentityEncodingChannel(channel); channel = ContentEncodingChannel.of(channel, endpoint); channel = TracedChannel.create(cf, channel, endpoint); + channel = RequestSizeMetricsChannel.create(cf, channel, endpoint); if (ChannelToEndpointChannel.isConstant(endpoint)) { // Avoid producing metrics for non-constant endpoints which may produce // high cardinality. @@ -207,7 +209,9 @@ public DialogueChannel build() { return new DialogueChannel(cf, channelFactory, stickyChannelSupplier); } - /** Does *not* do any clever live-reloading. */ + /** + * Does *not* do any clever live-reloading. + */ @CheckReturnValue public Channel buildNonLiveReloading() { return build(); diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java index b7c1a0c58..c4115f582 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java @@ -17,6 +17,7 @@ package com.palantir.dialogue.core; import com.codahale.metrics.Histogram; +import com.google.common.base.Suppliers; import com.google.common.io.CountingOutputStream; import com.google.common.util.concurrent.ListenableFuture; import com.palantir.conjure.java.client.config.ClientConfiguration; @@ -31,12 +32,15 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Optional; +import java.util.function.Supplier; final class RequestSizeMetricsChannel implements EndpointChannel { private static final SafeLogger log = SafeLoggerFactory.get(RequestSizeMetricsChannel.class); + // MIN_REPORTED_REQUEST_SIZE filters recording small requests to reduce metric cardinality + private static final long MIN_REPORTED_REQUEST_SIZE = 1 << 20; private final EndpointChannel delegate; - private final Histogram retryableRequestSize; - private final Histogram nonretryableRequestSize; + private final Supplier retryableRequestSize; + private final Supplier nonretryableRequestSize; static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpoint) { ClientConfiguration clientConf = cf.clientConf(); @@ -47,20 +51,20 @@ static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpo EndpointChannel delegate, String channelName, Endpoint endpoint, TaggedMetricRegistry registry) { this.delegate = delegate; DialogueClientMetrics dialogueClientMetrics = DialogueClientMetrics.of(registry); - this.retryableRequestSize = dialogueClientMetrics + this.retryableRequestSize = Suppliers.memoize(() -> dialogueClientMetrics .requestsSize() .channelName(channelName) .serviceName(endpoint.serviceName()) .endpoint(endpoint.endpointName()) .retryable("true") - .build(); - this.nonretryableRequestSize = dialogueClientMetrics + .build()); + this.nonretryableRequestSize = Suppliers.memoize(() -> dialogueClientMetrics .requestsSize() .channelName(channelName) .serviceName(endpoint.serviceName()) .endpoint(endpoint.endpointName()) .retryable("false") - .build(); + .build()); } @Override @@ -75,7 +79,7 @@ private Request wrap(Request request) { // No need to record empty bodies return request; } - Histogram requestSizeHistogram = + Supplier requestSizeHistogram = body.get().repeatable() ? this.retryableRequestSize : this.nonretryableRequestSize; return Request.builder() @@ -86,9 +90,9 @@ private Request wrap(Request request) { private static class RequestSizeRecordingRequestBody implements RequestBody { private final RequestBody delegate; - private final Histogram size; + private final Supplier size; - RequestSizeRecordingRequestBody(RequestBody requestBody, Histogram size) { + RequestSizeRecordingRequestBody(RequestBody requestBody, Supplier size) { this.delegate = requestBody; this.size = size; } @@ -97,7 +101,9 @@ private static class RequestSizeRecordingRequestBody implements RequestBody { public void writeTo(OutputStream output) throws IOException { CountingOutputStream countingOut = new CountingOutputStream(output); delegate.writeTo(countingOut); - size.update(countingOut.getCount()); + if (countingOut.getCount() > MIN_REPORTED_REQUEST_SIZE) { + size.get().update(countingOut.getCount()); + } } @Override diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java index ff03e20d9..71e0fb4c8 100644 --- a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java @@ -30,11 +30,13 @@ import com.palantir.dialogue.TestEndpoint; import com.palantir.dialogue.TestResponse; import com.palantir.tritium.metrics.registry.DefaultTaggedMetricRegistry; +import com.palantir.tritium.metrics.registry.MetricName; import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.OptionalLong; import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; @@ -44,6 +46,10 @@ @ExtendWith(MockitoExtension.class) public class RequestSizeMetricsChannelTest { + private static final String JAVA_VERSION = System.getProperty("java.version", "unknown"); + private static final String LIBRARY_VERSION = + Objects.requireNonNullElse(DialogueClientMetrics.class.getPackage().getImplementationVersion(), "unknown"); + @Mock DialogueChannelFactory factory; @@ -52,7 +58,8 @@ public void records_request_size_metrics() throws ExecutionException, Interrupte TaggedMetricRegistry registry = DefaultTaggedMetricRegistry.getDefault(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] expected = "test request body".getBytes(StandardCharsets.UTF_8); + int recordableRequestSize = 2 << 20; + byte[] expected = "a".repeat(recordableRequestSize).getBytes(StandardCharsets.UTF_8); Request request = Request.builder() .body(new RequestBody() { @Override @@ -111,6 +118,71 @@ public void close() {} assertThat(snapshot.get99thPercentile()).isEqualTo(expected.length); } + @Test + public void small_request_not_recorded() throws ExecutionException, InterruptedException { + TaggedMetricRegistry registry = DefaultTaggedMetricRegistry.getDefault(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] expected = "test request body".getBytes(StandardCharsets.UTF_8); + Request request = Request.builder() + .body(new RequestBody() { + @Override + public void writeTo(OutputStream output) throws IOException { + output.write(expected); + } + + @Override + public String contentType() { + return "text/plain"; + } + + @Override + public boolean repeatable() { + return true; + } + + @Override + public OptionalLong contentLength() { + return OptionalLong.of(expected.length); + } + + @Override + public void close() {} + }) + .build(); + + EndpointChannel channel = RequestSizeMetricsChannel.create( + config(ClientConfiguration.builder() + .from(TestConfigurations.create("https://foo:10001")) + .taggedMetricRegistry(registry) + .build()), + r -> { + try { + RequestBody body = r.body().get(); + body.writeTo(baos); + body.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return Futures.immediateFuture(new TestResponse().code(200)); + }, + TestEndpoint.GET); + ListenableFuture response = channel.execute(request); + + assertThat(response.get().code()).isEqualTo(200); + MetricName metricName = MetricName.builder() + .safeName("dialogue.client.requests.size") + .putSafeTags("channel-name", "channelName") + .putSafeTags("service-name", "service") + .putSafeTags("endpoint", "endpoint") + .putSafeTags("retryable", "true") + .putSafeTags("libraryName", "dialogue") + .putSafeTags("libraryVersion", LIBRARY_VERSION) + .putSafeTags("javaVersion", JAVA_VERSION) + .build(); + assertThat(registry.remove(metricName)).isEmpty(); + } + private ImmutableConfig config(ClientConfiguration rawConfig) { return ImmutableConfig.builder() .channelName("channelName") From 1d4f94c96e3dec931e281049a11ae81037d7a7fb Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Mon, 2 Oct 2023 11:28:23 -0400 Subject: [PATCH 07/10] Update tests --- .../core/RequestSizeMetricsChannelTest.java | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java index 71e0fb4c8..8d4b517e3 100644 --- a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java @@ -36,7 +36,6 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import java.util.Objects; import java.util.OptionalLong; import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; @@ -46,10 +45,6 @@ @ExtendWith(MockitoExtension.class) public class RequestSizeMetricsChannelTest { - private static final String JAVA_VERSION = System.getProperty("java.version", "unknown"); - private static final String LIBRARY_VERSION = - Objects.requireNonNullElse(DialogueClientMetrics.class.getPackage().getImplementationVersion(), "unknown"); - @Mock DialogueChannelFactory factory; @@ -88,10 +83,14 @@ public void close() {} .build(); EndpointChannel channel = RequestSizeMetricsChannel.create( - config(ClientConfiguration.builder() - .from(TestConfigurations.create("https://foo:10001")) - .taggedMetricRegistry(registry) - .build()), + ImmutableConfig.builder() + .channelName("channelName") + .channelFactory(factory) + .rawConfig(ClientConfiguration.builder() + .from(TestConfigurations.create("https://foo:10001")) + .taggedMetricRegistry(registry) + .build()) + .build(), r -> { try { RequestBody body = r.body().get(); @@ -152,10 +151,14 @@ public void close() {} .build(); EndpointChannel channel = RequestSizeMetricsChannel.create( - config(ClientConfiguration.builder() - .from(TestConfigurations.create("https://foo:10001")) - .taggedMetricRegistry(registry) - .build()), + ImmutableConfig.builder() + .channelName("smallRequestChannelName") + .channelFactory(factory) + .rawConfig(ClientConfiguration.builder() + .from(TestConfigurations.create("https://foo:10001")) + .taggedMetricRegistry(registry) + .build()) + .build(), r -> { try { RequestBody body = r.body().get(); @@ -170,24 +173,13 @@ public void close() {} ListenableFuture response = channel.execute(request); assertThat(response.get().code()).isEqualTo(200); - MetricName metricName = MetricName.builder() - .safeName("dialogue.client.requests.size") - .putSafeTags("channel-name", "channelName") - .putSafeTags("service-name", "service") - .putSafeTags("endpoint", "endpoint") - .putSafeTags("retryable", "true") - .putSafeTags("libraryName", "dialogue") - .putSafeTags("libraryVersion", LIBRARY_VERSION) - .putSafeTags("javaVersion", JAVA_VERSION) - .build(); + MetricName metricName = DialogueClientMetrics.of(registry) + .requestsSize() + .channelName("smallRequestChannelName") + .serviceName("service") + .endpoint("endpoint") + .retryable("true") + .buildMetricName(); assertThat(registry.remove(metricName)).isEmpty(); } - - private ImmutableConfig config(ClientConfiguration rawConfig) { - return ImmutableConfig.builder() - .channelName("channelName") - .channelFactory(factory) - .rawConfig(rawConfig) - .build(); - } } From bf43b4386f3e2495555be20376a00fb8ad5942d7 Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Tue, 3 Oct 2023 10:49:56 -0400 Subject: [PATCH 08/10] PR feedback --- dialogue-clients/metrics.md | 6 +++- .../core/RequestSizeMetricsChannel.java | 21 +++++++---- .../main/metrics/dialogue-core-metrics.yml | 7 +++- .../core/RequestSizeMetricsChannelTest.java | 36 +++++++++---------- 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/dialogue-clients/metrics.md b/dialogue-clients/metrics.md index 78f66dde9..c8f790a77 100644 --- a/dialogue-clients/metrics.md +++ b/dialogue-clients/metrics.md @@ -71,7 +71,11 @@ Dialogue-specific metrics that are not necessarily applicable to other client im - `dialogue.client.request.queued.time` tagged `channel-name` (timer): Time spent waiting in the queue before execution. - `dialogue.client.request.endpoint.queued.time` tagged `channel-name`, `service-name`, `endpoint` (timer): Time spent waiting in the queue before execution on a specific endpoint due to server QoS. - `dialogue.client.request.sticky.queued.time` tagged `channel-name` (timer): Time spent waiting in the sticky queue before execution attempt. -- `dialogue.client.requests.size` tagged `channel-name`, `service-name`, `endpoint`, `retryable` (histogram): Size of requests +- `dialogue.client.requests.size` (histogram): Size of requests + - `repeatable` values (`true`,`false`) + - `channel-name` + - `service-name` + - `endpoint` - `dialogue.client.create` tagged `client-name`, `client-type` (meter): Marked every time a new client is created. ### dialogue.concurrencylimiter diff --git a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java index c4115f582..3742a70f9 100644 --- a/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java +++ b/dialogue-core/src/main/java/com/palantir/dialogue/core/RequestSizeMetricsChannel.java @@ -26,12 +26,14 @@ import com.palantir.dialogue.Request; import com.palantir.dialogue.RequestBody; import com.palantir.dialogue.Response; +import com.palantir.dialogue.core.DialogueClientMetrics.RequestsSize_Repeatable; import com.palantir.logsafe.logger.SafeLogger; import com.palantir.logsafe.logger.SafeLoggerFactory; import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; import java.io.IOException; import java.io.OutputStream; import java.util.Optional; +import java.util.OptionalLong; import java.util.function.Supplier; final class RequestSizeMetricsChannel implements EndpointChannel { @@ -39,8 +41,8 @@ final class RequestSizeMetricsChannel implements EndpointChannel { // MIN_REPORTED_REQUEST_SIZE filters recording small requests to reduce metric cardinality private static final long MIN_REPORTED_REQUEST_SIZE = 1 << 20; private final EndpointChannel delegate; - private final Supplier retryableRequestSize; - private final Supplier nonretryableRequestSize; + private final Supplier repeatableRequestSize; + private final Supplier unrepeatableRequestSize; static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpoint) { ClientConfiguration clientConf = cf.clientConf(); @@ -51,19 +53,19 @@ static EndpointChannel create(Config cf, EndpointChannel channel, Endpoint endpo EndpointChannel delegate, String channelName, Endpoint endpoint, TaggedMetricRegistry registry) { this.delegate = delegate; DialogueClientMetrics dialogueClientMetrics = DialogueClientMetrics.of(registry); - this.retryableRequestSize = Suppliers.memoize(() -> dialogueClientMetrics + this.repeatableRequestSize = Suppliers.memoize(() -> dialogueClientMetrics .requestsSize() + .repeatable(RequestsSize_Repeatable.TRUE) .channelName(channelName) .serviceName(endpoint.serviceName()) .endpoint(endpoint.endpointName()) - .retryable("true") .build()); - this.nonretryableRequestSize = Suppliers.memoize(() -> dialogueClientMetrics + this.unrepeatableRequestSize = Suppliers.memoize(() -> dialogueClientMetrics .requestsSize() + .repeatable(RequestsSize_Repeatable.FALSE) .channelName(channelName) .serviceName(endpoint.serviceName()) .endpoint(endpoint.endpointName()) - .retryable("false") .build()); } @@ -80,7 +82,7 @@ private Request wrap(Request request) { return request; } Supplier requestSizeHistogram = - body.get().repeatable() ? this.retryableRequestSize : this.nonretryableRequestSize; + body.get().repeatable() ? this.repeatableRequestSize : this.unrepeatableRequestSize; return Request.builder() .from(request) @@ -116,6 +118,11 @@ public boolean repeatable() { return delegate.repeatable(); } + @Override + public OptionalLong contentLength() { + return delegate.contentLength(); + } + @Override public void close() { delegate.close(); diff --git a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml index 1d9bf5633..ba335ec86 100644 --- a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml +++ b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml @@ -58,7 +58,12 @@ namespaces: docs: Time spent waiting in the sticky queue before execution attempt. requests.size: type: histogram - tags: [channel-name, service-name, endpoint, retryable] + tags: + - name: repeatable + values: [ 'true', 'false' ] + - name: channel-name + - name: service-name + - name: endpoint docs: Size of requests # Note: the 'dialogue.client.create' metric is also defined in the apache metrics. create: diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java index 8d4b517e3..452405db1 100644 --- a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat; import com.codahale.metrics.Snapshot; +import com.google.common.io.ByteStreams; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.palantir.conjure.java.client.config.ClientConfiguration; @@ -29,10 +30,10 @@ import com.palantir.dialogue.TestConfigurations; import com.palantir.dialogue.TestEndpoint; import com.palantir.dialogue.TestResponse; +import com.palantir.dialogue.core.DialogueClientMetrics.RequestsSize_Repeatable; import com.palantir.tritium.metrics.registry.DefaultTaggedMetricRegistry; import com.palantir.tritium.metrics.registry.MetricName; import com.palantir.tritium.metrics.registry.TaggedMetricRegistry; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; @@ -40,19 +41,19 @@ import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class RequestSizeMetricsChannelTest { - @Mock - DialogueChannelFactory factory; + + private static final DialogueChannelFactory STUB_FACTORY = _ignored -> { + throw new AssertionError("DialogueChannelFactory should not be used"); + }; @Test public void records_request_size_metrics() throws ExecutionException, InterruptedException { - TaggedMetricRegistry registry = DefaultTaggedMetricRegistry.getDefault(); + TaggedMetricRegistry registry = new DefaultTaggedMetricRegistry(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); int recordableRequestSize = 2 << 20; byte[] expected = "a".repeat(recordableRequestSize).getBytes(StandardCharsets.UTF_8); Request request = Request.builder() @@ -85,17 +86,15 @@ public void close() {} EndpointChannel channel = RequestSizeMetricsChannel.create( ImmutableConfig.builder() .channelName("channelName") - .channelFactory(factory) + .channelFactory(STUB_FACTORY) .rawConfig(ClientConfiguration.builder() .from(TestConfigurations.create("https://foo:10001")) .taggedMetricRegistry(registry) .build()) .build(), r -> { - try { - RequestBody body = r.body().get(); - body.writeTo(baos); - body.close(); + try (RequestBody body = r.body().get()) { + body.writeTo(ByteStreams.nullOutputStream()); } catch (IOException e) { throw new RuntimeException(e); } @@ -107,10 +106,10 @@ public void close() {} assertThat(response.get().code()).isEqualTo(200); Snapshot snapshot = DialogueClientMetrics.of(registry) .requestsSize() + .repeatable(RequestsSize_Repeatable.TRUE) .channelName("channelName") .serviceName("service") .endpoint("endpoint") - .retryable("true") .build() .getSnapshot(); assertThat(snapshot.size()).isEqualTo(1); @@ -119,9 +118,8 @@ public void close() {} @Test public void small_request_not_recorded() throws ExecutionException, InterruptedException { - TaggedMetricRegistry registry = DefaultTaggedMetricRegistry.getDefault(); + TaggedMetricRegistry registry = new DefaultTaggedMetricRegistry(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] expected = "test request body".getBytes(StandardCharsets.UTF_8); Request request = Request.builder() .body(new RequestBody() { @@ -153,17 +151,15 @@ public void close() {} EndpointChannel channel = RequestSizeMetricsChannel.create( ImmutableConfig.builder() .channelName("smallRequestChannelName") - .channelFactory(factory) + .channelFactory(STUB_FACTORY) .rawConfig(ClientConfiguration.builder() .from(TestConfigurations.create("https://foo:10001")) .taggedMetricRegistry(registry) .build()) .build(), r -> { - try { - RequestBody body = r.body().get(); - body.writeTo(baos); - body.close(); + try (RequestBody body = r.body().get()) { + body.writeTo(ByteStreams.nullOutputStream()); } catch (IOException e) { throw new RuntimeException(e); } @@ -175,10 +171,10 @@ public void close() {} assertThat(response.get().code()).isEqualTo(200); MetricName metricName = DialogueClientMetrics.of(registry) .requestsSize() + .repeatable(RequestsSize_Repeatable.TRUE) .channelName("smallRequestChannelName") .serviceName("service") .endpoint("endpoint") - .retryable("true") .buildMetricName(); assertThat(registry.remove(metricName)).isEmpty(); } From 66ba6bd26918347a46177aa101748de0f5b9decb Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Tue, 3 Oct 2023 10:57:32 -0400 Subject: [PATCH 09/10] Remove mockito extension --- .../palantir/dialogue/core/RequestSizeMetricsChannelTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java index 452405db1..4559f56c6 100644 --- a/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java +++ b/dialogue-core/src/test/java/com/palantir/dialogue/core/RequestSizeMetricsChannelTest.java @@ -40,10 +40,7 @@ import java.util.OptionalLong; import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -@ExtendWith(MockitoExtension.class) public class RequestSizeMetricsChannelTest { private static final DialogueChannelFactory STUB_FACTORY = _ignored -> { From fe262048de380bd911f507556e6ffa3b39cccf50 Mon Sep 17 00:00:00 2001 From: Andy Bradshaw Date: Tue, 3 Oct 2023 11:09:25 -0400 Subject: [PATCH 10/10] Update metric docs --- dialogue-clients/metrics.md | 2 +- dialogue-core/src/main/metrics/dialogue-core-metrics.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dialogue-clients/metrics.md b/dialogue-clients/metrics.md index c8f790a77..d25dce91f 100644 --- a/dialogue-clients/metrics.md +++ b/dialogue-clients/metrics.md @@ -71,7 +71,7 @@ Dialogue-specific metrics that are not necessarily applicable to other client im - `dialogue.client.request.queued.time` tagged `channel-name` (timer): Time spent waiting in the queue before execution. - `dialogue.client.request.endpoint.queued.time` tagged `channel-name`, `service-name`, `endpoint` (timer): Time spent waiting in the queue before execution on a specific endpoint due to server QoS. - `dialogue.client.request.sticky.queued.time` tagged `channel-name` (timer): Time spent waiting in the sticky queue before execution attempt. -- `dialogue.client.requests.size` (histogram): Size of requests +- `dialogue.client.requests.size` (histogram): Histogram of the sizes of requests larger than a threshold (1 MiB). - `repeatable` values (`true`,`false`) - `channel-name` - `service-name` diff --git a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml index ba335ec86..1e1698fbf 100644 --- a/dialogue-core/src/main/metrics/dialogue-core-metrics.yml +++ b/dialogue-core/src/main/metrics/dialogue-core-metrics.yml @@ -64,7 +64,7 @@ namespaces: - name: channel-name - name: service-name - name: endpoint - docs: Size of requests + docs: Histogram of the sizes of requests larger than a threshold (1 MiB). # Note: the 'dialogue.client.create' metric is also defined in the apache metrics. create: type: meter