You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cs...@apache.org on 2025/07/30 11:47:17 UTC

(sling-org-apache-sling-distribution-journal) 01/01: SLING-12872 - Add metric for distribution readiness check

This is an automated email from the ASF dual-hosted git repository.

cschneider pushed a commit to branch SLING-12872
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-journal.git

commit bce5bd8a3fa9311ac4aba311ba18b7c3f89b9b15
Author: Christian Schneider <cs...@adobe.com>
AuthorDate: Wed Jul 30 12:32:18 2025 +0200

    SLING-12872 - Add metric for distribution readiness check
---
 .../journal/bookkeeper/SubscriberMetrics.java           | 17 +++++++++++++++++
 .../distribution/journal/impl/subscriber/IdleCheck.java |  1 +
 .../journal/impl/subscriber/SubscriberReady.java        | 13 ++++++-------
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/main/java/org/apache/sling/distribution/journal/bookkeeper/SubscriberMetrics.java b/src/main/java/org/apache/sling/distribution/journal/bookkeeper/SubscriberMetrics.java
index 3b2cf37..fb6f464 100644
--- a/src/main/java/org/apache/sling/distribution/journal/bookkeeper/SubscriberMetrics.java
+++ b/src/main/java/org/apache/sling/distribution/journal/bookkeeper/SubscriberMetrics.java
@@ -20,8 +20,12 @@ package org.apache.sling.distribution.journal.bookkeeper;
 
 import static org.apache.sling.distribution.journal.metrics.TaggedMetrics.getMetricName;
 
+import java.time.Duration;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
 
@@ -30,6 +34,7 @@ import org.apache.sling.commons.metrics.Histogram;
 import org.apache.sling.commons.metrics.Meter;
 import org.apache.sling.commons.metrics.MetricsService;
 import org.apache.sling.commons.metrics.Timer;
+import org.apache.sling.distribution.journal.impl.subscriber.IdleCheck;
 import org.apache.sling.distribution.journal.messages.PackageStatusMessage.Status;
 import org.apache.sling.distribution.journal.metrics.Tag;
 
@@ -51,6 +56,9 @@ public class SubscriberMetrics {
     // Is the queue editable (true, false)
     private static final String TAG_EDITABLE = "editable";
     
+    // See IdleCheck.ReadyReason
+    private static final String TAG_READY_REASON = "ready_reason";
+    
     public static final String SUB_COMPONENT = "distribution.journal.subscriber.";
     
     private static final String PACKAGE_STATUS_COUNT = SUB_COMPONENT + "package_status_count";
@@ -97,6 +105,8 @@ public class SubscriberMetrics {
 	private static final String FV_MESSAGE_COUNT = SUB_COMPONENT + "fv_message_count";
 	private static final String FV_ERROR_COUNT = SUB_COMPONENT + "fv_error_count";
 
+	private static final String READINESS_DURATION = SUB_COMPONENT + "readiness_duration";
+
     private final MetricsService metricsService;
     private final Tag tagSubName;
     private final Tag tagPubName;
@@ -240,6 +250,13 @@ public class SubscriberMetrics {
     public Timer getInvalidationProcessDuration() {
         return metricsService.timer(getMetricName(INVALIDATION_PROCESS_DURATION, tags));
     }
+    
+    public void readinessDuration(IdleCheck.ReadyReason readyReason, Duration duration) {
+    	List<Tag>_tags = new ArrayList<>(tags);
+    	tags.add(Tag.of(TAG_READY_REASON, readyReason.name()));
+        Timer timer = metricsService.timer(getMetricName(READINESS_DURATION, _tags));
+        timer.update(duration.get(ChronoUnit.MILLIS), TimeUnit.MILLISECONDS);
+    }
 
     public Counter getInvalidationProcessSuccess() {
         return metricsService.counter(getMetricName(INVALIDATION_PROCESS_SUCCESS_COUNT, tags));
diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/IdleCheck.java b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/IdleCheck.java
index 4a8b894..a749345 100644
--- a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/IdleCheck.java
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/IdleCheck.java
@@ -21,6 +21,7 @@ package org.apache.sling.distribution.journal.impl.subscriber;
 import java.io.Closeable;
 
 public interface IdleCheck extends Closeable {
+	enum ReadyReason { IDLE, MAX_RETRIES, LATENCY, FORCE};
 
     /**
      * Called when processing of a message starts
diff --git a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberReady.java b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberReady.java
index 144c216..d09d84f 100644
--- a/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberReady.java
+++ b/src/main/java/org/apache/sling/distribution/journal/impl/subscriber/SubscriberReady.java
@@ -19,7 +19,6 @@
 package org.apache.sling.distribution.journal.impl.subscriber;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.MINUTES;
 
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -87,10 +86,10 @@ public class SubscriberReady implements IdleCheck {
         cancelSchedule();
         long latency = timeProvider.get() - messageCreateTime;
         if (latency < acceptableAgeDiffMs) {
-            ready(String.format("Package message latency %d s < %d s acceptable limit", MILLISECONDS.toSeconds(latency), MILLISECONDS.toSeconds(acceptableAgeDiffMs)));
+            ready(ReadyReason.LATENCY, String.format("Package message latency %d s < %d s acceptable limit", MILLISECONDS.toSeconds(latency), MILLISECONDS.toSeconds(acceptableAgeDiffMs)));
         }
         if (retries > MAX_RETRIES) {
-            ready(String.format("Retries %d > %d", retries, MAX_RETRIES));
+            ready(ReadyReason.MAX_RETRIES, String.format("Retries %d > %d", retries, MAX_RETRIES));
         }
     }
 
@@ -108,7 +107,7 @@ public class SubscriberReady implements IdleCheck {
     }
     
     private void forceIdle() {
-        ready(String.format("Forcing ready after %d s", MILLISECONDS.toSeconds(forceIdleMillies)));
+        ready(ReadyReason.FORCE, String.format("Forcing ready after %d s", MILLISECONDS.toSeconds(forceIdleMillies)));
         cancelSchedule();
     }
     
@@ -119,13 +118,13 @@ public class SubscriberReady implements IdleCheck {
     }
 
     private void idleReady() {
-        ready(String.format("%s ready after being idle for > %d s", subAgentName, MILLISECONDS.toSeconds(idleMillis)));
+        ready(ReadyReason.IDLE, String.format("%s ready after being idle for > %d s", subAgentName, MILLISECONDS.toSeconds(idleMillis)));
     }
     
-    private void ready(String reason) {
+    private void ready(IdleCheck.ReadyReason reason, String reasonSt) {
         long readyTime = timeProvider.get();
         long timeToIdle = MILLISECONDS.toSeconds(readyTime - startTime);
-        log.info("Subscriber becoming ready after timeToIdle={} s. Reason='{}'", timeToIdle, reason);
+        log.info("Subscriber becoming ready after timeToIdle={} s. Reason={}, Details='{}'.", timeToIdle, reason, reasonSt);
         isReady.set(true);
         cancelSchedule();
         forceShedule.cancel(false);