You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by GitBox <gi...@apache.org> on 2021/11/23 13:00:50 UTC

[GitHub] [jackrabbit-oak] joerghoh opened a new pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

joerghoh opened a new pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420


   Print the name of the calling class invoking a query in some cases:
   * on traversals and index-traversals
   * when using a deprecated index
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] joerghoh commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
joerghoh commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r756867297



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {

Review comment:
       Of course it is possible to also put ```some_api_used_by_feature_classes_to_execute_query``` (packages and/or classes) to the ```ignoredJavaPackages```. That probably requires some fine-tuning, but it is definitely possible.
   
   When testing with AEM I used this list:
   ```
   org.apache.jackrabbit.oak
   java.lang
   org.apache.sling.jcr.resource.internal.helper.JcrResourceUtil.query
   org.apache.sling.jcr.resource.internal.helper.jcr.BasicQueryLanguageProvider
   org.apache.sling.resourceresolver.impl.providers.stateful.AuthenticatedResourceProvider.findResources
   org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl.findResources
   org.apache.sling.resourceresolver.impl.ResourceResolverImpl.findResources
   com.day.cq.search.impl.builder.QueryImpl
   ```
   
   and got good results (using Oracle Java)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] joerghoh commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
joerghoh commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r756867297



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {

Review comment:
       Of course it is possible to also put ```some_api_used_by_feature_classes_to_execute_query``` (packages and/or classes) to the ```ignoredJavaPackages```. That probably requires some fine-tuning, but it is definitely possible.
   
   When testing with AEM I used this list:
   ```
   org.apache.jackrabbit.oak
   java.lang
   org.apache.sling.jcr.resource.internal.helper.JcrResourceUtil.query
   org.apache.sling.jcr.resource.internal.helper.jcr.BasicQueryLanguageProvider
   org.apache.sling.resourceresolver.impl.providers.stateful.AuthenticatedResourceProvider.findResources
   org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl.findResources
   org.apache.sling.resourceresolver.impl.ResourceResolverImpl.findResources
   com.day.cq.search.impl.builder.QueryImpl
   ```
   
   and got good results.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] joerghoh commented on pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
joerghoh commented on pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#issuecomment-976878351


   Failed because of a test failure of a single build:
   ```
   [ERROR] org.apache.jackrabbit.oak.upgrade.cli.SegmentTarToSegmentAzureTest  Time elapsed: 0.29 s  <<< ERROR!
   
   java.lang.RuntimeException: Unable to start docker container: DockerConfig{name=oak-test-azurite}
   	at com.arakelian.docker.junit.DockerRule$StatementWithDockerRule.evaluate(DockerRule.java:76)
   	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
   	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
   	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
   	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
   	at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
   	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
   	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
   	at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
   	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
   	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
   	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)
   Caused by: java.lang.IllegalStateException: Unable to create container using ContainerConfig{hostname=null, domainname=null, user=null, attachStdin=null, attachStdout=null, attachStderr=null, portSpecs=null, exposedPorts=[10000], tty=null, openStdin=null, stdinOnce=null, env=[executable=blob], cmd=null, image=trekawek/azurite, volumes={}, workingDir=null, entrypoint=null, networkDisabled=false, onBuild=null, labels=null, macAddress=null, hostConfig=HostConfig{binds=null, blkioWeight=null, blkioWeightDevice=null, blkioDeviceReadBps=null, blkioDeviceWriteBps=null, blkioDeviceReadIOps=null, blkioDeviceWriteIOps=null, containerIdFile=null, lxcConf=null, privileged=null, portBindings={10000=[PortBinding{hostIp=0.0.0.0, hostPort=}]}, links=null, publishAllPorts=null, dns=null, dnsOptions=null, dnsSearch=null, extraHosts=null, volumesFrom=null, capAdd=null, capDrop=null, networkMode=null, securityOpt=null, devices=null, memory=null, memorySwap=null, memorySwappiness=null, memoryReservati
 on=null, nanoCpus=null, cpuPeriod=null, cpuShares=null, cpusetCpus=null, cpusetMems=null, cpuQuota=null, cgroupParent=null, restartPolicy=null, logConfig=null, ipcMode=null, ulimits=null, pidMode=null, shmSize=null, oomKillDisable=null, oomScoreAdj=null, autoRemove=null, pidsLimit=null, tmpfs=null, readonlyRootfs=null, storageOpt=null}, stopSignal=null, healthcheck=null, networkingConfig=null}
   	at com.arakelian.docker.junit.Container.createContainer(Container.java:449)
   	at com.arakelian.docker.junit.Container.start(Container.java:251)
   	at com.arakelian.docker.junit.DockerRule$StatementWithDockerRule.evaluate(DockerRule.java:72)
   	... 11 more
   Caused by: com.spotify.docker.client.exceptions.ImageNotFoundException: Image not found: trekawek/azurite
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] fabriziofortino commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
fabriziofortino commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r755913415



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -30,16 +30,19 @@
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.UNIQUE_PROPERTY_NAME;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import javax.jcr.RepositoryException;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.QueryEngine;

Review comment:
       not used

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -30,16 +30,19 @@
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.UNIQUE_PROPERTY_NAME;
 
+import java.util.Arrays;

Review comment:
       not used

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java
##########
@@ -339,7 +340,9 @@ private void fetchNext() {
                     readCount++;
                     if (readCount % 1000 == 0) {
                         FilterIterators.checkReadLimit(readCount, settings);
-                        LOG.warn("Traversed " + readCount + " nodes with filter " + filter + "; consider creating an index or changing the query");
+                        String caller = IndexUtils.getCaller(this.settings.getIgnoredClassNamesInCallTrace());
+                        LOG.warn("Traversed {} nodes with filter {} called by {}; consider creating an index or changing the query" , 
+                                new Object[] {readCount, filter, caller});

Review comment:
       the array creation could be avoided since the method receives a `varargs`
   ```suggestion
                           LOG.warn("Traversed {} nodes with filter {} called by {}; consider creating an index or changing the query" ,
                                   readCount, filter, caller);
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +244,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ingoredJavaPackages parameter is null or empty, the caller is not looked up, but

