79259512

Date: 2024-12-06 22:17:48
Score: 0.5
Natty:
Report link

TLDR

Add the following property to your application property file if you need slo buckets

management.metrics.distribution.slo.spring.cloud.gateway.requests=50ms,100ms,200ms,300ms,400ms,500ms

If you need percentiles add

management.metrics.distribution.percentiles.spring.cloud.gateway.requests=0.95,0.99

Also make sure you enabled spring.cloud.gateway.metrics.enabled and spring.cloud.gateway.metrics.tags.path.enabled.

Also this solution can be used with every Timer or DistributionSummary metric that you have, you just need to change id-prefix to your metric id.

management.metrics.distribution.slo.{id-prefix}={your desired slo values}

Explanation

Metrics for Spring Cloud Gateway are registered through the GatewayMetricsFilter class. As you can see this is a simple class that does nothing more than create a Timer which is then passed to the MeterRegistry.

The magic is in the MeterRegistry and MeterFilter. As soon as you create a metric via meterRegistry, it goes through a chain of implementations of the MeterFilter interface.

if (config != null) {
    for (MeterFilter filter : filters) {
        DistributionStatisticConfig filteredConfig = filter.configure(mappedId, config);
        if (filteredConfig != null) {
            config = filteredConfig;
        }
    }
}

Their task is to filter and configure metrics that fall into them. If you want to know how they are arranged, you can read the article.

We are interested in PropertiesMeterFilter, which is created at the stage of application autoconfiguration. Thanks to it we can configure all our metrics through the applicaiton.property file. We are interested in how it configures DistributionStatisticConfig:

@Override
public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
    Distribution distribution = this.properties.getDistribution();
    return DistributionStatisticConfig.builder()
        .percentilesHistogram(lookupWithFallbackToAll(distribution.getPercentilesHistogram(), id, null))
        .percentiles(lookupWithFallbackToAll(distribution.getPercentiles(), id, null))
        .serviceLevelObjectives(
                convertServiceLevelObjectives(id.getType(), lookup(distribution.getSlo(), id, null)))
        .minimumExpectedValue(
                convertMeterValue(id.getType(), lookup(distribution.getMinimumExpectedValue(), id, null)))
        .maximumExpectedValue(
                convertMeterValue(id.getType(), lookup(distribution.getMaximumExpectedValue(), id, null)))
        .expiry(lookupWithFallbackToAll(distribution.getExpiry(), id, null))
        .bufferLength(lookupWithFallbackToAll(distribution.getBufferLength(), id, null))
        .build()
        .merge(config);
}

As we can see it does a lookup on all the slo values you specified in applicaiton.property:

lookup(distribution.getSlo(), id, null))

And if the id of the metrics match then it publishes your bucket list.

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: kairoslav