You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ch...@apache.org on 2016/02/11 08:15:11 UTC

svn commit: r1729769 - in /sling/trunk/contrib/extensions/tracer/src: main/java/org/apache/sling/tracer/internal/ test/java/org/apache/sling/tracer/internal/

Author: chetanm
Date: Thu Feb 11 07:15:11 2016
New Revision: 1729769

URL: http://svn.apache.org/viewvc?rev=1729769&view=rev
Log:
SLING-5505 - Allow recording of caller stacktrace with the logs

Caller stack trace would be included if `caller` is set to true. One can specify the list packages which should be excluded with `callerPrefixFilter`

Added:
    sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerFilter.java   (with props)
    sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerStackReporter.java   (with props)
    sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/PrefixExcludeFilter.java   (with props)
    sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerStackReporterTest.java   (with props)
    sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/TracerSetTest.java   (with props)
Modified:
    sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/JSONRecording.java
    sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerConfig.java
    sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerSet.java
    sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerFinderTest.java
    sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/JSONRecordingTest.java

Added: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerFilter.java?rev=1729769&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerFilter.java (added)
+++ sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerFilter.java Thu Feb 11 07:15:11 2016
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.tracer.internal;
+
+interface CallerFilter {
+    CallerFilter ALL = new CallerFilter() {
+        @Override
+        public boolean include(StackTraceElement ste) {
+            return true;
+        }
+    };
+
+    boolean include(StackTraceElement ste);
+}

Propchange: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerStackReporter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerStackReporter.java?rev=1729769&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerStackReporter.java (added)
+++ sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerStackReporter.java Thu Feb 11 07:15:11 2016
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.tracer.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+
+class CallerStackReporter {
+    /**
+     * Package names which should be excluded from the stack as they do not serve
+     * any purpose and bloat the size
+     */
+    private static final CallerFilter FWK_EXCLUDE_FILTER = new PrefixExcludeFilter(asList(
+            "java.lang.Thread",
+            "org.apache.sling.tracer.internal",
+            "ch.qos.logback.classic",
+            "sun.reflect",
+            "java.lang.reflect"
+    ));
+    private final CallerFilter callerFilter;
+    private final int start;
+    private final int depth;
+
+    public CallerStackReporter(int depth){
+        this(0, depth, CallerFilter.ALL);
+    }
+
+    public CallerStackReporter(int start, int depth, CallerFilter filter){
+        this.start = start;
+        this.depth = depth;
+        this.callerFilter = filter;
+    }
+
+    public List<StackTraceElement> report(){
+        return report(Thread.currentThread().getStackTrace());
+    }
+
+    public List<StackTraceElement> report(StackTraceElement[] stack){
+        List<StackTraceElement> filteredStack = fwkExcludedStack(stack);
+        List<StackTraceElement> result = new ArrayList<StackTraceElement>(filteredStack.size());
+
+        //Iterate over the filtered stack with limits applicable on that not on actual stack
+        for (int i = 0; i < filteredStack.size(); i++) {
+            StackTraceElement ste = filteredStack.get(i);
+            if (i >=  start && i < depth
+                    && callerFilter.include(ste)){
+                result.add(ste);
+            }
+        }
+        return result;
+    }
+
+    private List<StackTraceElement> fwkExcludedStack(StackTraceElement[] stack) {
+        List<StackTraceElement> filteredStack = new ArrayList<StackTraceElement>(stack.length);
+        for (StackTraceElement ste : stack) {
+            if (FWK_EXCLUDE_FILTER.include(ste)){
+                filteredStack.add(ste);
+            }
+        }
+        return filteredStack;
+    }
+
+    public CallerFilter getCallerFilter() {
+        return callerFilter;
+    }
+
+    public int getStart() {
+        return start;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+}

Propchange: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/CallerStackReporter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/JSONRecording.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/JSONRecording.java?rev=1729769&r1=1729768&r2=1729769&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/JSONRecording.java (original)
+++ sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/JSONRecording.java Thu Feb 11 07:15:11 2016
@@ -32,6 +32,7 @@ import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.zip.GZIPInputStream;
@@ -129,7 +130,7 @@ class JSONRecording implements Recording
         if (logger.startsWith(OAK_QUERY_PKG)) {
             queryCollector.record(level, logger, tuple);
         }
-        logs.add(new LogEntry(level, logger, tuple));
+        logs.add(new LogEntry(tc, level, logger, tuple));
     }
 
     @Override
@@ -233,11 +234,20 @@ class JSONRecording implements Recording
         final String logger;
         final FormattingTuple tuple;
         final long timestamp = System.currentTimeMillis();
+        final List<StackTraceElement> caller;
 
