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

joscorbe pushed a commit to branch OAK-11997
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit 480cf45fa909373b0812d26d93143d0f497a5ee0
Author: Jose Cordero <[email protected]>
AuthorDate: Fri Oct 24 11:39:14 2025 +0200

    OAK-11997: Add OSGi config to log slow Mongo queries.
---
 .../oak/plugins/document/Configuration.java        |  8 +++
 .../plugins/document/DocumentNodeStoreService.java |  7 +++
 .../mongo/MongoDocumentNodeStoreBuilderBase.java   | 19 +++++++
 .../DocumentNodeStoreServiceConfigurationTest.java | 59 ++++++++++++++++++++++
 4 files changed, 93 insertions(+)

diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
index a23685f402..9e3d5d798d 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Configuration.java
@@ -39,6 +39,7 @@ import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreServic
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FULL_GC_ENABLED;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_EMBEDDED_VERIFICATION_ENABLED;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FULL_GC_GENERATION;
+import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_MONGO_QUERY_WARNING_THRESHOLD_MILLIS;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_PERFLOGGER_INFO_MILLIS;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_THROTTLING_ENABLED;
 import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.DEFAULT_FULL_GC_MODE;
@@ -516,4 +517,11 @@ import static 
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreServic
                     "merging the changes in case of a conflict. The Default 
value is " + DEFAULT_AVOID_EXCLUSIVE_MERGE_LOCK +
                     " Note that this value can be overridden via framework 
property 'oak.documentstore.avoidExclusiveMergeLock'")
     boolean avoidExclusiveMergeLock() default 
