This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit e157e17aaded4e7c931bf9f30de1553a8a31b0aa Author: duc91 <duc91....@gmail.com> AuthorDate: Thu Jun 4 15:54:24 2020 +0700 JAMES-3170 Add CachedLatencyMetric, CachedHitMetric,CachedMissMetric and test --- .../blob/cassandra/cache/CachedBlobStore.java | 21 +++++++++--- .../blob/cassandra/cache/CachedBlobStoreTest.java | 40 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java b/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java index 45952a8e..d33c52f 100644 --- a/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java +++ b/server/blob/blob-cassandra/src/main/java/org/apache/james/blob/cassandra/cache/CachedBlobStore.java @@ -36,6 +36,8 @@ import org.apache.james.blob.api.BlobStore; import org.apache.james.blob.api.BucketName; import org.apache.james.blob.api.ObjectNotFoundException; import org.apache.james.blob.api.ObjectStoreIOException; +import org.apache.james.metrics.api.Metric; +import org.apache.james.metrics.api.MetricFactory; import org.reactivestreams.Publisher; import com.google.common.base.Preconditions; @@ -96,22 +98,32 @@ public class CachedBlobStore implements BlobStore { this.firstBytes = firstBytes; this.hasMore = hasMore; } - } public static final String BACKEND = "blobStoreBackend"; + public static final String BLOBSTORE_CACHED_LATENCY_METRIC_NAME = "blobstoreCachedLatency"; + public static final String BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME = "blobstoreCachedHit"; + public static final String BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME = "blobstoreCachedMiss"; + + private final Metric metricRetrieveHitCount; + private final Metric metricRetrieveMissCount; private final BlobStoreCache cache; private final BlobStore backend; private final Integer sizeThresholdInBytes; + private final MetricFactory metricFactory; @Inject public CachedBlobStore(BlobStoreCache cache, @Named(BACKEND) BlobStore backend, - CassandraCacheConfiguration cacheConfiguration) { + CassandraCacheConfiguration cacheConfiguration, + MetricFactory metricFactory) { this.cache = cache; this.backend = backend; this.sizeThresholdInBytes = cacheConfiguration.getSizeThresholdInBytes(); + this.metricFactory = metricFactory; + metricRetrieveHitCount = metricFactory.generate(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME); + metricRetrieveMissCount = metricFactory.generate(BLOBSTORE_CACHED_MISS_COUNT_METRIC_NAME); } @Override @@ -237,10 +249,11 @@ public class CachedBlobStore implements BlobStore { } private Mono<byte[]> readFromCache(BlobId blobId) { - return Mono.from(cache.read(blobId)); + return Mono.from(metricFactory.runPublishingTimerMetric(BLOBSTORE_CACHED_LATENCY_METRIC_NAME, cache.read(blobId))) + .doOnNext(bytes -> metricRetrieveHitCount.increment()); } private Mono<byte[]> readBytesFromBackend(BucketName bucketName, BlobId blobId) { - return Mono.from(backend.readBytes(bucketName, blobId)); + return Mono.from(backend.readBytes(bucketName, blobId)).doOnNext(bytes -> metricRetrieveMissCount.increment()); } } diff --git a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java index 8da8e61..884f14d 100644 --- a/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java +++ b/server/blob/blob-cassandra/src/test/java/org/apache/james/blob/cassandra/cache/CachedBlobStoreTest.java @@ -23,6 +23,8 @@ import static org.apache.james.blob.api.BlobStore.StoragePolicy.LOW_COST; import static org.apache.james.blob.api.BlobStore.StoragePolicy.SIZE_BASED; import static org.apache.james.blob.api.BucketName.DEFAULT; import static org.apache.james.blob.cassandra.cache.BlobStoreCacheContract.EIGHT_KILOBYTES; +import static org.apache.james.blob.cassandra.cache.CachedBlobStore.BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME; +import static org.apache.james.blob.cassandra.cache.CachedBlobStore.BLOBSTORE_CACHED_LATENCY_METRIC_NAME; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -42,6 +44,7 @@ import org.apache.james.blob.api.HashBlobId; import org.apache.james.blob.api.ObjectNotFoundException; import org.apache.james.blob.cassandra.CassandraBlobModule; import org.apache.james.blob.cassandra.CassandraBlobStore; +import org.apache.james.metrics.tests.RecordingMetricFactory; import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -64,6 +67,7 @@ public class CachedBlobStoreTest implements BlobStoreContract { private BlobStore testee; private BlobStore backend; private BlobStoreCache cache; + private RecordingMetricFactory metricFactory; @BeforeEach void setUp(CassandraCluster cassandra) { @@ -73,7 +77,8 @@ public class CachedBlobStoreTest implements BlobStoreContract { .timeOut(Duration.ofSeconds(60)) .build(); cache = new CassandraBlobStoreCache(cassandra.getConf(), cacheConfig); - testee = new CachedBlobStore(cache, backend, cacheConfig); + metricFactory = new RecordingMetricFactory(); + testee = new CachedBlobStore(cache, backend, cacheConfig, metricFactory); } @Override @@ -274,4 +279,37 @@ public class CachedBlobStoreTest implements BlobStoreContract { assertThat(Mono.from(cache.read(blobId)).blockOptional()).isEmpty(); }); } + + @Test + public void readBlobstoreCachedShouldPublishTimerMetrics() { + BlobId blobId = Mono.from(backend.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block(); + + testee.read(DEFAULT_BUCKETNAME, blobId); + testee.read(DEFAULT_BUCKETNAME, blobId); + + assertThat(metricFactory.executionTimesFor(BLOBSTORE_CACHED_LATENCY_METRIC_NAME)) + .hasSize(2); + } + + @Test + public void readBlobstoreCachedShouldCountWhenHit() { + BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block(); + + testee.read(DEFAULT_BUCKETNAME, blobId); + testee.read(DEFAULT_BUCKETNAME, blobId); + + assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME)) + .isEqualTo(2); + } + + @Test + public void readBlobstoreCachedShouldCountWhenMissed() { + BlobId blobId = Mono.from(testee.save(DEFAULT_BUCKETNAME, APPROXIMATELY_FIVE_KILOBYTES, SIZE_BASED)).block(); + + testee.read(DEFAULT_BUCKETNAME, blobId); + testee.read(DEFAULT_BUCKETNAME, blobId); + + assertThat(metricFactory.countFor(BLOBSTORE_CACHED_HIT_COUNT_METRIC_NAME)) + .isEqualTo(2); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org