From 91dd2cf23a4f6d48cc3ae4f6f32d11e63f39a421 Mon Sep 17 00:00:00 2001 From: grzegorzswistak Date: Mon, 19 May 2025 15:53:52 +0200 Subject: [PATCH] Aws metrics v2 --- .../lo2iothub/ConnectorApplication.java | 67 +------- .../lo2iothub/utils/MeterRegistryConfig.java | 149 ++++++++++++++++++ .../lo2iothub/utils/MetricsProperties.java | 18 +++ src/main/resources/application.yml | 2 + src/main/resources/logback.xml | 2 + 5 files changed, 177 insertions(+), 61 deletions(-) create mode 100644 src/main/java/com/orange/lo/sample/lo2iothub/utils/MeterRegistryConfig.java diff --git a/src/main/java/com/orange/lo/sample/lo2iothub/ConnectorApplication.java b/src/main/java/com/orange/lo/sample/lo2iothub/ConnectorApplication.java index 2735a7a..ca84483 100644 --- a/src/main/java/com/orange/lo/sample/lo2iothub/ConnectorApplication.java +++ b/src/main/java/com/orange/lo/sample/lo2iothub/ConnectorApplication.java @@ -1,74 +1,19 @@ -/** -* Copyright (c) Orange. All Rights Reserved. -* -* This source code is licensed under the MIT license found in the -* LICENSE file in the root directory of this source tree. -*/ +/** + * Copyright (c) Orange. All Rights Reserved. + *

+ * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ package com.orange.lo.sample.lo2iothub; -import com.orange.lo.sample.lo2iothub.utils.MetricsProperties; -import io.micrometer.cloudwatch2.CloudWatchConfig; -import io.micrometer.cloudwatch2.CloudWatchMeterRegistry; -import io.micrometer.core.instrument.Clock; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; - -import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; -import software.amazon.awssdk.regions.providers.AwsProfileRegionProvider; -import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient; - -import java.lang.invoke.MethodHandles; @SpringBootApplication public class ConnectorApplication { - private static final String SERVICE_PROFILE_NAME = "service-profile"; - private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private final MetricsProperties metricsProperties; - - ConnectorApplication(MetricsProperties metricsProperties) { - this.metricsProperties = metricsProperties; - } - public static void main(String[] args) { SpringApplication.run(ConnectorApplication.class, args); } - - @Bean - @Qualifier("counters") - public MeterRegistry meterRegistry() { - CloudWatchAsyncClient cloudWatchAsyncClient = CloudWatchAsyncClient.builder() - .credentialsProvider(ProfileCredentialsProvider.create(SERVICE_PROFILE_NAME)) - .region(new AwsProfileRegionProvider(null, SERVICE_PROFILE_NAME).getRegion()) - .build(); - - CloudWatchMeterRegistry cloudWatchMeterRegistry = new CloudWatchMeterRegistry(cloudWatchConfig(), Clock.SYSTEM, cloudWatchAsyncClient); - - cloudWatchMeterRegistry.config() - .meterFilter(MeterFilter.deny(id -> !id.getName().startsWith("message"))) - .commonTags(metricsProperties.getDimensionName(), metricsProperties.getDimensionValue()); - return cloudWatchMeterRegistry; - } - - private CloudWatchConfig cloudWatchConfig() { - return new CloudWatchConfig() { - - @Override - public String get(String key) { - return null; - } - - @Override - public String namespace() { - return metricsProperties.getNamespace(); - } - }; - } } diff --git a/src/main/java/com/orange/lo/sample/lo2iothub/utils/MeterRegistryConfig.java b/src/main/java/com/orange/lo/sample/lo2iothub/utils/MeterRegistryConfig.java new file mode 100644 index 0000000..7f7fb02 --- /dev/null +++ b/src/main/java/com/orange/lo/sample/lo2iothub/utils/MeterRegistryConfig.java @@ -0,0 +1,149 @@ +/** + * Copyright (c) Orange. All Rights Reserved. + *

+ * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.orange.lo.sample.lo2iothub.utils; + +import io.micrometer.cloudwatch2.CloudWatchConfig; +import io.micrometer.cloudwatch2.CloudWatchMeterRegistry; +import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.config.MeterFilter; +import io.micrometer.core.instrument.step.StepMeterRegistry; +import io.micrometer.core.instrument.step.StepRegistryConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; +import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider; +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.providers.AwsProfileRegionProvider; +import software.amazon.awssdk.regions.providers.InstanceProfileRegionProvider; +import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient; + +import java.lang.invoke.MethodHandles; +import java.time.Duration; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +@Configuration +public class MeterRegistryConfig { + + private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private static final String AWS_SERVICE_PROFILE_NAME = "service-profile"; + private final MetricsProperties metricsProperties; + + public MeterRegistryConfig(MetricsProperties metricsProperties) { + this.metricsProperties = metricsProperties; + } + + @Bean + @Qualifier("counters") + public MeterRegistry meterRegistry() { + MeterRegistry meterRegistry; + if (metricsProperties.isSendToCloudwatch()) { + meterRegistry = getCloudWatchMeterRegistry(); + } else { + meterRegistry = stepMeterRegistry(); + } + return meterRegistry; + } + + private CloudWatchMeterRegistry getCloudWatchMeterRegistry() { + CloudWatchAsyncClient cloudWatchAsyncClient = CloudWatchAsyncClient.builder() + .credentialsProvider(getAwsCredentialsProvider()) + .region(getRegion()) + .build(); + + CloudWatchMeterRegistry cloudWatchMeterRegistry = new CloudWatchMeterRegistry(cloudWatchConfig(), Clock.SYSTEM, cloudWatchAsyncClient); + + cloudWatchMeterRegistry.config() + .meterFilter(MeterFilter.deny(id -> !id.getName().startsWith("message"))) + .commonTags(metricsProperties.getDimensionName(), metricsProperties.getDimensionValue()); + return cloudWatchMeterRegistry; + } + + private AwsCredentialsProvider getAwsCredentialsProvider() { + return metricsProperties.isUseServiceProfile() + ? ProfileCredentialsProvider.create(AWS_SERVICE_PROFILE_NAME) + : InstanceProfileCredentialsProvider.create(); + } + + private Region getRegion() { + return metricsProperties.isUseServiceProfile() + ? new AwsProfileRegionProvider(null, AWS_SERVICE_PROFILE_NAME).getRegion() + : new InstanceProfileRegionProvider().getRegion(); + } + + private CloudWatchConfig cloudWatchConfig() { + return new CloudWatchConfig() { + + @Override + public String get(String key) { + return null; + } + + @Override + public String namespace() { + return metricsProperties.getNamespace(); + } + }; + } + + private StepMeterRegistry stepMeterRegistry() { + StepMeterRegistry stepMeterRegistry = new StepMeterRegistry(stepRegistryConfig(), Clock.SYSTEM) { + + @Override + protected TimeUnit getBaseTimeUnit() { + return TimeUnit.MILLISECONDS; + } + + @Override + protected void publish() { + getMeters().stream() + .filter(m -> m.getId().getName().startsWith("message")) + .map(m -> get(m.getId().getName()).counter()) + .forEach(c -> LOG.info("{} = {}", c.getId().getName(), val(c))); + } + + @Override + public void start(ThreadFactory threadFactory) { + super.start(Executors.defaultThreadFactory()); + } + }; + stepMeterRegistry.start(Executors.defaultThreadFactory()); + return stepMeterRegistry; + } + + private StepRegistryConfig stepRegistryConfig() { + return new StepRegistryConfig() { + + @Override + public Duration step() { + return Duration.ofMinutes(1); + } + + @Override + public String prefix() { + return ""; + } + + @Override + public String get(String key) { + return null; + } + }; + } + + private long val(Counter cnt) { + return Math.round(cnt.count()); + } +} diff --git a/src/main/java/com/orange/lo/sample/lo2iothub/utils/MetricsProperties.java b/src/main/java/com/orange/lo/sample/lo2iothub/utils/MetricsProperties.java index 0522e5f..c4d865f 100644 --- a/src/main/java/com/orange/lo/sample/lo2iothub/utils/MetricsProperties.java +++ b/src/main/java/com/orange/lo/sample/lo2iothub/utils/MetricsProperties.java @@ -9,6 +9,8 @@ public class MetricsProperties { private String namespace; private String dimensionName; private String dimensionValue; + private boolean sendToCloudwatch; + private boolean useServiceProfile; public String getNamespace() { return namespace; @@ -33,4 +35,20 @@ public String getDimensionValue() { public void setDimensionValue(String dimensionValue) { this.dimensionValue = dimensionValue; } + + public boolean isSendToCloudwatch() { + return sendToCloudwatch; + } + + public void setSendToCloudwatch(boolean sendToCloudwatch) { + this.sendToCloudwatch = sendToCloudwatch; + } + + public boolean isUseServiceProfile() { + return useServiceProfile; + } + + public void setUseServiceProfile(boolean useServiceProfile) { + this.useServiceProfile = useServiceProfile; + } } \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index df3eb84..b7c353a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -53,6 +53,8 @@ azure: instrumentation-key: YOUR_INSTMENTATION_KEY metrics: + send-to-cloudwatch: false + use-service-profile: false namespace: CCS dimension-name: connector-id dimension-value: diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 295fd61..59ad92a 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -40,6 +40,8 @@ + +