Send metrics when running healthcheck Upon running healthcheck, healthcheck components metrics are propagated. Failure count: * plugins_healthcheck_jgit_failure_total * plugins_healthcheck_reviewdb_failure_total * plugins_healthcheck_projectslist_failure_total Latency (Timer): the elapsed time for executing that specific healthcheck * plugins_healthcheck_jgit_latency * plugins_healthcheck_projectslist_latency * plugins_healthcheck_reviewdb_latency Feature: Issue 10321 Change-Id: I1b393258dc823b19b74106fa7fce377d5c8bba92
diff --git a/README.md b/README.md index edb538d..fe38bc8 100644 --- a/README.md +++ b/README.md
@@ -39,7 +39,7 @@ - elapsed: elapsed time in millis to perform the check - reviewdb: check that Gerrit can connect and query ReviewDb - projectslist: check that Gerrit can list projects -- auth: check that Gerrit can authenticate users +- jgit: check that Gerrit can access repositories Each check returns a JSON payload with the following information: @@ -72,7 +72,7 @@ "elapsed": 100, "result": "passed" }, - "auth": { + "jgit": { "ts": 139402910202, "elapsed": 80, "result": "passed" @@ -101,7 +101,7 @@ "elapsed": 100, "result": "timeout" }, - "auth": { + "jgit": { "ts": 139402910202, "elapsed": 80, "result": "passed" @@ -109,3 +109,12 @@ } ``` +## Metrics + +As for all other endpoints in Gerrit, some metrics are automatically emitted when the `/config/server/healthcheck~status` +endpoint is hit (thanks to the [Dropwizard](https://metrics.dropwizard.io/3.1.0/manual/core/) library). + +Some additional metrics are also produced to give extra insights on their result about results and latency of healthcheck +sub component, such as jgit, reviewdb, etc. + +More information can be found in the [config.md](resources/Documentation/config.md) file. \ No newline at end of file
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java index 5857bc4..a497a83 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java
@@ -16,8 +16,10 @@ import com.google.gerrit.extensions.registration.DynamicSet; import com.google.inject.AbstractModule; +import com.google.inject.assistedinject.FactoryModuleBuilder; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.JGitHealthCheck; +import com.googlesource.gerrit.plugins.healthcheck.check.MetricsHandler; import com.googlesource.gerrit.plugins.healthcheck.check.ProjectsListHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.ReviewDbHealthCheck; @@ -25,6 +27,11 @@ @Override protected void configure() { + install( + new FactoryModuleBuilder() + .implement(MetricsHandler.class, MetricsHandler.class) + .build(MetricsHandler.Factory.class)); + bindChecker(ReviewDbHealthCheck.class); bindChecker(JGitHealthCheck.class); bindChecker(ProjectsListHealthCheck.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java index 5c8d410..a71e287 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AbstractHealthCheck.java
@@ -27,10 +27,13 @@ public static final long CHECK_TIMEOUT = 500L; private final String name; private final ListeningExecutorService executor; + private final MetricsHandler metricsHandler; - protected AbstractHealthCheck(ListeningExecutorService executor, String name) { + protected AbstractHealthCheck( + ListeningExecutorService executor, String name, MetricsHandler.Factory metricsHandler) { this.executor = executor; this.name = name; + this.metricsHandler = metricsHandler.create(name); } @Override @@ -41,6 +44,7 @@ @Override public Status run() { final long ts = System.currentTimeMillis(); + Status status = null; ListenableFuture<Status> resultFuture = executor.submit( () -> { @@ -53,16 +57,18 @@ } return new Status(healthy, ts, System.currentTimeMillis() - ts); }); - try { - return resultFuture.get(CHECK_TIMEOUT, TimeUnit.MILLISECONDS); + status = resultFuture.get(CHECK_TIMEOUT, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { log.warn("Check {} timed out", name, e); - return new Status(Result.TIMEOUT, ts, System.currentTimeMillis() - ts); + status = new Status(Result.TIMEOUT, ts, System.currentTimeMillis() - ts); } catch (InterruptedException | ExecutionException e) { log.warn("Check {} failed while waiting for its future result", name, e); - return new Status(Result.FAILED, ts, System.currentTimeMillis() - ts); + status = new Status(Result.FAILED, ts, System.currentTimeMillis() - ts); + } finally { + metricsHandler.sendMetrics(status); } + return status; } protected abstract Result doCheck() throws Exception;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java index 355b0cf..6f44ca4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheck.java
@@ -37,6 +37,10 @@ this.ts = ts; this.elapsed = elapsed; } + + protected Boolean isFailure() { + return this.result != Result.PASSED; + } } Status run();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java index a23e0d1..7de042c 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/JGitHealthCheck.java
@@ -31,8 +31,9 @@ public JGitHealthCheck( ListeningExecutorService executor, GitRepositoryManager repositoryManager, - AllProjectsName allProjectsName) { - super(executor, JGIT); + AllProjectsName allProjectsName, + MetricsHandler.Factory metricsHandlerFactory) { + super(executor, JGIT, metricsHandlerFactory); this.repositoryManager = repositoryManager; this.allProjectsName = allProjectsName; }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/MetricsHandler.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/MetricsHandler.java new file mode 100644 index 0000000..c28f52a --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/MetricsHandler.java
@@ -0,0 +1,43 @@ +package com.googlesource.gerrit.plugins.healthcheck.check; + +import com.google.gerrit.metrics.Counter0; +import com.google.gerrit.metrics.Description; +import com.google.gerrit.metrics.MetricMaker; +import com.google.gerrit.metrics.Timer0; +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import java.util.concurrent.TimeUnit; + +public class MetricsHandler { + private final Timer0 latencyMetric; + private final Counter0 failureMetric; + + public interface Factory { + public MetricsHandler create(String name); + } + + @Inject + public MetricsHandler(@Assisted String name, MetricMaker metricMaker) { + this.latencyMetric = + metricMaker.newTimer( + name + "/latency", + new Description(String.format("%s health check latency execution (ms)", name)) + .setCumulative() + .setUnit(Description.Units.MILLISECONDS)); + + this.failureMetric = + metricMaker.newCounter( + name + "/failure", + new Description(String.format("%s healthcheck failures count", name)) + .setCumulative() + .setRate() + .setUnit("failures")); + } + + public void sendMetrics(HealthCheck.Status status) { + latencyMetric.record(status.elapsed, TimeUnit.MILLISECONDS); + if (status.isFailure()) { + failureMetric.increment(); + } + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java index 580f3a0..c31a286 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ProjectsListHealthCheck.java
@@ -30,8 +30,11 @@ private final ListProjects listProjects; @Inject - public ProjectsListHealthCheck(ListeningExecutorService executor, ListProjects listProjects) { - super(executor, PROJECTSLIST); + public ProjectsListHealthCheck( + ListeningExecutorService executor, + ListProjects listProjects, + MetricsHandler.Factory metricHandlerFactory) { + super(executor, PROJECTSLIST, metricHandlerFactory); this.listProjects = listProjects; }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java index 138997b..7bd60cf 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/ReviewDbHealthCheck.java
@@ -26,8 +26,11 @@ private final SchemaFactory<ReviewDb> reviewDb; @Inject - public ReviewDbHealthCheck(ListeningExecutorService executor, SchemaFactory<ReviewDb> reviewDb) { - super(executor, REVIEWDB); + public ReviewDbHealthCheck( + ListeningExecutorService executor, + SchemaFactory<ReviewDb> reviewDb, + MetricsHandler.Factory metricHandlerFactory) { + super(executor, REVIEWDB, metricHandlerFactory); this.reviewDb = reviewDb; }
diff --git a/src/resources/Documentation/config.md b/src/resources/Documentation/config.md new file mode 100644 index 0000000..72a3ad5 --- /dev/null +++ b/src/resources/Documentation/config.md
@@ -0,0 +1,86 @@ +## Metrics + +As for all other endpoints in Gerrit, some metrics are automatically emitted when the `/config/server/healthcheck~status` +endpoint is hit (thanks to the [Dropwizard](https://metrics.dropwizard.io/3.1.0/manual/core/) library). +For example, some of the metrics exposed will be: + +``` +# HELP http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint Generated from Dropwizard metric import (metric=http/server/rest_api/response_bytes/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint, type=com.codahale.metrics.Histogram) +# TYPE http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint summary +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.5",} 308.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.75",} 308.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.95",} 308.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.98",} 310.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.99",} 310.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.999",} 310.0 +http_server_rest_api_response_bytes_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_count 4.0 + +# HELP http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint Generated from Dropwizard metric import (metric=http/server/rest_api/server_latency/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint, type=com.codahale.metrics.Timer) +# TYPE http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint summary +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.5",} 0.008638662 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.75",} 0.008638662 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.95",} 0.010553707 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.98",} 0.147902061 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.99",} 0.147902061 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint{quantile="0.999",} 0.147902061 +http_server_rest_api_server_latency_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_count 4.0 + +# HELP http_server_rest_api_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_total Generated from Dropwizard metric import (metric=http/server/rest_api/count/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint, type=com.codahale.metrics.Meter) +# TYPE http_server_rest_api_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_total counter +http_server_rest_api_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_total 4.0 + +# HELP http_server_rest_api_error_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_500_total Generated from Dropwizard metric import (metric=http/server/rest_api/error_count/healthcheck-com.googlesource.gerrit.plugins.healthcheck.api.HealthCheckStatusEndpoint/500, type=com.codahale.metrics.Meter) +# TYPE http_server_rest_api_error_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_500_total counter +http_server_rest_api_error_count_healthcheck_com_googlesource_gerrit_plugins_healthcheck_api_HealthCheckStatusEndpoint_500_total 2.0 +``` + +However some extra metrics are also emitted to expose more details about the healthcheck result. +Specifically two metrics are emitted for each component contributing to the overall healthcheck result (JGIT, PROJECTLIST, REVIEWDB). +* plugins_healthcheck_<healthcheck_component>_latency: the cumulative latency (in ms) of performing the healthcheck for this specific component +* plugins_healthcheck_jgit_failure_total: the cumulative number of failures for this specific component + +``` +# HELP plugins_healthcheck_jgit_latency Generated from Dropwizard metric import (metric=plugins/healthcheck/jgit/latency, type=com.codahale.metrics.Timer) +# TYPE plugins_healthcheck_jgit_latency summary +plugins_healthcheck_jgit_latency{quantile="0.5",} 0.002 +plugins_healthcheck_jgit_latency{quantile="0.75",} 0.002 +plugins_healthcheck_jgit_latency{quantile="0.95",} 0.002 +plugins_healthcheck_jgit_latency{quantile="0.98",} 0.002 +plugins_healthcheck_jgit_latency{quantile="0.99",} 0.002 +plugins_healthcheck_jgit_latency{quantile="0.999",} 0.002 +plugins_healthcheck_jgit_latency_count 1.0 + +# HELP plugins_healthcheck_projectslist_latency Generated from Dropwizard metric import (metric=plugins/healthcheck/projectslist/latency, type=com.codahale.metrics.Timer) +# TYPE plugins_healthcheck_projectslist_latency summary +plugins_healthcheck_projectslist_latency{quantile="0.5",} 0.001 +plugins_healthcheck_projectslist_latency{quantile="0.75",} 0.001 +plugins_healthcheck_projectslist_latency{quantile="0.95",} 0.001 +plugins_healthcheck_projectslist_latency{quantile="0.98",} 0.001 +plugins_healthcheck_projectslist_latency{quantile="0.99",} 0.001 +plugins_healthcheck_projectslist_latency{quantile="0.999",} 0.001 +plugins_healthcheck_projectslist_latency_count 1.0 + +# HELP plugins_healthcheck_reviewdb_latency Generated from Dropwizard metric import (metric=plugins/healthcheck/reviewdb/latency, type=com.codahale.metrics.Timer) +# TYPE plugins_healthcheck_reviewdb_latency summary +plugins_healthcheck_reviewdb_latency{quantile="0.5",} 0.001 +plugins_healthcheck_reviewdb_latency{quantile="0.75",} 0.001 +plugins_healthcheck_reviewdb_latency{quantile="0.95",} 0.001 +plugins_healthcheck_reviewdb_latency{quantile="0.98",} 0.001 +plugins_healthcheck_reviewdb_latency{quantile="0.99",} 0.001 +plugins_healthcheck_reviewdb_latency{quantile="0.999",} 0.001 +plugins_healthcheck_reviewdb_latency_count 1.0 + +# HELP plugins_healthcheck_jgit_failure_total Generated from Dropwizard metric import (metric=plugins/healthcheck/jgit/failure, type=com.codahale.metrics.Meter) +# TYPE plugins_healthcheck_jgit_failure_total counter +plugins_healthcheck_jgit_failure_total 0.0 + +# HELP plugins_healthcheck_projectslist_failure_total Generated from Dropwizard metric import (metric=plugins/healthcheck/projectslist/failure, type=com.codahale.metrics.Meter) +# TYPE plugins_healthcheck_projectslist_failure_total counter +plugins_healthcheck_projectslist_failure_total 0.0 + +# HELP plugins_healthcheck_reviewdb_failure_total Generated from Dropwizard metric import (metric=plugins/healthcheck/reviewdb/failure, type=com.codahale.metrics.Meter) +# TYPE plugins_healthcheck_reviewdb_failure_total counter +plugins_healthcheck_reviewdb_failure_total 0.0 +``` + +Metrics will be exposed to prometheus by the [metrics-reporter-prometheus](https://gerrit.googlesource.com/plugins/metrics-reporter-prometheus/) plugin.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java index 84ec773..1d46933 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckStatusEndpointTest.java
@@ -18,6 +18,8 @@ import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.extensions.restapi.Response; +import com.google.gerrit.metrics.DisabledMetricMaker; +import com.google.gerrit.metrics.MetricMaker; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; @@ -57,6 +59,7 @@ protected void configure() { DynamicSet.bind(binder(), HealthCheck.class) .toInstance(new TestHealthCheck("checkOk", HealthCheck.Result.PASSED, 1, 2)); + DynamicSet.bind(binder(), MetricMaker.class).toInstance(new DisabledMetricMaker()); } });
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java index 990b4cb..b9beb77 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/JGitHealthCheckTest.java
@@ -18,6 +18,7 @@ import static org.eclipse.jgit.lib.RefUpdate.Result.NEW; import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.gerrit.metrics.DisabledMetricMaker; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.server.config.AllProjectsName; import com.google.gerrit.server.git.GitRepositoryManager; @@ -27,6 +28,7 @@ import com.google.inject.Inject; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result; import com.googlesource.gerrit.plugins.healthcheck.check.JGitHealthCheck; +import com.googlesource.gerrit.plugins.healthcheck.check.MetricsHandler; import java.io.IOException; import java.util.Collections; import java.util.SortedSet; @@ -45,6 +47,13 @@ private AllProjectsName allProjectsName = new AllProjectsName("All-Projects"); private InMemoryRepositoryManager inMemoryRepositoryManager = new InMemoryRepositoryManager(); private PersonIdent personIdent = new PersonIdent("Gerrit Rietveld", "gerrit@rietveld.nl"); + private final MetricsHandler.Factory metricsHandlerFactory = + new MetricsHandler.Factory() { + @Override + public MetricsHandler create(String name) { + return new MetricsHandler("foo", new DisabledMetricMaker()); + } + }; @Inject private ListeningExecutorService executor; @@ -60,14 +69,16 @@ @Test public void shouldBeHealthyWhenJGitIsWorking() { JGitHealthCheck reviewDbCheck = - new JGitHealthCheck(executor, getWorkingRepositoryManager(), allProjectsName); + new JGitHealthCheck( + executor, getWorkingRepositoryManager(), allProjectsName, metricsHandlerFactory); assertThat(reviewDbCheck.run().result).isEqualTo(Result.PASSED); } @Test public void shouldBeUnhealthyWhenJGitIsFailing() { JGitHealthCheck jGitHealthCheck = - new JGitHealthCheck(executor, getFailingGitRepositoryManager(), allProjectsName); + new JGitHealthCheck( + executor, getFailingGitRepositoryManager(), allProjectsName, metricsHandlerFactory); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.FAILED); }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/MetricsHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/MetricsHandlerTest.java new file mode 100644 index 0000000..aa66b1f --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/MetricsHandlerTest.java
@@ -0,0 +1,99 @@ +package com.googlesource.gerrit.plugins.healthcheck; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.gerrit.metrics.Counter0; +import com.google.gerrit.metrics.Description; +import com.google.gerrit.metrics.DisabledMetricMaker; +import com.google.gerrit.metrics.Timer0; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result; +import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Status; +import com.googlesource.gerrit.plugins.healthcheck.check.MetricsHandler; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public class MetricsHandlerTest { + + private class TestMetricsMaker extends DisabledMetricMaker { + private Long failures = 0L; + private Long latency = 0L; + + @Override + public Counter0 newCounter(String name, Description desc) { + return new Counter0() { + @Override + public void incrementBy(long value) { + failures += value; + } + + @Override + public void remove() {} + }; + } + + @Override + public Timer0 newTimer(String name, Description desc) { + return new Timer0() { + @Override + public void remove() {} + + @Override + public void record(long value, TimeUnit unit) { + latency = value; + } + }; + } + } + + @Test + public void shouldSendCounterWhenStatusFailed() { + TestMetricsMaker metricMaker = new TestMetricsMaker(); + MetricsHandler handler = new MetricsHandler("test", metricMaker); + + handler.sendMetrics(new Status(Result.FAILED, 1L, 1L)); + + assertThat(metricMaker.failures).isEqualTo(1L); + } + + @Test + public void shouldSendCounterWhenStatusTimeout() { + TestMetricsMaker metricMaker = new TestMetricsMaker(); + MetricsHandler handler = new MetricsHandler("test", metricMaker); + + handler.sendMetrics(new Status(Result.TIMEOUT, 1L, 1L)); + + assertThat(metricMaker.failures).isEqualTo(1L); + } + + @Test + public void shouldNOTSendCounterWhenStatusSuccess() { + TestMetricsMaker metricMaker = new TestMetricsMaker(); + MetricsHandler handler = new MetricsHandler("test", metricMaker); + + handler.sendMetrics(new Status(Result.PASSED, 1L, 1L)); + + assertThat(metricMaker.failures).isEqualTo(0L); + } + + @Test + public void shouldRecordLatencyWhenSuccess() { + TestMetricsMaker metricMaker = new TestMetricsMaker(); + MetricsHandler handler = new MetricsHandler("test", metricMaker); + Long elapsed = System.currentTimeMillis(); + + handler.sendMetrics(new Status(Result.PASSED, 1L, elapsed)); + + assertThat(metricMaker.latency).isEqualTo(elapsed); + } + + @Test + public void shouldRecordLatencyWhenFailure() { + TestMetricsMaker metricMaker = new TestMetricsMaker(); + MetricsHandler handler = new MetricsHandler("test", metricMaker); + Long elapsed = System.currentTimeMillis(); + + handler.sendMetrics(new Status(Result.FAILED, 1L, elapsed)); + + assertThat(metricMaker.latency).isEqualTo(elapsed); + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java index 5fb2925..942af0c 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ProjectsListHealthCheckTest.java
@@ -19,11 +19,13 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.gerrit.extensions.common.ProjectInfo; import com.google.gerrit.extensions.restapi.BadRequestException; +import com.google.gerrit.metrics.DisabledMetricMaker; import com.google.gerrit.server.project.ListProjects; import com.google.inject.Guice; import com.google.inject.Inject; import com.googlesource.gerrit.plugins.healthcheck.check.AbstractHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck.Result; +import com.googlesource.gerrit.plugins.healthcheck.check.MetricsHandler; import com.googlesource.gerrit.plugins.healthcheck.check.ProjectsListHealthCheck; import java.util.SortedMap; import java.util.TreeMap; @@ -31,6 +33,13 @@ import org.junit.Test; public class ProjectsListHealthCheckTest { + private final MetricsHandler.Factory metricsHandlerFactory = + new MetricsHandler.Factory() { + @Override + public MetricsHandler create(String name) { + return new MetricsHandler("foo", new DisabledMetricMaker()); + } + }; @Inject private ListeningExecutorService executor; @Before @@ -41,14 +50,14 @@ @Test public void shouldBeHealthyWhenListProjectsWorks() { ProjectsListHealthCheck jGitHealthCheck = - new ProjectsListHealthCheck(executor, getWorkingProjectList(0)); + new ProjectsListHealthCheck(executor, getWorkingProjectList(0), metricsHandlerFactory); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.PASSED); } @Test public void shouldBeUnhealthyWhenListProjectsIsFailing() { ProjectsListHealthCheck jGitHealthCheck = - new ProjectsListHealthCheck(executor, getFailingProjectList()); + new ProjectsListHealthCheck(executor, getFailingProjectList(), metricsHandlerFactory); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.FAILED); } @@ -56,7 +65,9 @@ public void shouldBeUnhealthyWhenListProjectsIsTimingOut() { ProjectsListHealthCheck jGitHealthCheck = new ProjectsListHealthCheck( - executor, getWorkingProjectList(AbstractHealthCheck.CHECK_TIMEOUT * 2)); + executor, + getWorkingProjectList(AbstractHealthCheck.CHECK_TIMEOUT * 2), + metricsHandlerFactory); assertThat(jGitHealthCheck.run().result).isEqualTo(Result.TIMEOUT); }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ReviewDbHealthCheckTest.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ReviewDbHealthCheckTest.java index 1e5d712..6c5e008 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ReviewDbHealthCheckTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/ReviewDbHealthCheckTest.java
@@ -18,38 +18,50 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.gerrit.lifecycle.LifecycleManager; +import com.google.gerrit.metrics.DisabledMetricMaker; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.testutil.DisabledReviewDb; import com.google.gerrit.testutil.InMemoryDatabase; import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Guice; import com.google.inject.Inject; +import com.google.inject.Injector; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; +import com.googlesource.gerrit.plugins.healthcheck.check.MetricsHandler; import com.googlesource.gerrit.plugins.healthcheck.check.ReviewDbHealthCheck; import org.junit.Before; import org.junit.Test; public class ReviewDbHealthCheckTest { private SchemaFactory<ReviewDb> workingReviewDbFactory; - + private final MetricsHandler.Factory metricsHandlerFactory = + new MetricsHandler.Factory() { + @Override + public MetricsHandler create(String name) { + return new MetricsHandler("foo", new DisabledMetricMaker()); + } + }; @Inject private ListeningExecutorService executor; @Before public void setUp() throws Exception { - Guice.createInjector(new HealthCheckModule()).injectMembers(this); + Injector testInjector = Guice.createInjector(new HealthCheckModule()); + testInjector.injectMembers(this); + workingReviewDbFactory = InMemoryDatabase.newDatabase(new LifecycleManager()).create(); } @Test public void shouldBeHealthyWhenReviewDbIsWorking() { - ReviewDbHealthCheck reviewDbCheck = new ReviewDbHealthCheck(executor, workingReviewDbFactory); + ReviewDbHealthCheck reviewDbCheck = + new ReviewDbHealthCheck(executor, workingReviewDbFactory, metricsHandlerFactory); assertThat(reviewDbCheck.run().result).isEqualTo(HealthCheck.Result.PASSED); } @Test public void shouldBeUnhealthyWhenReviewDbIsFailing() { ReviewDbHealthCheck reviewDbCheck = - new ReviewDbHealthCheck(executor, getFailingReviewDbProvider()); + new ReviewDbHealthCheck(executor, getFailingReviewDbProvider(), metricsHandlerFactory); assertThat(reviewDbCheck.run().result).isEqualTo(HealthCheck.Result.FAILED); }