Review comment:
       typo
   ```suggestion
        * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java
##########
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.index;
 
+import java.util.Arrays;

Review comment:
       minor: this import is not needed

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +244,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ingoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {
+            final String classAndMethod = stackFrame.getClassName() + "." + stackFrame.getMethodName();
+            if (Stream.of(ignoredJavaPackages).noneMatch(pkg -> classAndMethod.startsWith(pkg))) {

Review comment:
       you could use method reference here but I think it's a matter of taste
   ```suggestion
               if (Stream.of(ignoredJavaPackages).noneMatch(classAndMethod::startsWith)) {
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsService.java
##########
@@ -77,6 +77,14 @@
                         "the queryPaths of the index is taken into account."
         )
         String getStrictPathRestrictionsForIndexes() default DISABLED_STRICT_PATH_RESTRICTION;
+        
+        @AttributeDefinition(
+                name="Fully qualified class names to ignore when finding caller",
+                description="If non-empty the query engine logs the query statement plus the java package "
+                        + "which executed this query. This java package is the first package in the call trace"
+                        + "which does not not start with the any of the provided fully qualfied class names (packagename + classname)"

Review comment:
       typos
   
   ```suggestion
                           + "which does not start with any of the provided fully qualified class names (packagename + classname)"
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsService.java
##########
@@ -77,6 +77,14 @@
                         "the queryPaths of the index is taken into account."
         )
         String getStrictPathRestrictionsForIndexes() default DISABLED_STRICT_PATH_RESTRICTION;
+        
+        @AttributeDefinition(
+                name="Fully qualified class names to ignore when finding caller",
+                description="If non-empty the query engine logs the query statement plus the java package "
+                        + "which executed this query. This java package is the first package in the call trace"

Review comment:
       missing space at the end
   
   ```suggestion
                           + "which executed this query. This java package is the first package in the call trace "
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
##########
@@ -24,12 +24,14 @@
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.PROPERTY_NAMES;
 
+import java.util.Arrays;

Review comment:
       not used

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +244,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ingoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {
+            final String classAndMethod = stackFrame.getClassName() + "." + stackFrame.getMethodName();
+            if (Stream.of(ignoredJavaPackages).noneMatch(pkg -> classAndMethod.startsWith(pkg))) {
+                return classAndMethod;
+            }
+        }
+        // if every element is ignored, we assume it's an internal request
+        return "(internal)";

Review comment:
       If you want to be more `functional` this should produce the same results. Notice that the stream is lazy, the `findFirst` basically returns the first element filtered in the previous call without filtering the entire stream. WARN: I have not tested it :-)
   
   ```suggestion
           return Arrays.stream(Thread.currentThread().getStackTrace())
                   .map(sf -> sf.getClassName() + "." + sf.getMethodName())
                   .filter(classAndMethod -> Stream.of(ignoredJavaPackages).noneMatch(classAndMethod::startsWith))
                   .findFirst()
                   .orElse("(internal)");
   ```

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineSettingsService.java
##########
@@ -77,6 +77,14 @@
                         "the queryPaths of the index is taken into account."
         )
         String getStrictPathRestrictionsForIndexes() default DISABLED_STRICT_PATH_RESTRICTION;
