EXPEDIA GROUP TECHNOLOGY — DATA

Working around Datadog’s cardinality limitations

How to get custom metrics for ID-based entities while keeping your expenses under control

Man standing on ice

Background

Publish only what you need

Manipulating metrics

An ugly sawtooth graph
A segmented graph, not smooth but much better
A monitor that compares the current rate with a threshold

Hands on with Spring Boot

management:
metrics:
export:
statsd:
flavor: datadog
host: ${DD_AGENT_HOST}
@Bean
public SimpleMeterRegistry internalMeterRegistry() {
final SimpleConfig config = new SimpleConfig() {
@Override
public String get(String key) {
return null;
}
@Override
public Duration step() {
return Duration.ofMillis(5 * 60 * 1000);
}
@Override
public CountingMode mode() {
return CountingMode.STEP;
}
};
return new SimpleMeterRegistry(config, Clock.SYSTEM);
}

count() will report the number of events in the last complete interval rather than the total for the life of the process.

@Service
@EnableScheduling
public class AggregateMetricsService {
private final MeterRegistry internalMeterRegistry;
private final AtomicLong topmostProducedRate = new AtomicLong();
private final Set<Long> publishingExperiments = new HashSet<>();
@Autowired
public AggregateMetricsService(SimpleMeterRegistry internalMeterRegistry, StatsdMeterRegistry publishingMeterRegistry) {
this.internalMeterRegistry = internalMeterRegistry;
publishingMeterRegistry.gauge("aggregateMetricName", topmostProducedRate);
}
// This should be invoked whenever an exposure is detected
public void mark(Long experimentId) {
internalCounterByExperiment(experimentId).increment();
publishingExperiments.add(experimentId);
}
@Scheduled(fixedRate = 5 * 60 * 1000)
public void publish() {
long topmostProducedCountInInterval = 0;
for (final Long experimentId : publishingExperiments) {
final double count = internalCounterByExperiment(experimentId).count();
if (count > topmostProducedCountInInterval) {
topmostProducedCountInInterval = count;
}
}
this.topmostProducedRate.set(topmostProducedCountInInterval * 12);
}
private Counter internalCounterByExperiment(Long experimentId) {
return internalMeterRegistry.counter("internalMetricName", "experimentIdTag", String.valueOf(experimentId));
}
}

Fine tuning

Finding the culprit

Learn more about technology at Expedia Group

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store