Skip to content

Commit

Permalink
Migrate Kafka metrics to KafkaClientMetrics
Browse files Browse the repository at this point in the history
Closes gh-20838
  • Loading branch information
snicoll committed Apr 6, 2020
1 parent 333ac27 commit 888a81b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ dependencies {
optional("org.springframework.data:spring-data-redis")
optional("org.springframework.data:spring-data-solr")
optional("org.springframework.integration:spring-integration-core")
optional("org.springframework.kafka:spring-kafka")
optional("org.springframework.security:spring-security-config")
optional("org.springframework.security:spring-security-web")
optional("org.springframework.session:spring-session-core")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,37 +18,37 @@

import java.util.Collections;

import javax.management.MBeanServer;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.kafka.KafkaConsumerMetrics;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import io.micrometer.core.instrument.binder.kafka.KafkaClientMetrics;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.ProducerFactory;

/**
* Auto-configuration for Kafka metrics.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @since 2.1.0
*/
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter({ MetricsAutoConfiguration.class, JmxAutoConfiguration.class })
@ConditionalOnClass({ KafkaConsumerMetrics.class, KafkaConsumer.class })
@AutoConfigureAfter({ MetricsAutoConfiguration.class, KafkaAutoConfiguration.class })
@ConditionalOnClass({ KafkaClientMetrics.class, ProducerFactory.class })
@ConditionalOnBean(MeterRegistry.class)
public class KafkaMetricsAutoConfiguration {

@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(MBeanServer.class)
public KafkaConsumerMetrics kafkaConsumerMetrics(MBeanServer mbeanServer) {
return new KafkaConsumerMetrics(mbeanServer, Collections.emptyList());
@ConditionalOnSingleCandidate(ProducerFactory.class)
public KafkaClientMetrics kafkaClientMetrics(ProducerFactory<?, ?> producerFactory) {

This comment has been minimized.

Copy link
@izeye

izeye Apr 18, 2020

Contributor

This seems to be changed to producer metrics from consumer metrics. KafkaClientMetrics supports instrumentation for Producer, Consumer, and AdminClient, so you might want to instrument others. Micrometer 1.4.0 also adds KafkaStreamsMetrics, so you might want to use it, too.

return new KafkaClientMetrics(producerFactory.createProducer(), Collections.emptyList());

This comment has been minimized.

Copy link
@izeye

izeye Apr 18, 2020

Contributor

This seems to create a new producer and instrument it rather than instrumenting an existing one.

This comment has been minimized.

Copy link
@snicoll

snicoll Apr 18, 2020

Author Member

AFAIK we don't export such object as beans so I don't really know how we would get a handle to those. Can you please create an issue?

This comment has been minimized.

Copy link
@izeye

izeye Apr 18, 2020

Contributor

@snicoll Sure, I created #21008.

}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,54 +16,54 @@

package org.springframework.boot.actuate.autoconfigure.metrics;

import io.micrometer.core.instrument.binder.kafka.KafkaConsumerMetrics;
import io.micrometer.core.instrument.binder.kafka.KafkaClientMetrics;
import org.junit.jupiter.api.Test;

import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

/**
* Tests for {@link KafkaMetricsAutoConfiguration}.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
*/
class KafkaMetricsAutoConfigurationTests {

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple())
.withPropertyValues("spring.jmx.enabled=true")
.withConfiguration(AutoConfigurations.of(KafkaMetricsAutoConfiguration.class));

@Test
void whenThereIsNoMBeanServerAutoConfigurationBacksOff() {
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(KafkaConsumerMetrics.class));
void whenThereIsNoProducerFactoryAutoConfigurationBacksOff() {
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(KafkaClientMetrics.class));
}

@Test
void whenThereIsAnMBeanServerKafkaConsumerMetricsIsConfigured() {
this.contextRunner.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(KafkaConsumerMetrics.class));
void whenThereIsAnAProducerFactoryKafkaClientMetricsIsConfigured() {
this.contextRunner.withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class))
.run((context) -> assertThat(context).hasSingleBean(KafkaClientMetrics.class));
}

@Test
void allowsCustomKafkaConsumerMetricsToBeUsed() {
this.contextRunner.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class))
.withUserConfiguration(CustomKafkaConsumerMetricsConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(KafkaConsumerMetrics.class)
.hasBean("customKafkaConsumerMetrics"));
void allowsCustomKafkaClientMetricsToBeUsed() {
this.contextRunner.withConfiguration(AutoConfigurations.of(KafkaAutoConfiguration.class))
.withUserConfiguration(CustomKafkaClientMetricsConfiguration.class).run((context) -> assertThat(context)
.hasSingleBean(KafkaClientMetrics.class).hasBean("customKafkaClientMetrics"));
}

@Configuration(proxyBeanMethods = false)
static class CustomKafkaConsumerMetricsConfiguration {
static class CustomKafkaClientMetricsConfiguration {

@Bean
KafkaConsumerMetrics customKafkaConsumerMetrics() {
return new KafkaConsumerMetrics();
KafkaClientMetrics customKafkaClientMetrics() {
return mock(KafkaClientMetrics.class);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,7 @@ Spring Boot registers the following core metrics when applicable:
** Number of classes loaded/unloaded
* CPU metrics
* File descriptor metrics
* Kafka consumer metrics (<<production-ready-jmx,JMX support>> should be enabled)
* Kafka consumer metrics
* Log4j2 metrics: record the number of events logged to Log4j2 at each level
* Logback metrics: record the number of events logged to Logback at each level
* Uptime metrics: report a gauge for uptime and a fixed gauge representing the application's absolute start time
Expand Down

0 comments on commit 888a81b

Please sign in to comment.