+        
+        @AttributeDefinition(
+                name="Fully qualified class names to ignore when finding caller",
+                description="If non-empty the query engine logs the query statement plus the java package "
+                        + "which executed this query. This java package is the first package in the call trace"
+                        + "which does not not start with the any of the provided fully qualfied class names (packagename + classname)"
+                )
+        String[] ignoredClassNamesinCallTrace() default {};

Review comment:
       this should be camel cased
   
   ```suggestion
           String[] ignoredClassNamesInCallTrace() default {};
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] joerghoh commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
joerghoh commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r756650313



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {

Review comment:
       We are interested in the first class name, which is is not ignored. This should give us a good understanding which code is triggering a query (assuming that we put all relevant packages/classes into the ```ignoredJavaPackages``` which do not help us to determine that).




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] joerghoh commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
joerghoh commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r756271628



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +244,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ingoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {
+            final String classAndMethod = stackFrame.getClassName() + "." + stackFrame.getMethodName();
+            if (Stream.of(ignoredJavaPackages).noneMatch(pkg -> classAndMethod.startsWith(pkg))) {
+                return classAndMethod;
+            }
+        }
+        // if every element is ignored, we assume it's an internal request
+        return "(internal)";

Review comment:
       Hm,  nested streaming ... I don't get my head around it. I rather leave it as is and just implement the method reference mentioned above.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] averma21 commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
averma21 commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r757408789



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {

Review comment:
       okay, if the results are good, then let's go ahead :)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] averma21 commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
averma21 commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r756596980



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {

Review comment:
       This means we are capturing the top of the stack first. Wondering if we would be interested in bottom of the stack or top. 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] fabriziofortino merged pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
fabriziofortino merged pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] averma21 commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
averma21 commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r756773415



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";
+        }
+
+        // With java9 we would use https://docs.oracle.com/javase/9/docs/api/java/lang/StackWalker.html
+        final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        for (StackTraceElement stackFrame : callStack) {

Review comment:
       Yes, my question was more around - are we trying to obtain the generic feature which caused this query or, the api which actually executed this query. The stack would be something like -
   ```
   ---other ignored packages---
   ignored oak query classes
   some_api_used_by_feature_classes_to_execute_query
   high_level_feature_classes
   ---ignored packages---
   ```
   Iterating the stack from top to bottom and capturing the first non-ignored class would provide the api used by feature classes, not exactly those features which are using this query.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [jackrabbit-oak] thomasmueller commented on a change in pull request #420: OAK-9624 print the name of the calling class invoking a query in some cases

Posted by GitBox <gi...@apache.org>.
thomasmueller commented on a change in pull request #420:
URL: https://github.com/apache/jackrabbit-oak/pull/420#discussion_r758388981



##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexUtils.java
##########
@@ -241,4 +242,37 @@ public static String getAsyncLaneName(NodeState idxState, String indexPath, Prop
         }
         return null;
     }
+
+    /**
+     * Retrieves the calling class and method from the call stack; this is determined by unwinding
+     * the stack until it finds a combination of full qualified classname + method (separated by ".") which
+     * do not start with any of the values provided by the ignoredJavaPackages parameters. If the provided
+     * parameters cover all stack frames, the whole query is considered to be internal, where the 
+     * actual caller doesn't matter (or cannot be determined clearly). In this case a short message
+     * indicating this is returned.
+     *
+     * If the ignoredJavaPackages parameter is null or empty, the caller is not looked up, but
+     * instead it is assumed, that the feature is not configured; in that case a short messages
+     * is returned indicating that the feature is not configured.
+     *
+     * @param ignoredJavaPackages the java packages or class names
+     * @return the calling class or another non-null value
+     */
+    @NotNull
+    public static String getCaller(@Nullable String[] ignoredJavaPackages) {
+        if (ignoredJavaPackages == null || ignoredJavaPackages.length == 0) {
+            return "(<function not configured>)";

Review comment:
       Couldn't we use some sensible defaults? For example, ignore oak.apache.jackrabbit.

##########
File path: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java
##########
@@ -339,7 +339,9 @@ private void fetchNext() {
                     readCount++;
                     if (readCount % 1000 == 0) {
                         FilterIterators.checkReadLimit(readCount, settings);
-                        LOG.warn("Traversed " + readCount + " nodes with filter " + filter + "; consider creating an index or changing the query");
+                        String caller = IndexUtils.getCaller(this.settings.getIgnoredClassNamesInCallTrace());

Review comment:
       Nit: "this." is unnecessary here (see line above)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org