Skip to content

Commit

Permalink
Deprecating core.instrument.binder and move classes to binder package (
Browse files Browse the repository at this point in the history
…#3043)

* Moving binders out

we have copied over the binders from core to a separate module called micrometer-binders
binders in micrometer-core will be deprecated
the migration path will be for the users to use the micrometer-binders jar together with micrometer-core if necessary

* Added deprecations

* Move binders out from the TCK too

* Use io.micrometer.binder.jvm in JvmServiceLevelObjectives

* Use io.micrometer.binder in the registries (Health and StatsD)

* Use io.micrometer.binder in core

* Use io.micrometer.binder in samples

* Add deprecated note to javadoc with a suggestion to resolve it

* Deleting javadoc comments from binder package-info
I guess this was a c/p error.

* Delete DiskSpaceMetrics that we deprecated earlier

* Delete JettyStatisticsMetrics that we deprecated earlier

* Delete KafkaConsumerMetrics that we deprecated earlier

* Delete hibernate metrics that we deprecated earlier

Co-authored-by: Marcin Grzejszczak <mgrzejszczak@vmware.com>
  • Loading branch information
jonatan-ivanov and marcingrzejszczak authored Feb 28, 2022
1 parent 259923c commit 598a6b4
Show file tree
Hide file tree
Showing 276 changed files with 24,058 additions and 47 deletions.
2 changes: 2 additions & 0 deletions config/checkstyle/checkstyle-suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
<suppressions>
<suppress files="io[\\/]micrometer[\\/]core[\\/]instrument[\\/]binder[\\/]logging[\\/].+" checks="IllegalImport" />
<suppress files="io[\\/]micrometer[\\/]core[\\/]util[\\/]internal[\\/]logging[\\/].+" checks="IllegalImport" />
<suppress files="io[\\/]micrometer[\\/]binder[\\/]logging[\\/].+" checks="IllegalImport" />
<suppress files="implementations[\\/].+" id="SLF4JIllegalImportCheck" />
<suppress files="samples[\\/].+" checks="IllegalImport" />
<suppress files="test[\\/]java[\\/]io[\\/]micrometer[\\/]jersey.+" checks="IllegalImport" />
<suppress files="test[\\/]java[\\/]io[\\/]micrometer[\\/]core[\\/]instrument[\\/]binder[\\/]jersey[\\/]server.+" checks="(IllegalImport)" />
<suppress files="test[\\/]java[\\/]io[\\/]micrometer[\\/]binder[\\/]jersey[\\/]server.+" checks="(IllegalImport)" />
<suppress files="LogbackMetricsAutoConfiguration" checks="IllegalImport" />
</suppressions>
1 change: 1 addition & 0 deletions implementations/micrometer-registry-health/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dependencies {
api project(':micrometer-core')
api project(':micrometer-binders')

implementation 'org.slf4j:slf4j-api'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/
package io.micrometer.health.objectives;

import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmHeapPressureMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
import io.micrometer.binder.jvm.JvmGcMetrics;
import io.micrometer.binder.jvm.JvmHeapPressureMetrics;
import io.micrometer.binder.jvm.JvmMemoryMetrics;
import io.micrometer.health.ServiceLevelObjective;

import java.time.Duration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package io.micrometer.health.objectives;

import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
import io.micrometer.binder.system.FileDescriptorMetrics;
import io.micrometer.health.ServiceLevelObjective;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MockClock;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
import io.micrometer.binder.jvm.JvmMemoryMetrics;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.health.objectives.JvmServiceLevelObjectives;
import org.junit.jupiter.api.Test;
Expand Down
1 change: 1 addition & 0 deletions implementations/micrometer-registry-statsd/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {

dependencies {
api project(':micrometer-core')
api project(':micrometer-binders')

implementation 'io.projectreactor:reactor-core'
implementation('io.projectreactor.netty:reactor-netty-core') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import java.util.function.LongConsumer;

import io.micrometer.core.instrument.binder.logging.LogbackMetrics;
import io.micrometer.binder.logging.LogbackMetrics;
import reactor.core.Disposable;
import reactor.core.publisher.FluxSink;
import reactor.util.context.Context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import ch.qos.logback.classic.Logger;
import io.micrometer.core.Issue;
import io.micrometer.core.instrument.*;
import io.micrometer.core.instrument.binder.logging.LogbackMetrics;
import io.micrometer.binder.logging.LogbackMetrics;
import io.micrometer.core.instrument.config.NamingConvention;
import io.micrometer.core.lang.Nullable;
import org.junit.jupiter.api.AfterEach;
Expand Down
149 changes: 149 additions & 0 deletions micrometer-binders/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
plugins {
id 'idea'
}

dependencies {
// TODO(anuraaga): HdrHistogram is exposed in the micrometer API but probably shouldn't be
api 'org.hdrhistogram:HdrHistogram'
implementation('org.latencyutils:LatencyUtils') {
exclude group: 'org.hdrhistogram', module: 'HdrHistogram'
}

api project(':micrometer-core')

// cache monitoring
optionalApi 'com.google.guava:guava'
optionalApi 'com.github.ben-manes.caffeine:caffeine'
optionalApi 'net.sf.ehcache:ehcache'
optionalApi 'javax.cache:cache-api'
optionalApi 'com.hazelcast:hazelcast'
optionalApi 'org.hibernate:hibernate-entitymanager'

// server runtime monitoring
optionalApi 'org.eclipse.jetty:jetty-server'
optionalApi 'org.eclipse.jetty:jetty-client'
optionalApi 'org.apache.tomcat.embed:tomcat-embed-core'
optionalApi 'org.glassfish.jersey.core:jersey-server'
optionalApi 'io.grpc:grpc-api'

// apache httpcomponents monitoring
optionalApi 'org.apache.httpcomponents:httpclient'
optionalApi 'org.apache.httpcomponents:httpasyncclient'

// hystrix monitoring
// TODO: Mark deprecated in 1.9 in old code
// TODO: Make it noop in 1.9 in new code and in 2.0
// TODO: Marked for removal in 2.1.0?
optionalApi 'com.netflix.hystrix:hystrix-core'

// log monitoring
optionalApi 'ch.qos.logback:logback-classic'
optionalApi 'org.apache.logging.log4j:log4j-core'

// @Timed AOP
optionalApi 'com.squareup.okhttp3:okhttp'

optionalApi 'org.mongodb:mongodb-driver-sync'

optionalApi 'org.jooq:jooq'

optionalApi 'org.apache.kafka:kafka-clients'
optionalApi 'org.apache.kafka:kafka-streams'

testImplementation 'io.projectreactor:reactor-test'

// JUnit 5
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'com.tngtech.archunit:archunit-junit5'

// Eclipse still needs this (as of 4.7.1a)
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

testImplementation 'org.mockito:mockito-inline'

testImplementation 'org.hsqldb:hsqldb'

// dependency injection tests
testImplementation 'javax.inject:javax.inject'
testImplementation 'org.springframework:spring-context'
testImplementation 'com.google.inject:guice'

testImplementation 'com.h2database:h2'

// Uncomment these if you are interested in testing injection with dagger in MeterRegistryInjectionTest
// testImplementation 'com.google.dagger:dagger'
// testAnnotationProcessor 'com.google.dagger:dagger-compiler'

testImplementation 'org.assertj:assertj-core'
testImplementation 'org.awaitility:awaitility'

testImplementation 'org.ehcache:ehcache'

testImplementation 'org.apache.kafka:kafka-clients'

testImplementation 'org.apache.commons:commons-pool2:2.+'

testImplementation 'org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-inmemory'
testRuntimeOnly 'org.glassfish.jersey.inject:jersey-hk2'

testImplementation 'ru.lanwen.wiremock:wiremock-junit5'
testImplementation 'com.github.tomakehurst:wiremock-jre8-standalone'

// Log4j2 Async dependency
testImplementation 'com.lmax:disruptor:3.4.+'

// Kafka binder IT dependencies
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:kafka'

// Postgres Binder IT dependencies
testImplementation 'org.testcontainers:postgresql'
testImplementation 'org.postgresql:postgresql'

testImplementation 'org.testcontainers:mongodb'
}

task shenandoahTest(type: Test) {
// set heap size for the test JVM(s)
maxHeapSize = "1500m"

useJUnitPlatform {
includeTags 'gc'
}

jvmArgs '-XX:+UseShenandoahGC'
}

task zgcTest(type: Test) {
// set heap size for the test JVM(s)
maxHeapSize = "1500m"

useJUnitPlatform {
includeTags 'gc'
}

jvmArgs '-XX:+UseZGC'
}

task openj9BalancedTest(type: Test) {
// set heap size for the test JVM(s)
maxHeapSize = "1500m"

useJUnitPlatform {
includeTags 'gc'
}

jvmArgs '-Xgcpolicy:balanced'
}

task openj9ConcurrentScavengeTest(type: Test) {
// set heap size for the test JVM(s)
maxHeapSize = "1500m"

useJUnitPlatform {
includeTags 'gc'
}

jvmArgs '-Xgc:concurrentScavenge'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright 2017 VMware, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.binder.cache;

import java.lang.ref.WeakReference;

import io.micrometer.core.instrument.FunctionCounter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.lang.NonNullApi;
import io.micrometer.core.lang.NonNullFields;
import io.micrometer.core.lang.Nullable;

/**
* A common base class for cache metrics that ensures that all caches are instrumented
* with the same basic set of metrics while allowing for additional detail that is specific
* to an individual implementation.
* <p>
* Having this common base set of metrics ensures that you can reason about basic cache performance
* in a dimensional slice that spans different cache implementations in your application.
*
* @author Jon Schneider
*/
@NonNullApi
@NonNullFields
public abstract class CacheMeterBinder<C> implements MeterBinder {
private final WeakReference<C> cacheRef;
private final Iterable<Tag> tags;

public CacheMeterBinder(C cache, String cacheName, Iterable<Tag> tags) {
this.tags = Tags.concat(tags, "cache", cacheName);
this.cacheRef = new WeakReference<>(cache);
}

@Nullable
protected C getCache() {
return cacheRef.get();
}

@Override
public final void bindTo(MeterRegistry registry) {
C cache = getCache();
if (size() != null) {
Gauge.builder("cache.size", cache,
c -> {
Long size = size();
return size == null ? 0 : size;
})
.tags(tags)
.description("The number of entries in this cache. This may be an approximation, depending on the type of cache.")
.register(registry);
}

if (missCount() != null) {
FunctionCounter.builder("cache.gets", cache,
c -> {
Long misses = missCount();
return misses == null ? 0 : misses;
})
.tags(tags).tag("result", "miss")
.description("the number of times cache lookup methods have returned an uncached (newly loaded) value, or null")
.register(registry);
}

FunctionCounter.builder("cache.gets", cache, c -> hitCount())
.tags(tags).tag("result", "hit")
.description("The number of times cache lookup methods have returned a cached value.")
.register(registry);

FunctionCounter.builder("cache.puts", cache, c -> putCount())
.tags(tags)
.description("The number of entries added to the cache")
.register(registry);

if (evictionCount() != null) {
FunctionCounter.builder("cache.evictions", cache,
c -> {
Long evictions = evictionCount();
return evictions == null ? 0 : evictions;
})
.tags(tags)
.description("cache evictions")
.register(registry);
}

bindImplementationSpecificMetrics(registry);
}

/**
* MOST cache implementations provide a means of retrieving the number of entries. Even if
*
* @return Total number of cache entries. This value may go up or down with puts, removes, and evictions. Returns
* {@code null} if the cache implementation does not provide a way to track cache size.
*/
@Nullable
protected abstract Long size();

/**
* @return Get requests that resulted in a "hit" against an existing cache entry. Monotonically increasing hit count.
*/
protected abstract long hitCount();

/**
* @return Get requests that resulted in a "miss", or didn't match an existing cache entry. Monotonically increasing count.
* Returns {@code null} if the cache implementation does not provide a way to track miss count, especially in distributed
* caches.
*/
@Nullable
protected abstract Long missCount();

/**
* @return Total number of entries that have been evicted from the cache. Monotonically increasing eviction count.
* Returns {@code null} if the cache implementation does not support eviction, or does not provide a way to track
* the eviction count.
*/
@Nullable
protected abstract Long evictionCount();

/**
* The put mechanism is unimportant - this count applies to entries added to the cache according to a pre-defined
* load function such as exists in Guava/Caffeine caches as well as manual puts.
*
* Note that Guava/Caffeine caches don't count manual puts.
*
* @return Total number of entries added to the cache. Monotonically increasing count.
*/
protected abstract long putCount();

/**
* Bind detailed metrics that are particular to the cache implementation, e.g. load duration for
* Caffeine caches, heap and disk size for EhCache caches. These metrics are above and beyond the
* basic set of metrics that is common to all caches.
*
* @param registry The registry to bind metrics to.
*/
protected abstract void bindImplementationSpecificMetrics(MeterRegistry registry);

protected Iterable<Tag> getTagsWithCacheName() {
return tags;
}
}
Loading

0 comments on commit 598a6b4

Please sign in to comment.