Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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.
* <p>
* 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();
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/**
* Copyright (c) Orange. All Rights Reserved.
* <p>
* 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
<logger name="com.microsoft.azure" level="ERROR" />
<logger name="org.apache.qpid" level="FINE"/>
<logger name="proton.trace" level="FINE" />
<Logger name="org.apache.catalina.core" level="WARN" />
<Logger name="org.springframework.boot.web.embedded.tomcat" level="WARN" />

<root level="INFO">
<appender-ref ref="STDOUT" />
Expand Down