mirror of
https://github.com/google/nomulus.git
synced 2025-05-02 21:17:50 +02:00
The metrics are collected in a new handler (BackendMetricsHandler), which gets outbound FullHttpRequest and inbound FullHttpResponse. All metrics collected here are backend metrics, i. e. metrics about connection between the proxy and GAE. They also corresponds to the metrics that we are correctly collection from the [] proxy, minus a few that are related to quota management, which are yet to be implemented. This CL also removed some unnecessary steps to write the frontend protocol name and client hash certificate into backend channel attributes. Instead, BackendMetricsHandler will read these information from the frontend channel attributes directly. This is because backend channel is established after frontend channel, and reading frontend channel attributes from backend handlers always works. On the other hand, there is no easy way to guarantee that the backend channel attributes are writable from frontend handlers, because the channel itself may not have been fully established. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=174513334
125 lines
5.2 KiB
Java
125 lines
5.2 KiB
Java
// Copyright 2017 The Nomulus Authors. 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 google.registry.monitoring.metrics.contrib;
|
|
|
|
import static com.google.common.truth.Truth.assertAbout;
|
|
|
|
import com.google.common.base.Joiner;
|
|
import com.google.common.collect.BoundType;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.collect.Range;
|
|
import com.google.common.truth.FailureMetadata;
|
|
import google.registry.monitoring.metrics.Distribution;
|
|
import google.registry.monitoring.metrics.ImmutableDistribution;
|
|
import google.registry.monitoring.metrics.Metric;
|
|
import google.registry.monitoring.metrics.MetricPoint;
|
|
import google.registry.monitoring.metrics.MutableDistribution;
|
|
import java.util.Map;
|
|
import javax.annotation.Nullable;
|
|
|
|
/**
|
|
* Truth subject for the {@link Metric<Distribution>} class.
|
|
*
|
|
* <p>For use with the Google <a href="https://google.github.io/truth/">Truth</a> framework. Usage:
|
|
*
|
|
* <pre> assertThat(myDistributionMetric)
|
|
* .hasAnyValueForLabels("label1", "label2", "label3")
|
|
* .and()
|
|
* .hasNoOtherValues();
|
|
* assertThat(myDistributionMetric)
|
|
* .doesNotHaveAnyValueForLabels("label1", "label2");
|
|
* assertThat(myDistributionMetric)
|
|
* .hasDataSetForLabels(ImmutableSet.of(data1, data2, data3), "label1", "label2");
|
|
* </pre>
|
|
*
|
|
* <p>The assertions treat an empty distribution as no value at all. This is not how the data is
|
|
* actually stored; event metrics do in fact have an empty distribution after they are reset. But
|
|
* it's difficult to write assertions about expected metric data when any number of empty
|
|
* distributions can also be present, so they are screened out for convenience.
|
|
*/
|
|
public final class DistributionMetricSubject
|
|
extends AbstractMetricSubject<Distribution, DistributionMetricSubject> {
|
|
|
|
/** {@link Subject.Factory} for assertions about {@link Metric<Distribution>} objects. */
|
|
/** Static assertThat({@link Metric<Distribution>}) shortcut method. */
|
|
public static DistributionMetricSubject assertThat(@Nullable Metric<Distribution> metric) {
|
|
return assertAbout(DistributionMetricSubject::new).that(metric);
|
|
}
|
|
|
|
private DistributionMetricSubject(FailureMetadata metadata, Metric<Distribution> actual) {
|
|
super(metadata, actual);
|
|
}
|
|
|
|
/**
|
|
* Returns an indication to {@link AbstractMetricSubject#hasNoOtherValues} on whether a {@link
|
|
* MetricPoint} has a non-empty distribution.
|
|
*/
|
|
@Override
|
|
protected boolean hasDefaultValue(MetricPoint<Distribution> metricPoint) {
|
|
return metricPoint.value().count() == 0;
|
|
}
|
|
|
|
/** Returns an appropriate string representation of a metric value for use in error messages. */
|
|
@Override
|
|
protected String getMessageRepresentation(Distribution distribution) {
|
|
StringBuilder sb = new StringBuilder("{");
|
|
boolean first = true;
|
|
for (Map.Entry<Range<Double>, Long> entry :
|
|
distribution.intervalCounts().asMapOfRanges().entrySet()) {
|
|
if (entry.getValue() != 0L) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
sb.append(',');
|
|
}
|
|
if (entry.getKey().hasLowerBound()) {
|
|
sb.append((entry.getKey().lowerBoundType() == BoundType.CLOSED) ? '[' : '(');
|
|
sb.append(entry.getKey().lowerEndpoint());
|
|
}
|
|
sb.append("..");
|
|
if (entry.getKey().hasUpperBound()) {
|
|
sb.append(entry.getKey().upperEndpoint());
|
|
sb.append((entry.getKey().upperBoundType() == BoundType.CLOSED) ? ']' : ')');
|
|
}
|
|
sb.append('=');
|
|
sb.append(entry.getValue());
|
|
}
|
|
}
|
|
sb.append('}');
|
|
return sb.toString();
|
|
}
|
|
|
|
/**
|
|
* Asserts that the distribution for the given label can be constructed from the given data set.
|
|
*
|
|
* <p>Note that this only tests that the distribution has the same binned histogram, along with
|
|
* the same mean, and sum of squared deviation as it would if it had recorded the specified data
|
|
* points. It could have in fact collected different data points that resulted in the same
|
|
* distribution, but that information is lost to us and cannot be tested.
|
|
*/
|
|
public And<DistributionMetricSubject> hasDataSetForLabels(
|
|
ImmutableSet<? extends Number> dataSet, String... labels) {
|
|
ImmutableList<MetricPoint<Distribution>> metricPoints = actual().getTimestampedValues();
|
|
if (metricPoints.isEmpty()) {
|
|
failWithBadResults(
|
|
"has a distribution for labels", Joiner.on(':').join(labels), "has", "no values");
|
|
}
|
|
MutableDistribution targetDistribution =
|
|
new MutableDistribution(metricPoints.get(0).value().distributionFitter());
|
|
dataSet.forEach(data -> targetDistribution.add(data.doubleValue()));
|
|
return hasValueForLabels(ImmutableDistribution.copyOf(targetDistribution), labels);
|
|
}
|
|
}
|