diff --git a/metrics/pom.xml b/metrics/pom.xml
index c4b433482b..189f9afbff 100644
--- a/metrics/pom.xml
+++ b/metrics/pom.xml
@@ -23,5 +23,30 @@
metrics-core
${dep.ver.metrics}
+
+ io.dropwizard.metrics
+ metrics-healthchecks
+ ${dep.ver.metrics}
+
+
+ io.dropwizard.metrics
+ metrics-servlets
+ ${dep.ver.metrics}
+
+
+ io.dropwizard.metrics
+ metrics-servlet
+ ${dep.ver.metrics}
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+
+
+ junit
+ junit
+ 4.12
+
\ No newline at end of file
diff --git a/metrics/src/main/java/com/baeldung/metrics/core/ActiveUserCountGauge.java b/metrics/src/main/java/com/baeldung/metrics/core/ActiveUserCountGauge.java
new file mode 100644
index 0000000000..f14e7b520a
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/core/ActiveUserCountGauge.java
@@ -0,0 +1,17 @@
+package com.baeldung.metrics.core;
+
+import java.util.List;
+
+import com.codahale.metrics.DerivativeGauge;
+import com.codahale.metrics.Gauge;
+
+public class ActiveUserCountGauge extends DerivativeGauge, Integer> {
+ public ActiveUserCountGauge(Gauge> base) {
+ super(base);
+ }
+
+ @Override
+ protected Integer transform(List value) {
+ return value.size();
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/core/ActiveUsersGauge.java b/metrics/src/main/java/com/baeldung/metrics/core/ActiveUsersGauge.java
new file mode 100644
index 0000000000..79ac132e0b
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/core/ActiveUsersGauge.java
@@ -0,0 +1,25 @@
+package com.baeldung.metrics.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import com.codahale.metrics.CachedGauge;
+
+public class ActiveUsersGauge extends CachedGauge> {
+ public ActiveUsersGauge(long timeout, TimeUnit timeoutUnit) {
+ super(timeout, timeoutUnit);
+ }
+
+ @Override
+ protected List loadValue() {
+ return getActiveUserCount();
+ }
+
+ private List getActiveUserCount() {
+ // mock reading from database and count the active users, return a fixed value
+ List result = new ArrayList();
+ result.add(12L);
+ return result;
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/core/AttendanceRatioGauge.java b/metrics/src/main/java/com/baeldung/metrics/core/AttendanceRatioGauge.java
new file mode 100644
index 0000000000..e4cdca6b0a
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/core/AttendanceRatioGauge.java
@@ -0,0 +1,18 @@
+package com.baeldung.metrics.core;
+
+import com.codahale.metrics.RatioGauge;
+
+public class AttendanceRatioGauge extends RatioGauge {
+ private int attendanceCount;
+ private int courseCount;
+
+ public AttendanceRatioGauge(int attendanceCount, int courseCount) {
+ this.attendanceCount = attendanceCount;
+ this.courseCount = courseCount;
+ }
+
+ @Override
+ protected Ratio getRatio() {
+ return Ratio.of(attendanceCount, courseCount);
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/core/MetricsDemo.java b/metrics/src/main/java/com/baeldung/metrics/core/MetricsDemo.java
deleted file mode 100644
index 3f3127fd5a..0000000000
--- a/metrics/src/main/java/com/baeldung/metrics/core/MetricsDemo.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.baeldung.metrics.core;
-
-public class MetricsDemo {
-}
diff --git a/metrics/src/main/java/com/baeldung/metrics/core/MetricsRegistryDemo.java b/metrics/src/main/java/com/baeldung/metrics/core/MetricsRegistryDemo.java
deleted file mode 100644
index fe390d5534..0000000000
--- a/metrics/src/main/java/com/baeldung/metrics/core/MetricsRegistryDemo.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.baeldung.metrics.core;
-
-public class MetricsRegistryDemo {
- public static void main(String[] args) {
- }
-}
diff --git a/metrics/src/main/java/com/baeldung/metrics/healthchecks/DatabaseHealthCheck.java b/metrics/src/main/java/com/baeldung/metrics/healthchecks/DatabaseHealthCheck.java
new file mode 100644
index 0000000000..46170f627f
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/healthchecks/DatabaseHealthCheck.java
@@ -0,0 +1,10 @@
+package com.baeldung.metrics.healthchecks;
+
+import com.codahale.metrics.health.HealthCheck;
+
+public class DatabaseHealthCheck extends HealthCheck {
+ @Override
+ protected Result check() throws Exception {
+ return HealthCheck.Result.healthy();
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/healthchecks/UserCenterHealthCheck.java b/metrics/src/main/java/com/baeldung/metrics/healthchecks/UserCenterHealthCheck.java
new file mode 100644
index 0000000000..481ced142d
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/healthchecks/UserCenterHealthCheck.java
@@ -0,0 +1,10 @@
+package com.baeldung.metrics.healthchecks;
+
+import com.codahale.metrics.health.HealthCheck;
+
+public class UserCenterHealthCheck extends HealthCheck {
+ @Override
+ protected Result check() throws Exception {
+ return Result.healthy();
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/servlet/MyInstrumentedFilterContextListener.java b/metrics/src/main/java/com/baeldung/metrics/servlet/MyInstrumentedFilterContextListener.java
new file mode 100644
index 0000000000..3036eeeb23
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/servlet/MyInstrumentedFilterContextListener.java
@@ -0,0 +1,13 @@
+package com.baeldung.metrics.servlet;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlet.InstrumentedFilterContextListener;
+
+public class MyInstrumentedFilterContextListener extends InstrumentedFilterContextListener {
+ public static final MetricRegistry REGISTRY = new MetricRegistry();
+
+ @Override
+ protected MetricRegistry getMetricRegistry() {
+ return REGISTRY;
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/servlets/MyHealthCheckServletContextListener.java b/metrics/src/main/java/com/baeldung/metrics/servlets/MyHealthCheckServletContextListener.java
new file mode 100644
index 0000000000..12f12b3e6f
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/servlets/MyHealthCheckServletContextListener.java
@@ -0,0 +1,18 @@
+package com.baeldung.metrics.servlets;
+
+import com.baeldung.metrics.healthchecks.DatabaseHealthCheck;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import com.codahale.metrics.servlets.HealthCheckServlet;
+
+public class MyHealthCheckServletContextListener extends HealthCheckServlet.ContextListener {
+ public static final HealthCheckRegistry HEALTH_CHECK_REGISTRY = new HealthCheckRegistry();
+
+ static {
+ HEALTH_CHECK_REGISTRY.register("db", new DatabaseHealthCheck());
+ }
+
+ @Override
+ protected HealthCheckRegistry getHealthCheckRegistry() {
+ return HEALTH_CHECK_REGISTRY;
+ }
+}
diff --git a/metrics/src/main/java/com/baeldung/metrics/servlets/MyMetricsServletContextListener.java b/metrics/src/main/java/com/baeldung/metrics/servlets/MyMetricsServletContextListener.java
new file mode 100644
index 0000000000..7b4f33447a
--- /dev/null
+++ b/metrics/src/main/java/com/baeldung/metrics/servlets/MyMetricsServletContextListener.java
@@ -0,0 +1,25 @@
+package com.baeldung.metrics.servlets;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlets.MetricsServlet;
+
+public class MyMetricsServletContextListener extends MetricsServlet.ContextListener {
+ private static final MetricRegistry METRIC_REGISTRY = new MetricRegistry();
+
+ static {
+ Counter counter = METRIC_REGISTRY.counter("m01-counter");
+ counter.inc();
+
+ Histogram histogram = METRIC_REGISTRY.histogram("m02-histogram");
+ histogram.update(5);
+ histogram.update(20);
+ histogram.update(100);
+ }
+
+ @Override
+ protected MetricRegistry getMetricRegistry() {
+ return METRIC_REGISTRY;
+ }
+}
diff --git a/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java b/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java
new file mode 100644
index 0000000000..b9bcc6a5fe
--- /dev/null
+++ b/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java
@@ -0,0 +1,139 @@
+package com.baeldung.metrics.core;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+
+import com.codahale.metrics.*;
+
+public class MetricsTest {
+ @Test
+ public void testMeter() throws InterruptedException {
+ Meter meter = new Meter();
+
+ long initCount = meter.getCount();
+ assertThat(initCount, equalTo(0L));
+
+ meter.mark();
+ assertThat(meter.getCount(), equalTo(1L));
+
+ meter.mark(20);
+ assertThat(meter.getCount(), equalTo(21L));
+
+ // not use assert for these rate values because they change every time when this test is run
+ double meanRate = meter.getMeanRate();
+ double oneMinRate = meter.getOneMinuteRate();
+ double fiveMinRate = meter.getFiveMinuteRate();
+ double fifteenMinRate = meter.getFifteenMinuteRate();
+ System.out.println(meanRate);
+ System.out.println(oneMinRate);
+ System.out.println(fiveMinRate);
+ System.out.println(fifteenMinRate);
+ }
+
+ @Test
+ public void testRatioGauge() {
+ Gauge ratioGauge = new AttendanceRatioGauge(15, 20);
+ assertThat(ratioGauge.getValue(), equalTo(0.75));
+ }
+
+ @Test
+ public void testCacheGauge() {
+ Gauge> activeUsersGauge = new ActiveUsersGauge(15, TimeUnit.MINUTES);
+ List expected = new ArrayList();
+ expected.add(12L);
+ assertThat(activeUsersGauge.getValue(), equalTo(expected));
+ }
+
+ @Test
+ public void testDerivativeGauge() {
+ Gauge> activeUsersGauge = new ActiveUsersGauge(15, TimeUnit.MINUTES);
+ Gauge activeUserCountGauge = new ActiveUserCountGauge(activeUsersGauge);
+ assertThat(activeUserCountGauge.getValue(), equalTo(1));
+ }
+
+ @Test
+ public void testCounter() {
+ Counter counter = new Counter();
+
+ long initCount = counter.getCount();
+ assertThat(initCount, equalTo(0L));
+
+ counter.inc();
+ assertThat(counter.getCount(), equalTo(1L));
+
+ counter.inc(11);
+ assertThat(counter.getCount(), equalTo(12L));
+
+ counter.dec();
+ assertThat(counter.getCount(), equalTo(11L));
+
+ counter.dec(6);
+ assertThat(counter.getCount(), equalTo(5L));
+ }
+
+ @Test
+ public void testHistogram() {
+ Histogram histogram = new Histogram(new UniformReservoir());
+
+ histogram.update(5);
+ long count1 = histogram.getCount();
+ assertThat(count1, equalTo(1L));
+ Snapshot snapshot1 = histogram.getSnapshot();
+ assertThat(snapshot1.getValues().length, equalTo(1));
+ assertThat(snapshot1.getValues()[0], equalTo(5L));
+ assertThat(snapshot1.getMax(), equalTo(5L));
+ assertThat(snapshot1.getMin(), equalTo(5L));
+ assertThat(snapshot1.getMean(), equalTo(5.0));
+ assertThat(snapshot1.getMedian(), equalTo(5.0));
+ assertThat(snapshot1.getStdDev(), equalTo(0.0));
+ assertThat(snapshot1.get75thPercentile(), equalTo(5.0));
+ assertThat(snapshot1.get95thPercentile(), equalTo(5.0));
+ assertThat(snapshot1.get98thPercentile(), equalTo(5.0));
+ assertThat(snapshot1.get99thPercentile(), equalTo(5.0));
+ assertThat(snapshot1.get999thPercentile(), equalTo(5.0));
+
+ histogram.update(20);
+ long count2 = histogram.getCount();
+ assertThat(count2, equalTo(2L));
+ Snapshot snapshot2 = histogram.getSnapshot();
+ assertThat(snapshot2.getValues().length, equalTo(2));
+ assertThat(snapshot2.getValues()[0], equalTo(5L));
+ assertThat(snapshot2.getValues()[1], equalTo(20L));
+ assertThat(snapshot2.getMax(), equalTo(20L));
+ assertThat(snapshot2.getMin(), equalTo(5L));
+ assertThat(snapshot2.getMean(), equalTo(12.5));
+ assertThat(snapshot2.getMedian(), equalTo(12.5));
+ assertEquals(10.6, snapshot2.getStdDev(), 0.1);
+ assertThat(snapshot2.get75thPercentile(), equalTo(20.0));
+ assertThat(snapshot2.get95thPercentile(), equalTo(20.0));
+ assertThat(snapshot2.get98thPercentile(), equalTo(20.0));
+ assertThat(snapshot2.get99thPercentile(), equalTo(20.0));
+ assertThat(snapshot2.get999thPercentile(), equalTo(20.0));
+ }
+
+ @Test
+ public void testTimer() throws InterruptedException {
+ Timer timer = new Timer();
+
+ Timer.Context context1 = timer.time();
+ TimeUnit.SECONDS.sleep(5);
+
+ long elapsed1 = context1.stop();
+ assertEquals(5000000000L, elapsed1, 1000000);
+ assertThat(timer.getCount(), equalTo(1L));
+ assertEquals(0.2, timer.getMeanRate(), 0.1);
+
+ Timer.Context context2 = timer.time();
+ TimeUnit.SECONDS.sleep(2);
+ context2.close();
+ assertThat(timer.getCount(), equalTo(2L));
+ assertEquals(0.3, timer.getMeanRate(), 0.1);
+ }
+}
diff --git a/metrics/src/test/java/com/baeldung/metrics/core/ReporterTest.java b/metrics/src/test/java/com/baeldung/metrics/core/ReporterTest.java
new file mode 100644
index 0000000000..4676f8c3a4
--- /dev/null
+++ b/metrics/src/test/java/com/baeldung/metrics/core/ReporterTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.metrics.core;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+
+import com.codahale.metrics.*;
+
+public class ReporterTest {
+ @Test
+ public void testConsoleReporter() {
+ MetricRegistry metricRegistry = new MetricRegistry();
+
+ Meter meter = metricRegistry.meter("meter");
+ meter.mark();
+ meter.mark(200);
+ Histogram histogram = metricRegistry.histogram("histogram");
+ histogram.update(12);
+ histogram.update(17);
+ histogram.update(20);
+ Counter counter = metricRegistry.counter("counter");
+ counter.inc();
+ counter.dec();
+ counter.inc();
+ counter.inc();
+ counter.inc();
+ counter.inc();
+
+ ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry).build();
+ reporter.start(5, TimeUnit.MICROSECONDS);
+ reporter.report();
+ }
+}
diff --git a/metrics/src/test/java/com/baeldung/metrics/healthchecks/HealthCheckTest.java b/metrics/src/test/java/com/baeldung/metrics/healthchecks/HealthCheckTest.java
new file mode 100644
index 0000000000..4cefc9f3a0
--- /dev/null
+++ b/metrics/src/test/java/com/baeldung/metrics/healthchecks/HealthCheckTest.java
@@ -0,0 +1,31 @@
+package com.baeldung.metrics.healthchecks;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.codahale.metrics.health.HealthCheck;
+import com.codahale.metrics.health.HealthCheckRegistry;
+
+public class HealthCheckTest {
+ @Test
+ public void testHealthCheck() {
+ HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
+
+ healthCheckRegistry.register("db", new DatabaseHealthCheck());
+ healthCheckRegistry.register("uc", new UserCenterHealthCheck());
+
+ assertThat(healthCheckRegistry.getNames().size(), equalTo(2));
+
+ Map results = healthCheckRegistry.runHealthChecks();
+ for (Map.Entry entry : results.entrySet()) {
+ assertThat(entry.getValue().isHealthy(), equalTo(true));
+ }
+
+ healthCheckRegistry.unregister("uc");
+ assertThat(healthCheckRegistry.getNames().size(), equalTo(1));
+ }
+}
\ No newline at end of file