I am using Micrometer Cloudwatch 1.1.3, brought in with Gradle as compile 'io.micrometer:micrometer-registry-cloudwatch:1.1.3'
In Java, I can create a CloudWatchConfig
by doing the following:
CloudWatchConfig cloudWatchConfig = new CloudWatchConfig() {
@Override
public String get(String s) {
return "my-service-metrics";
}
@Override
public boolean enabled() {
return true;
}
@Override
public Duration step() {
return Duration.ofSeconds(30);
}
@Override
public int batchSize() {
return CloudWatchConfig.MAX_BATCH_SIZE;
}
};
The equivalent in Kotlin, I think should be:
val cloudWatchConfig = CloudWatchConfig {
fun get(s:String) = "my-service-metrics"
fun enabled() = true
fun step() = Duration.ofSeconds(30)
fun batchSize() = CloudWatchConfig.MAX_BATCH_SIZE
}
The Koltin compiler fails this, pointing out the last line in the block: fun batchSize() = CloudWatchConfig.MAX_BATCH_SIZE
saying that it expected a value of type String?
After much debugging, I was able to fix this by returning the toString of the step function. You can't just pass any String through as it will be parsed as if it is generated by Duration. My Kotlin code now works and looks like the following:
val cloudWatchConfig = CloudWatchConfig {
fun get(s:String) = "my-service-metrics"
fun enabled() = true
fun step() = Duration.ofSeconds(30)
fun batchSize() = CloudWatchConfig.MAX_BATCH_SIZE
step().toString()
}
After looking through the CloudWatchConfig, StepRegisteryConfig and MeterRegistryConfig interfaces I can't work out why this is the case. Why does Koltin do this, and why is it expecting the toString of a Duration?
To create the equivalent of an anonymous class in Java, the syntax is a bit different. You need to use the object
keyword, and also include the override
keywords for the interface methods. e.g.
val cloudWatchConfig = object : CloudWatchConfig {
override fun get(key: String) = "my-service-metrics"
override fun enabled() = true
override fun step() = Duration.ofSeconds(30)
override fun batchSize() = CloudWatchConfig.MAX_BATCH_SIZE
}