简体   繁体   中英

Custom Cloudwatch MeterRegistry for Micrometer in Spring Boot 2

We would like to send actuator metrics to Cloudwatch. Using the provided micrometer cloudwatch MeterRegistry solutions makes to many assumptions about how our project is setup, for example you need to depend on cloud AWS which then makes even more assumptions. We would like to write a more lightweight implementation which just get a CloudWatchAsyncClient injected and makes no other assumptions about our project.

However im not sure how. Is there any example on how to make a custom implementation insted of having to depend on the available metrics registry?

So far I have done some experimenting with the following:

public interface CloudWatchConfig extends StepRegistryConfig {
    int MAX_BATCH_SIZE = 20;

    @Override
    default String prefix() {
        return "cloudwatch";
    }

    default String namespace() {
        String v = get(prefix() + ".namespace");
        if (v == null)
            throw new MissingRequiredConfigurationException("namespace must be set to report metrics to CloudWatch");
        return v;
    }

    @Override
    default int batchSize() {
        String v = get(prefix() + ".batchSize");
        if (v == null) {
            return MAX_BATCH_SIZE;
        }
        int vInt = Integer.parseInt(v);
        if (vInt > MAX_BATCH_SIZE)
            throw new InvalidConfigurationException("batchSize must be <= " + MAX_BATCH_SIZE);

        return vInt;
    }
}
@Service
@Log
public class CloudWatchMeterRegistry extends StepMeterRegistry {

    public CloudWatchMeterRegistry(CloudWatchConfig config, Clock clock) {
        super(config, clock);
    }

    @Override
    protected void publish() {
        getMeters().stream().forEach(a -> {
            log.warning(a.getId().toString());
        });
    }

    @Override
    protected TimeUnit getBaseTimeUnit() {
        return TimeUnit.MILLISECONDS;
    }
}
@Configuration
public class MetricsPublisherConfig {
    @Bean
    public CloudWatchConfig cloudWatchConfig() {
        return new CloudWatchConfig() {
            @Override
            public String get(String key) {
                switch (key) {
                    case "cloudwatch.step":
                        return props.getStep();
                    default:
                        return "testtest";
                }

            }
        };
    }
}

However when I run the publish method is never called and no metrics are ever logged. What am I missing to get this working?

Here's an example project. I don't use cloudwatch myself so not had a chance to test it integrating with AWS. Leave a comment if there are any issues and we can try to resolve them

https://github.com/michaelmcfadyen/spring-boot-cloudwatch

I am trying to do something similar, and avoid using Spring Cloud. The simplest solution I have found so far is:

import io.micrometer.cloudwatch2.CloudWatchConfig;
import io.micrometer.cloudwatch2.CloudWatchMeterRegistry;
import io.micrometer.core.instrument.Clock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;

@Configuration
public class MetricsConfiguration {

    @Bean
    public CloudWatchMeterRegistry cloudWatchMeterRegistry(CloudWatchConfig config, Clock clock) {
        return new CloudWatchMeterRegistry(config, clock, CloudWatchAsyncClient.create());
    }

    @Component
    public static class MicrometerCloudWatchConfig
            extends StepRegistryPropertiesConfigAdapter<StepRegistryProperties>
            implements CloudWatchConfig {

        private final String namespace;
        private final boolean enabled;

        public MicrometerCloudWatchConfig(
                @Value("${CLOUDWATCH_NAMESPACE}") String namespace,
                @Value("${METRICS_ENABLED}") boolean enabled) {
            super(new StepRegistryProperties() {
            });
            this.namespace = namespace;
            this.enabled = enabled;
        }

        @Override
        public String namespace() {
            return namespace;
        }

        @Override
        public boolean enabled() {
            return enabled;
        }

        @Override
        public int batchSize() {
            return CloudWatchConfig.MAX_BATCH_SIZE;
        }
    }
}

Dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-cloudwatch2</artifactId>
</dependency>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM