This is an automated email from the ASF dual-hosted git repository.
ycai pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-sidecar.git
The following commit(s) were added to refs/heads/trunk by this push:
new 04b0d095 CASSSIDECAR-165: Add metric to report consistency check
duration (#150)
04b0d095 is described below
commit 04b0d095c233f1b2f918446852c326caaf0125a2
Author: Yifan Cai <[email protected]>
AuthorDate: Wed Nov 20 15:21:34 2024 -0800
CASSSIDECAR-165: Add metric to report consistency check duration (#150)
Patch by Yifan Cai; Reviewed by Francisco Guerrero for CASSSIDECAR-165
---
CHANGES.txt | 1 +
.../yaml/AccessControlConfigurationImpl.java | 2 +-
.../cassandra/sidecar/metrics/NamedMetric.java | 18 +++++---
.../cassandra/sidecar/metrics/RestoreMetrics.java | 54 ++++++++--------------
.../restore/RestoreJobConsistencyLevelChecker.java | 15 ++++--
.../routes/restore/BaseRestoreJobTests.java | 3 ++
.../restore/RestoreJobProgressHandlerTest.java | 3 ++
7 files changed, 51 insertions(+), 45 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 4b934420..4b84e967 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,6 @@
1.0.0
-----
+ * Add metric to report consistency check duration (CASSSIDECAR-165)
* Add mTLS Authentication in Sidecar (CASSANDRASC-156)
* Fix dangling restore jobs (CASSANDRASC-155)
* Remove duplicated AbstractSchema class (CASSANDRASC-154)
diff --git
a/server/src/main/java/org/apache/cassandra/sidecar/config/yaml/AccessControlConfigurationImpl.java
b/server/src/main/java/org/apache/cassandra/sidecar/config/yaml/AccessControlConfigurationImpl.java
index ac58f560..a578396d 100644
---
a/server/src/main/java/org/apache/cassandra/sidecar/config/yaml/AccessControlConfigurationImpl.java
+++
b/server/src/main/java/org/apache/cassandra/sidecar/config/yaml/AccessControlConfigurationImpl.java
@@ -67,7 +67,7 @@ public class AccessControlConfigurationImpl implements
AccessControlConfiguratio
}
/**
- * @inheritDoc
+ * {@inheritDoc}
*/
@Override
@JsonProperty
diff --git
a/server/src/main/java/org/apache/cassandra/sidecar/metrics/NamedMetric.java
b/server/src/main/java/org/apache/cassandra/sidecar/metrics/NamedMetric.java
index e5966253..6ceb657e 100644
--- a/server/src/main/java/org/apache/cassandra/sidecar/metrics/NamedMetric.java
+++ b/server/src/main/java/org/apache/cassandra/sidecar/metrics/NamedMetric.java
@@ -59,8 +59,12 @@ public class NamedMetric<T extends Metric>
private final Function<String, T> metricCreator;
private final List<Tag> tags = new ArrayList<>();
private String domain;
- private String name;
+ private String simpleName;
+ /**
+ * Construct the build with the function to create metric
+ * @param metricCreator function to create metric from the canonical
name, which consists of the domain, tags and the simple name.
+ */
public Builder(Function<String, T> metricCreator)
{
this.metricCreator = metricCreator;
@@ -78,14 +82,14 @@ public class NamedMetric<T extends Metric>
}
/**
- * Sets {@code name} of metric.
+ * Sets the simple {@code name} of metric.
*
- * @param name metric name
+ * @param simpleName simply metric name
* @return a reference to this Builder
*/
- public Builder<T> withName(String name)
+ public Builder<T> withName(String simpleName)
{
- return update(b -> b.name = name);
+ return update(b -> b.simpleName = simpleName);
}
/**
@@ -124,7 +128,7 @@ public class NamedMetric<T extends Metric>
{
Objects.requireNonNull(metricCreator);
Objects.requireNonNull(domain);
- Objects.requireNonNull(name);
+ Objects.requireNonNull(simpleName);
return new NamedMetric<>(this);
}
@@ -133,7 +137,7 @@ public class NamedMetric<T extends Metric>
{
String domainPart = domain + '.';
String combinedTags = !tags.isEmpty() ? combineTags() + '.' : "";
- return domainPart + combinedTags + name;
+ return domainPart + combinedTags + simpleName;
}
private String combineTags()
diff --git
a/server/src/main/java/org/apache/cassandra/sidecar/metrics/RestoreMetrics.java
b/server/src/main/java/org/apache/cassandra/sidecar/metrics/RestoreMetrics.java
index 2e845493..ba07169c 100644
---
a/server/src/main/java/org/apache/cassandra/sidecar/metrics/RestoreMetrics.java
+++
b/server/src/main/java/org/apache/cassandra/sidecar/metrics/RestoreMetrics.java
@@ -19,8 +19,10 @@
package org.apache.cassandra.sidecar.metrics;
import java.util.Objects;
+import java.util.function.Function;
import com.codahale.metrics.DefaultSettableGauge;
+import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
@@ -35,6 +37,7 @@ public class RestoreMetrics
protected final MetricRegistry metricRegistry;
public final NamedMetric<Timer> sliceReplicationTime;
public final NamedMetric<Timer> jobCompletionTime;
+ public final NamedMetric<Timer> consistencyCheckTime;
public final NamedMetric<DeltaGauge> successfulJobs;
public final NamedMetric<DeltaGauge> failedJobs;
public final NamedMetric<DefaultSettableGauge<Integer>> activeJobs;
@@ -46,39 +49,22 @@ public class RestoreMetrics
{
this.metricRegistry = Objects.requireNonNull(metricRegistry, "Metric
registry can not be null");
- sliceReplicationTime
- =
NamedMetric.builder(metricRegistry::timer).withDomain(DOMAIN).withName("SliceReplicationTime").build();
- jobCompletionTime
- =
NamedMetric.builder(metricRegistry::timer).withDomain(DOMAIN).withName("JobCompletionTime").build();
- successfulJobs
- = NamedMetric.builder(name -> metricRegistry.gauge(name,
DeltaGauge::new))
- .withDomain(DOMAIN)
- .withName("SuccessfulJobs")
- .build();
- failedJobs
- = NamedMetric.builder(name -> metricRegistry.gauge(name,
DeltaGauge::new))
- .withDomain(DOMAIN)
- .withName("FailedJobs")
- .build();
- activeJobs
- = NamedMetric.builder(name -> metricRegistry.gauge(name, () -> new
DefaultSettableGauge<>(0)))
- .withDomain(DOMAIN)
- .withName("ActiveJobs")
- .build();
- tokenRefreshed
- = NamedMetric.builder(name -> metricRegistry.gauge(name,
DeltaGauge::new))
- .withDomain(DOMAIN)
- .withName("TokenRefreshed")
- .build();
- tokenUnauthorized
- = NamedMetric.builder(name -> metricRegistry.gauge(name,
DeltaGauge::new))
- .withDomain(DOMAIN)
- .withName("TokenUnauthorized")
- .build();
- tokenExpired
- = NamedMetric.builder(name -> metricRegistry.gauge(name,
DeltaGauge::new))
- .withDomain(DOMAIN)
- .withName("TokenExpired")
- .build();
+ sliceReplicationTime = createMetric("SliceReplicationTime",
metricRegistry::timer);
+ jobCompletionTime = createMetric("JobCompletionTime",
metricRegistry::timer);
+ consistencyCheckTime = createMetric("ConsistencyCheckTime",
metricRegistry::timer);
+ successfulJobs = createMetric("SuccessfulJobs", name ->
metricRegistry.gauge(name, DeltaGauge::new));
+ failedJobs = createMetric("FailedJobs", name ->
metricRegistry.gauge(name, DeltaGauge::new));
+ activeJobs = createMetric("ActiveJobs", name ->
metricRegistry.gauge(name, () -> new DefaultSettableGauge<>(0)));
+ tokenRefreshed = createMetric("TokenRefreshed", name ->
metricRegistry.gauge(name, DeltaGauge::new));
+ tokenUnauthorized = createMetric("TokenUnauthorized", name ->
metricRegistry.gauge(name, DeltaGauge::new));
+ tokenExpired = createMetric("TokenExpired", name ->
metricRegistry.gauge(name, DeltaGauge::new));
+ }
+
+ private <T extends Metric> NamedMetric<T> createMetric(String simpleName,
Function<String, T> metricCreator)
+ {
+ return NamedMetric.builder(metricCreator)
+ .withDomain(DOMAIN)
+ .withName(simpleName)
+ .build();
}
}
diff --git
a/server/src/main/java/org/apache/cassandra/sidecar/restore/RestoreJobConsistencyLevelChecker.java
b/server/src/main/java/org/apache/cassandra/sidecar/restore/RestoreJobConsistencyLevelChecker.java
index 47e67763..637e97d9 100644
---
a/server/src/main/java/org/apache/cassandra/sidecar/restore/RestoreJobConsistencyLevelChecker.java
+++
b/server/src/main/java/org/apache/cassandra/sidecar/restore/RestoreJobConsistencyLevelChecker.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,6 +49,9 @@ import
org.apache.cassandra.sidecar.concurrent.TaskExecutorPool;
import org.apache.cassandra.sidecar.db.RestoreJob;
import org.apache.cassandra.sidecar.db.RestoreRange;
import org.apache.cassandra.sidecar.db.RestoreRangeDatabaseAccessor;
+import org.apache.cassandra.sidecar.metrics.RestoreMetrics;
+import org.apache.cassandra.sidecar.metrics.SidecarMetrics;
+import org.apache.cassandra.sidecar.metrics.StopWatch;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
@@ -67,18 +71,21 @@ public class RestoreJobConsistencyLevelChecker
private final RestoreJobDiscoverer restoreJobDiscoverer;
private final RestoreRangeDatabaseAccessor rangeDatabaseAccessor;
private final TaskExecutorPool taskExecutorPool;
+ private final RestoreMetrics restoreMetrics;
private volatile boolean firstTimeSinceImportReady = true;
@Inject
public RestoreJobConsistencyLevelChecker(RingTopologyRefresher
ringTopologyRefresher,
RestoreJobDiscoverer
restoreJobDiscoverer,
RestoreRangeDatabaseAccessor
rangeDatabaseAccessor,
- ExecutorPools executorPools)
+ ExecutorPools executorPools,
+ SidecarMetrics sidecarMetrics)
{
this.ringTopologyRefresher = ringTopologyRefresher;
this.restoreJobDiscoverer = restoreJobDiscoverer;
this.rangeDatabaseAccessor = rangeDatabaseAccessor;
this.taskExecutorPool = executorPools.internal();
+ this.restoreMetrics = sidecarMetrics.server().restore();
}
public Future<RestoreJobProgress> check(RestoreJob restoreJob,
RestoreJobProgressFetchPolicy fetchPolicy)
@@ -90,8 +97,10 @@ public class RestoreJobConsistencyLevelChecker
RestoreJobProgressCollector collector =
RestoreJobProgressCollectors.create(restoreJob, fetchPolicy);
RestoreRangeStatus successCriteria =
restoreJob.expectedNextRangeStatus();
ConsistencyVerifier verifier =
ConsistencyVerifiers.forConsistencyLevel(restoreJob.consistencyLevel,
restoreJob.localDatacenter);
- return ringTopologyRefresher.replicaByTokenRangeAsync(restoreJob)
- .compose(topology ->
findRangesAndConclude(restoreJob, successCriteria, topology, verifier,
collector));
+ Future<RestoreJobProgress> future = ringTopologyRefresher
+
.replicaByTokenRangeAsync(restoreJob)
+ .compose(topology ->
findRangesAndConclude(restoreJob, successCriteria, topology, verifier,
collector));
+ return StopWatch.measureTimeTaken(future, durationNanos ->
restoreMetrics.consistencyCheckTime.metric.update(durationNanos,
TimeUnit.NANOSECONDS));
}
private Future<RestoreJobProgress> findRangesAndConclude(RestoreJob
restoreJob,
diff --git
a/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
b/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
index 45742674..50dc2c3c 100644
---
a/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
+++
b/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
@@ -69,6 +69,7 @@ import
org.apache.cassandra.sidecar.db.RestoreSliceDatabaseAccessor;
import org.apache.cassandra.sidecar.db.schema.SidecarSchema;
import org.apache.cassandra.sidecar.exceptions.RestoreJobFatalException;
import org.apache.cassandra.sidecar.foundation.RestoreJobSecretsGen;
+import org.apache.cassandra.sidecar.metrics.SidecarMetrics;
import org.apache.cassandra.sidecar.restore.RestoreJobDiscoverer;
import org.apache.cassandra.sidecar.restore.RestoreJobManagerGroup;
import org.apache.cassandra.sidecar.restore.RestoreJobProgressTracker;
@@ -98,6 +99,7 @@ public abstract class BaseRestoreJobTests
protected Vertx vertx;
protected Server server;
protected WebClient client;
+ protected SidecarMetrics sidecarMetrics;
protected TestRestoreJobDatabaseAccessor testRestoreJobs;
protected TestRestoreSliceDatabaseAccessor testRestoreSlices;
protected TestRestoreRangeDatabaseAccessor testRestoreRanges;
@@ -114,6 +116,7 @@ public abstract class BaseRestoreJobTests
.with(new
TestModuleOverride())));
vertx = injector.getInstance(Vertx.class);
server = injector.getInstance(Server.class);
+ sidecarMetrics = injector.getInstance(SidecarMetrics.class);
client = WebClient.create(vertx, new WebClientOptions());
testRestoreJobs = (TestRestoreJobDatabaseAccessor)
injector.getInstance(RestoreJobDatabaseAccessor.class);
testRestoreSlices = (TestRestoreSliceDatabaseAccessor)
injector.getInstance(RestoreSliceDatabaseAccessor.class);
diff --git
a/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/RestoreJobProgressHandlerTest.java
b/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/RestoreJobProgressHandlerTest.java
index b478f134..0ade5dc9 100644
---
a/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/RestoreJobProgressHandlerTest.java
+++
b/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/RestoreJobProgressHandlerTest.java
@@ -87,6 +87,7 @@ class RestoreJobProgressHandlerTest extends
BaseRestoreJobTests
asyncResult -> {
RestoreJobProgressResponsePayload respBody =
assertOKResponseAndExtractBody(asyncResult);
assertPendingProgressRespBody(respBody);
+
assertThat(sidecarMetrics.server().restore().consistencyCheckTime.metric.getSnapshot().getValues()).hasSize(1);
});
}
@@ -159,6 +160,7 @@ class RestoreJobProgressHandlerTest extends
BaseRestoreJobTests
assertThat(respBody.abortedRanges()).isNull();
// retrieving all 2 ranges back
assertThat(rangesRetrieved).isEqualTo(2);
+
assertThat(sidecarMetrics.server().restore().consistencyCheckTime.metric.getSnapshot().getValues()).hasSize(1);
});
}
@@ -183,6 +185,7 @@ class RestoreJobProgressHandlerTest extends
BaseRestoreJobTests
assertThat(respBody.abortedRanges()).isNull();
// retrieving all 2 ranges back, while there are 3
ranges in total. One range is satisfied
assertThat(rangesRetrieved).isEqualTo(2);
+
assertThat(sidecarMetrics.server().restore().consistencyCheckTime.metric.getSnapshot().getValues()).hasSize(1);
});
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]