DEFAULT_AVOID_EXCLUSIVE_MERGE_LOCK;
+
+    @AttributeDefinition(
+            name = "MongoDB Query Warning Threshold (in millis)",
+            description = "Threshold in milliseconds for logging warnings when 
MongoDB queries take longer than expected. " +
+                    "A value of 0 disables query time warnings. Default is 0 
(disabled). " +
+                    "Note that this value can be overridden via framework 
property 'oak.mongo.queryWarningThresholdMillis'")
+    long mongoQueryWarningThresholdMillis() default 
DEFAULT_MONGO_QUERY_WARNING_THRESHOLD_MILLIS;
 }
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
index c263934da5..0426d7b2ae 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
@@ -231,6 +231,12 @@ public class DocumentNodeStoreService {
 
     /** OAK-11246 : default millis for perflogger info */
     static final long DEFAULT_PERFLOGGER_INFO_MILLIS = Long.MAX_VALUE;
+
+    /**
+     * Default threshold in milliseconds for logging MongoDB query warnings.
+     * A value of 0 disables query time warnings.
+     */
+    static final long DEFAULT_MONGO_QUERY_WARNING_THRESHOLD_MILLIS = 0;
   
     /**
      * Feature toggle name to enable the prev-no-prop cache.
@@ -392,6 +398,7 @@ public class DocumentNodeStoreService {
             
builder.setMongoWaitQueueTimeoutMillis(config.mongoWaitQueueTimeoutMillis());
             builder.setMongoReadTimeoutMillis(config.mongoReadTimeoutMillis());
             
builder.setMongoMinHeartbeatFrequencyMillis(config.mongoMinHeartbeatFrequencyMillis());
+            
builder.setMongoQueryWarningThresholdMillis(config.mongoQueryWarningThresholdMillis());
             builder.setMongoDB(uri, db, config.blobCacheSize());
             
builder.setCollectionCompressionType(config.collectionCompressionType());
             mkBuilder = builder;
diff --git 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java
 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java
index fd0003c59e..73afe1e1ca 100644
--- 
a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java
+++ 
b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentNodeStoreBuilderBase.java
@@ -48,6 +48,7 @@ public abstract class MongoDocumentNodeStoreBuilderBase<T 
extends MongoDocumentN
     private MongoStatus mongoStatus;
     private long maxReplicationLagMillis = TimeUnit.HOURS.toMillis(6);
     private boolean clientSessionDisabled = false;
+    private long queryWarningThresholdMillis = 0;
     private Integer leaseSocketTimeout;
     private String uri;
     private String name;
@@ -224,6 +225,24 @@ public abstract class MongoDocumentNodeStoreBuilderBase<T 
extends MongoDocumentN
         return thisBuilder();
     }
 
+    /**
+     * Sets the threshold for logging warnings when MongoDB queries exceed 
this duration.
+     *
+     * @param thresholdMillis the threshold in milliseconds. A value of 0 
disables warnings.
+     * @return this builder.
+     */
+    public T setMongoQueryWarningThresholdMillis(long thresholdMillis) {
+        this.queryWarningThresholdMillis = thresholdMillis;
+        return thisBuilder();
+    }
+
+    /**
+     * @return the query warning threshold in milliseconds.
+     */
+    long getQueryWarningThresholdMillis() {
+        return queryWarningThresholdMillis;
+    }
+
     /**
      * @return the lease socket timeout in milliseconds. If none is set, then
      *      zero is returned.
diff --git 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
index 2dc014678e..4955d7fe92 100644
--- 
a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
+++ 
b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceConfigurationTest.java
@@ -468,6 +468,65 @@ public class DocumentNodeStoreServiceConfigurationTest {
         assertEquals(15000, config.mongoHeartbeatFrequencyMillis());
     }
 
+    @Test
+    public void mongoQueryWarningThresholdDefault() throws IOException {
+        Configuration config = createConfiguration();
+        
+        // Verify default value is 0 (disabled)
+        assertEquals("Default query warning threshold should be 0 (disabled)", 
+                0L, config.mongoQueryWarningThresholdMillis());
+    }
+
+    @Test
+    public void mongoQueryWarningThresholdCustomValue() throws IOException {
+        // Set custom threshold value (30000 milliseconds = 30 seconds)
+        addConfigurationEntry(configuration, 
"mongoQueryWarningThresholdMillis", 30000L);
+        
+        Configuration config = createConfiguration();
+        
+        // Verify the custom value is read correctly
+        assertEquals("Custom query warning threshold should be applied", 
+                30000L, config.mongoQueryWarningThresholdMillis());
+    }
+
+    @Test
+    public void mongoQueryWarningThresholdFromPreset() throws IOException {
+        // Set threshold value in preset (45000 milliseconds = 45 seconds)
+        addConfigurationEntry(preset, "mongoQueryWarningThresholdMillis", 
45000L);
+        
+        Configuration config = createConfiguration();
+        
+        // Verify the preset value is read correctly
+        assertEquals("Query warning threshold from preset should be applied", 
+                45000L, config.mongoQueryWarningThresholdMillis());
+    }
+
+    @Test
+    public void mongoQueryWarningThresholdOverridePreset() throws IOException {
+        // Set threshold in both preset and configuration
+        // Configuration should take precedence
+        addConfigurationEntry(preset, "mongoQueryWarningThresholdMillis", 
45000L);
+        addConfigurationEntry(configuration, 
"mongoQueryWarningThresholdMillis", 60000L);
+        
+        Configuration config = createConfiguration();
+        
+        // Verify the configuration value overrides preset
+        assertEquals("Configuration should override preset for query warning 
threshold", 
+                60000L, config.mongoQueryWarningThresholdMillis());
+    }
+
+    @Test
+    public void mongoQueryWarningThresholdDisabled() throws IOException {
+        // Explicitly set threshold to 0 to disable warnings
+        addConfigurationEntry(configuration, 
"mongoQueryWarningThresholdMillis", 0L);
+        
+        Configuration config = createConfiguration();
+        
+        // Verify warnings are disabled
+        assertEquals("Query warning threshold of 0 should disable warnings", 
+                0L, config.mongoQueryWarningThresholdMillis());
+    }
+
     private Configuration createConfiguration() throws IOException {
         return DocumentNodeStoreServiceConfiguration.create(
                 context.componentContext(), configAdmin,

Reply via email to