You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2017/08/28 11:38:49 UTC

svn commit: r1806432 - in /jackrabbit/oak/trunk: oak-core/ oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/ oak-core/src/test/java/org/apache/jackrabbit/oak/cache/ oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/ oak-parent/

Author: mreutegg
Date: Mon Aug 28 11:38:49 2017
New Revision: 1806432

URL: http://svn.apache.org/viewvc?rev=1806432&view=rev
Log:
OAK-6593: CacheStats metrics

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetrics.java   (with props)
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetricsTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/pom.xml
    jackrabbit/oak/trunk/oak-parent/pom.xml

Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1806432&r1=1806431&r2=1806432&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Mon Aug 28 11:38:49 2017
@@ -141,6 +141,11 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.service.component.annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.felix</groupId>
       <artifactId>org.apache.felix.scr.annotations</artifactId>
       <scope>provided</scope>

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetrics.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetrics.java?rev=1806432&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetrics.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetrics.java Mon Aug 28 11:38:49 2017
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *   http://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 org.apache.jackrabbit.oak.cache.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricRegistry;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
+import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An OSGi component that binds to all {@link CacheStatsMBean} instances and
+ * exposes their counters as {@link Metric}s.
+ */
+@Component(immediate = true)
+public class CacheStatsMetrics {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CacheStatsMetrics.class);
+
+    static final String HIT = "hit";
+    static final String MISS = "miss";
+    static final String EVICTION = "eviction";
+    static final String ELEMENT = "element";
+    static final String LOAD_TIME = "loadTime";
+
+    private static final List<String> TYPES = ImmutableList.of(
+            HIT, MISS, EVICTION, ELEMENT, LOAD_TIME);
+
+    private Map<String, CacheStatsMBean> cacheStatsMBeans = Maps.newHashMap();
+    private MetricRegistry registry = new MetricRegistry();
+
+    @Reference(
+            cardinality = ReferenceCardinality.AT_LEAST_ONE,
+            policy = ReferencePolicy.DYNAMIC
+    )
+    synchronized void addCacheStatsMBean(CacheStatsMBean stats) {
+        LOG.debug("addCacheStatsMBean({})", stats.getName());
+        cacheStatsMBeans.put(stats.getName(), stats);
+        registerCacheStatsMBean(this.registry, stats);
+    }
+
+    synchronized void removeCacheStatsMBean(CacheStatsMBean stats) {
+        LOG.debug("removeCacheStatsMBean({})", stats.getName());
+        cacheStatsMBeans.remove(stats.getName());
+        unregisterCacheStatsMBean(this.registry, stats);
+    }
+
+    @Reference(
+            target = "(name=oak)"
+    )
+    synchronized void setMetricRegistry(MetricRegistry registry) {
+        LOG.debug("setMetricRegistry({})", registry);
+        for (CacheStatsMBean stats : cacheStatsMBeans.values()) {
+            unregisterCacheStatsMBean(this.registry, stats);
+            registerCacheStatsMBean(registry, stats);
+        }
+        this.registry = registry;
+    }
+
+    private static void registerCacheStatsMBean(MetricRegistry registry,
+                                                CacheStatsMBean stats) {
+        registerMetric(registry, new HitCounter(stats));
+        registerMetric(registry, new MissCounter(stats));
+        registerMetric(registry, new EvictionCounter(stats));
+        registerMetric(registry, new ElementCounter(stats));
+        registerMetric(registry, new LoadTimeCounter(stats));
+    }
+
+    private static void registerMetric(MetricRegistry registry,
+                                       CacheStatsMBeanCounter metric) {
+        String name = metric.getName();
+        registry.remove(name);
+        registry.register(name, metric);
+    }
+
+    private static void unregisterCacheStatsMBean(MetricRegistry registry,
+                                                  CacheStatsMBean stats) {
+        String name = stats.getName();
+        for (String t : TYPES) {
+            registry.remove(metricName(name, t));
+        }
+    }
+
+    static String metricName(String cacheStatsName, String type) {
+        return "CacheStats." + cacheStatsName + "." + type;
+    }
+
+    private abstract static class CacheStatsMBeanCounter
+            extends Counter {
+
+        protected CacheStatsMBean stats;
+        protected String type;
+
+        CacheStatsMBeanCounter(CacheStatsMBean stats, String type) {
+            this.stats = stats;
+            this.type = type;
+        }
+
+        String getName() {
+            return metricName(stats.getName(), type);
+        }
+    }
+
+    private static final class HitCounter extends CacheStatsMBeanCounter {
+
+        HitCounter(CacheStatsMBean stats) {
+            super(stats, HIT);
+        }
+
+        @Override
+        public long getCount() {
+            return stats.getHitCount();
+        }
+    }
+
+    private static final class MissCounter extends CacheStatsMBeanCounter {
+
+        MissCounter(CacheStatsMBean stats) {
+            super(stats, MISS);
+        }
+
+        @Override
+        public long getCount() {
+            return stats.getMissCount();
+        }
+    }
+
+    private static final class EvictionCounter extends CacheStatsMBeanCounter {
+
+        EvictionCounter(CacheStatsMBean stats) {
+            super(stats, EVICTION);
+        }
+
+        @Override
+        public long getCount() {
+            return stats.getEvictionCount();
+        }
+    }
+
+    private static final class ElementCounter extends CacheStatsMBeanCounter {
+
+        ElementCounter(CacheStatsMBean stats) {
+            super(stats, ELEMENT);
+        }
+
+        @Override
+        public long getCount() {
+            return stats.getElementCount();
+        }
+    }
+
+    private static final class LoadTimeCounter extends CacheStatsMBeanCounter {
+
+        LoadTimeCounter(CacheStatsMBean stats) {
+            super(stats, LOAD_TIME);
+        }
+
+        @Override
+        public long getCount() {
+            return stats.getTotalLoadTime();
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetrics.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetricsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetricsTest.java?rev=1806432&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetricsTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetricsTest.java Mon Aug 28 11:38:49 2017
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *   http://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 org.apache.jackrabbit.oak.cache.impl;
+
+import java.util.Map;
+import java.util.Random;
+
+import javax.annotation.Nonnull;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.MetricRegistry;
+
+import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
+import org.apache.jackrabbit.oak.cache.AbstractCacheStats;
+import org.junit.Test;
+
+import static org.apache.jackrabbit.oak.cache.impl.CacheStatsMetrics.ELEMENT;
+import static org.apache.jackrabbit.oak.cache.impl.CacheStatsMetrics.EVICTION;
+import static org.apache.jackrabbit.oak.cache.impl.CacheStatsMetrics.HIT;
+import static org.apache.jackrabbit.oak.cache.impl.CacheStatsMetrics.MISS;
+import static org.apache.jackrabbit.oak.cache.impl.CacheStatsMetrics.metricName;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CacheStatsMetricsTest {
+
+    private static final Random RANDOM = new Random();
+    private static final long HIT_COUNT = RANDOM.nextInt(Integer.MAX_VALUE);
+    private static final long MISS_COUNT = RANDOM.nextInt(Integer.MAX_VALUE);
+    private static final long EVICTION_COUNT = RANDOM.nextInt(Integer.MAX_VALUE);
+    private static final long ELEMENT_COUNT = RANDOM.nextInt(Integer.MAX_VALUE);
+    private static final long LOAD_TIME = RANDOM.nextInt(Integer.MAX_VALUE);
+
+    @Test
+    public void metrics() {
+        MetricRegistry registry = new MetricRegistry();
+        CacheStatsMetrics metrics = new CacheStatsMetrics();
+        metrics.setMetricRegistry(registry);
+
+        CacheStatsMBean bean = new TestStats("stats");
+        metrics.addCacheStatsMBean(bean);
+
+        Map<String, Counter> counters = registry.getCounters();
+
+        Counter counter = counters.get(metricName(bean.getName(), HIT));
+        assertNotNull(counter);
+        assertEquals(HIT_COUNT, counter.getCount());
+
+        counter = counters.get(metricName(bean.getName(), MISS));
+        assertNotNull(counter);
+        assertEquals(MISS_COUNT, counter.getCount());
+
+        counter = counters.get(metricName(bean.getName(), EVICTION));
+        assertNotNull(counter);
+        assertEquals(EVICTION_COUNT, counter.getCount());
+
+        counter = counters.get(metricName(bean.getName(), ELEMENT));
+        assertNotNull(counter);
+        assertEquals(ELEMENT_COUNT, counter.getCount());
+
+        counter = counters.get(metricName(bean.getName(), CacheStatsMetrics.LOAD_TIME));
+        assertNotNull(counter);
+        assertEquals(LOAD_TIME, counter.getCount());
+
+        metrics.removeCacheStatsMBean(bean);
+        assertEquals(0, registry.getCounters().size());
+    }
+
+    private static class TestStats extends AbstractCacheStats {
+
+        TestStats(@Nonnull String name) {
+            super(name);
+        }
+
+        @Override
+        protected com.google.common.cache.CacheStats getCurrentStats() {
+            return new com.google.common.cache.CacheStats(
+                    HIT_COUNT, MISS_COUNT, MISS_COUNT, 0, LOAD_TIME, EVICTION_COUNT);
+        }
+
+        @Override
+        public long getElementCount() {
+            return ELEMENT_COUNT;
+        }
+
+        @Override
+        public long getMaxTotalWeight() {
+            return 1000;
+        }
+
+        @Override
+        public long estimateCurrentWeight() {
+            return 1000;
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/impl/CacheStatsMetricsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-parent/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-parent/pom.xml?rev=1806432&r1=1806431&r2=1806432&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-parent/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-parent/pom.xml Mon Aug 28 11:38:49 2017
@@ -515,6 +515,11 @@
         <version>4.2.0</version>
       </dependency>
       <dependency>
+        <groupId>org.osgi</groupId>
+        <artifactId>org.osgi.service.component.annotations</artifactId>
+        <version>1.3.0</version>
+      </dependency>
+      <dependency>
         <groupId>org.apache.felix</groupId>
         <artifactId>org.apache.felix.scr.annotations</artifactId>
         <version>1.9.6</version>