-        private LogEntry(Level level, String logger, FormattingTuple tuple) {
+        private LogEntry(TracerConfig tc, Level level, String logger, FormattingTuple tuple) {
             this.level = level != null ? level : Level.INFO;
             this.logger = logger;
             this.tuple = tuple;
+            this.caller = getCallerData(tc);
+        }
+
+        private static List<StackTraceElement> getCallerData(TracerConfig tc) {
+            if (tc.isReportCallerStack()){
+                return tc.getCallerReporter().report();
+            }
+            return Collections.emptyList();
         }
 
         private static String toString(Object o) {
@@ -274,6 +284,15 @@ class JSONRecording implements Recording
                 jw.key("exception").value(getStackTraceAsString(t));
 
             }
+
+            if (!caller.isEmpty()){
+                jw.key("caller");
+                jw.array();
+                for (StackTraceElement o : caller) {
+                    jw.value(o.toString());
+                }
+                jw.endArray();
+            }
         }
     }
 

Added: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/PrefixExcludeFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/PrefixExcludeFilter.java?rev=1729769&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/PrefixExcludeFilter.java (added)
+++ sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/PrefixExcludeFilter.java Thu Feb 11 07:15:11 2016
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.tracer.internal;
+
+import java.util.List;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Filter which returns false if the package of stack trace element
+ * is part of exclude list of prefixes
+ */
+class PrefixExcludeFilter implements CallerFilter{
+    private final List<String> prefixesToExclude;
+
+    public PrefixExcludeFilter(List<String> prefixes) {
+        this.prefixesToExclude = ImmutableList.copyOf(prefixes);
+    }
+
+    public static PrefixExcludeFilter from(String filter){
+        List<String> prefixes = Splitter.on('|').omitEmptyStrings().trimResults().splitToList(filter);
+        return new PrefixExcludeFilter(prefixes);
+    }
+
+    @Override
+    public boolean include(StackTraceElement ste) {
+        String className = ste.getClassName();
+        for (String prefix : prefixesToExclude){
+            if (className.startsWith(prefix)){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public List<String> getPrefixesToExclude() {
+        return prefixesToExclude;
+    }
+}

Propchange: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/PrefixExcludeFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerConfig.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerConfig.java?rev=1729769&r1=1729768&r2=1729769&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerConfig.java (original)
+++ sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerConfig.java Thu Feb 11 07:15:11 2016
@@ -19,6 +19,9 @@
 
 package org.apache.sling.tracer.internal;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.core.CoreConstants;
 
@@ -37,11 +40,17 @@ class TracerConfig implements Comparable
     private final String loggerName;
     private final Level level;
     private final int depth;
+    private final CallerStackReporter callerReporter;
 
     public TracerConfig(String loggerName, Level level) {
+        this(loggerName, level, null);
+    }
+
+    public TracerConfig(String loggerName, Level level,@Nullable CallerStackReporter reporter) {
         this.loggerName = loggerName;
         this.level = level;
         this.depth = getDepth(loggerName);
+        this.callerReporter = reporter;
     }
 
     public boolean match(String loggerName) {
@@ -59,7 +68,7 @@ class TracerConfig implements Comparable
     }
 
     @Override
-    public int compareTo(TracerConfig o) {
+    public int compareTo(@Nonnull TracerConfig o) {
         int comp = depth > o.depth ? -1 : depth < o.depth ? 1 : 0;
         if (comp == 0) {
             comp = loggerName.compareTo(o.loggerName);
@@ -79,6 +88,14 @@ class TracerConfig implements Comparable
         return level;
     }
 
+    public boolean isReportCallerStack(){
+        return callerReporter != null;
+    }
+
+    public CallerStackReporter getCallerReporter() {
+        return callerReporter;
+    }
+
     private static int getDepth(String loggerName) {
         int depth = 0;
         int fromIndex = 0;

Modified: sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerSet.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerSet.java?rev=1729769&r1=1729768&r2=1729769&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerSet.java (original)
+++ sling/trunk/contrib/extensions/tracer/src/main/java/org/apache/sling/tracer/internal/TracerSet.java Thu Feb 11 07:15:11 2016
@@ -28,6 +28,9 @@ import org.apache.sling.commons.osgi.Man
 
 class TracerSet {
     public static final String LEVEL = "level";
+    public static final String CALLER = "caller";
+    public static final String CALLER_PREFIX_FILTER = "callerPrefixFilter";
+
     private final String name;
     private final List<TracerConfig> configs;
 
@@ -72,8 +75,35 @@ class TracerSet {
 
             //Defaults to Debug
             Level level = Level.valueOf(e.getAttributeValue(LEVEL));
-            result.add(new TracerConfig(category, level));
+            CallerStackReporter reporter = createReporter(e);
+            result.add(new TracerConfig(category, level, reporter));
         }
         return Collections.unmodifiableList(result);
     }
+
+    static CallerStackReporter createReporter(ManifestHeader.Entry e) {
+        String caller = e.getAttributeValue(CALLER);
+        if (caller == null){
+            return null;
+        }
+
+        if ("true".equals(caller)){
+            return new CallerStackReporter(0, Integer.MAX_VALUE, CallerFilter.ALL);
+        }
+
+        CallerFilter filter = CallerFilter.ALL;
+        int depth;
+        try{
+            depth = Integer.parseInt(caller);
+        } catch (NumberFormatException ignore){
+            return null;
+        }
+
+        String filterValue = e.getAttributeValue(CALLER_PREFIX_FILTER);
+        if (filterValue != null){
+            filter = PrefixExcludeFilter.from(filterValue);
+        }
+
+        return new CallerStackReporter(0, depth, filter);
+    }
 }

Modified: sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerFinderTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerFinderTest.java?rev=1729769&r1=1729768&r2=1729769&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerFinderTest.java (original)
+++ sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerFinderTest.java Thu Feb 11 07:15:11 2016
@@ -30,7 +30,7 @@ public class CallerFinderTest {
     @Test
     public void determineCallerSingle() throws Exception{
         CallerFinder cf = new CallerFinder(new String[] {"o.a.s", "o.a.j.o"});
-        StackTraceElement[] stack = createStack(
+        StackTraceElement[] stack = asStack(
                 "o.a.j.o.a",
                 "o.a.j.o.b",
                 "c.a.g.w",
@@ -47,7 +47,7 @@ public class CallerFinderTest {
     @Test
     public void determineCallerMultipleApi() throws Exception{
         CallerFinder cf = new CallerFinder(new String[] {"o.a.s", "o.a.j.o"});
-        StackTraceElement[] stack = createStack(
+        StackTraceElement[] stack = asStack(
                 "o.a.j.o.a",
                 "o.a.j.o.b",
                 "o.a.s.a",
@@ -62,7 +62,7 @@ public class CallerFinderTest {
         assertNotNull(caller);
         assertEquals("c.a.g.w", caller.getClassName());
 
-        stack = createStack(
+        stack = asStack(
                 "o.a.j.o.a",
                 "o.a.j.o.b",
                 "o.a.s.a",
@@ -89,7 +89,7 @@ public class CallerFinderTest {
     @Test
     public void nullCaller() throws Exception{
         CallerFinder cf = new CallerFinder(new String[] {"o.a1.s", "o.a1.j.o"});
-        StackTraceElement[] stack = createStack(
+        StackTraceElement[] stack = asStack(
                 "o.a.j.o.a",
                 "o.a.j.o.b",
                 "o.a.s.a",
@@ -104,7 +104,7 @@ public class CallerFinderTest {
         assertNull(caller);
     }
 
-    private static StackTraceElement[] createStack(String ... stack){
+    static StackTraceElement[] asStack(String ... stack){
         StackTraceElement[] result = new StackTraceElement[stack.length];
         for (int i = 0; i < stack.length; i++) {
             result[i] = new StackTraceElement(stack[i], "foo", null, 0);

Added: sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerStackReporterTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerStackReporterTest.java?rev=1729769&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerStackReporterTest.java (added)
+++ sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerStackReporterTest.java Thu Feb 11 07:15:11 2016
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.tracer.internal;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.apache.sling.tracer.internal.CallerFinderTest.asStack;
+import static org.junit.Assert.assertArrayEquals;
+
+public class CallerStackReporterTest {
+
+    @Test
+    public void startAndStop() throws Exception {
+        StackTraceElement[] s = asStack("0", "1", "2", "3", "4", "5");
+        assertArrayEquals(new String[]{"0", "1", "2", "3"}, arr(new CallerStackReporter(4).report(s)));
+        assertArrayEquals(new String[]{"0"}, arr(new CallerStackReporter(1).report(s)));
+        assertArrayEquals(new String[]{"2", "3"}, arr(new CallerStackReporter(2, 4, CallerFilter.ALL).report(s)));
+    }
+
+    @Test
+    public void filter() throws Exception{
+        StackTraceElement[] s = asStack("0", "1", "2", "3", "4", "5");
+        CallerFilter f = new CallerFilter() {
+            @Override
+            public boolean include(StackTraceElement ste) {
+                String name = ste.getClassName();
+                return name.equals("1") || name.equals("2");
+            }
+        };
+
+        assertArrayEquals(new String[]{"1", "2"}, arr(new CallerStackReporter(0, 4, f).report(s)));
+    }
+
+    @Test
+    public void prefixFilter() throws Exception{
+        StackTraceElement[] s = asStack("a.b.c", "a.b.d", "f.g.h", "m.g.i", "4", "5");
+        assertArrayEquals(new String[]{"a.b.c", "a.b.d", "f.g.h", "m.g.i"},
+                arr(new CallerStackReporter(0, 4, CallerFilter.ALL).report(s)));
+
+        CallerFilter f = PrefixExcludeFilter.from("a.b|f.g");
+        assertArrayEquals(new String[]{"m.g.i"},
+                arr(new CallerStackReporter(0, 4, f).report(s)));
+    }
+
+    private static String[] arr(List<StackTraceElement> list) {
+        String[] result = new String[list.size()];
+        for (int i = 0; i < list.size(); i++) {
+            result[i] = list.get(i).getClassName();
+        }
+        return result;
+    }
+
+}
\ No newline at end of file

Propchange: sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/CallerStackReporterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/JSONRecordingTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/JSONRecordingTest.java?rev=1729769&r1=1729768&r2=1729769&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/JSONRecordingTest.java (original)
+++ sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/JSONRecordingTest.java Thu Feb 11 07:15:11 2016
@@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletReq
 
 import ch.qos.logback.classic.Level;
 import org.apache.sling.commons.json.JSONObject;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.slf4j.MDC;
 import org.slf4j.helpers.FormattingTuple;
@@ -104,12 +103,31 @@ public class JSONRecordingTest {
         assertEquals(tp1.getMessage(), l1.getString("message"));
         assertEquals(1, l1.getJSONArray("params").length());
         assertFalse(l1.has("exception"));
+        assertFalse(l1.has("caller"));
         assertTrue(l1.has("timestamp"));
 
         JSONObject l3 = json.getJSONArray("logs").getJSONObject(2);
         assertNotNull(l3.get("exception"));
     }
 
+    @Test
+    public void logsWithCaller() throws Exception{
+        StringWriter sw = new StringWriter();
+        final JSONRecording r = new JSONRecording("abc", request, true);
+
+        TracerConfig config = new TracerConfig(TracerContext.QUERY_LOGGER,
+                Level.INFO, new CallerStackReporter(20));
+        r.log(config, Level.INFO, "foo", tuple("foo"));
+
+        r.done();
+        r.render(sw);
+
+        JSONObject json = new JSONObject(sw.toString());
+        JSONObject l1 = json.getJSONArray("logs").getJSONObject(0);
+        assertTrue(l1.has("caller"));
+        assertTrue(l1.getJSONArray("caller").length() > 0);
+    }
+
     private static FormattingTuple tuple(String msg){
         return MessageFormatter.format(msg, null);
     }

Added: sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/TracerSetTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/TracerSetTest.java?rev=1729769&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/TracerSetTest.java (added)
+++ sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/TracerSetTest.java Thu Feb 11 07:15:11 2016
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sling.tracer.internal;
+
+import org.apache.sling.commons.osgi.ManifestHeader;
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+
+public class TracerSetTest {
+    
+    @Test
+    public void nullReporter() throws Exception{
+        CallerStackReporter r = TracerSet.createReporter(createEntry("foo"));
+        assertNull(r);
+    }
+
+    @Test
+    public void completeStack() throws Exception{
+        CallerStackReporter r = TracerSet.createReporter(createEntry("foo;caller=true"));
+        assertNotNull(r);
+        assertEquals(Integer.MAX_VALUE, r.getDepth());
+    }
+
+    @Test
+    public void depthSpecified() throws Exception{
+        CallerStackReporter r = TracerSet.createReporter(createEntry("foo;caller=28"));
+        assertNotNull(r);
+        assertEquals(28, r.getDepth());
+    }
+
+    @Test
+    public void invalidDepth() throws Exception{
+        CallerStackReporter r = TracerSet.createReporter(createEntry("foo;caller=abc"));
+        assertNull(r);
+    }
+
+    @Test
+    public void prefixFilter() throws Exception{
+        CallerStackReporter r = TracerSet.createReporter(createEntry("foo;caller=28;callerPrefixFilter=\"a|b\""));
+        assertNotNull(r);
+        assertEquals(28, r.getDepth());
+        assertTrue(r.getCallerFilter() instanceof PrefixExcludeFilter);
+        PrefixExcludeFilter f = (PrefixExcludeFilter) r.getCallerFilter();
+        assertEquals(asList("a", "b"), f.getPrefixesToExclude());
+    }
+
+    private static ManifestHeader.Entry createEntry(String config){
+        ManifestHeader parsedConfig = ManifestHeader.parse(config);
+        return parsedConfig.getEntries()[0];
+    }
+}

Propchange: sling/trunk/contrib/extensions/tracer/src/test/java/org/apache/sling/tracer/internal/TracerSetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native