Author: chetanm
Date: Thu Oct 13 06:20:31 2016
New Revision: 1764602

URL: http://svn.apache.org/viewvc?rev=1764602&view=rev
Log:
SLING-6142 - Add grep like support in Log Tailer

Added:
    
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/FilteringListener.java
   (with props)
    
sling/trunk/bundles/commons/log/src/test/java/org/apache/sling/commons/log/logback/internal/FilteringListenerTest.java
   (with props)
Modified:
    
sling/trunk/bundles/commons/log-webconsole/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
    
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
    
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
    
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
    
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/LogPanel.java
    
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/TailerOptions.java

Modified: 
sling/trunk/bundles/commons/log-webconsole/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log-webconsole/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java?rev=1764602&r1=1764601&r2=1764602&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log-webconsole/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
 (original)
+++ 
sling/trunk/bundles/commons/log-webconsole/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
 Thu Oct 13 06:20:31 2016
@@ -34,7 +34,8 @@ import org.apache.sling.commons.osgi.Pro
 
 import static 
org.apache.sling.commons.log.logback.webconsole.LogPanel.APP_ROOT;
 import static 
org.apache.sling.commons.log.logback.webconsole.LogPanel.PARAM_APPENDER_NAME;
-import static 
org.apache.sling.commons.log.logback.webconsole.LogPanel.PARAM_NUM_OF_LINES;
+import static 
org.apache.sling.commons.log.logback.webconsole.LogPanel.PARAM_TAIL_NUM_OF_LINES;
+import static 
org.apache.sling.commons.log.logback.webconsole.LogPanel.PARAM_TAIL_GREP;
 import static 
org.apache.sling.commons.log.logback.webconsole.LogPanel.PATH_TAILER;
 
 public class LogWebConsolePlugin extends SimpleWebConsolePlugin {
@@ -62,13 +63,14 @@ public class LogWebConsolePlugin extends
         if (req.getPathInfo() != null) {
             if (req.getPathInfo().endsWith(PATH_TAILER)) {
                 String appenderName = req.getParameter(PARAM_APPENDER_NAME);
+                String regex = req.getParameter(PARAM_TAIL_GREP);
                 addNoSniffHeader(resp);
                 if (appenderName == null) {
                     pw.printf("Provide appender name via [%s] request 
parameter%n", PARAM_APPENDER_NAME);
                     return;
                 }
-                int numOfLines = 
PropertiesUtil.toInteger(req.getParameter(PARAM_NUM_OF_LINES), 0);
-                TailerOptions opts = new TailerOptions(numOfLines);
+                int numOfLines = 
PropertiesUtil.toInteger(req.getParameter(PARAM_TAIL_NUM_OF_LINES), 0);
+                TailerOptions opts = new TailerOptions(numOfLines, regex);
                 panel.tail(pw, appenderName, opts);
                 return;
             }

Modified: 
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java?rev=1764602&r1=1764601&r2=1764602&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
 (original)
+++ 
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
 Thu Oct 13 06:20:31 2016
@@ -24,6 +24,7 @@ import java.io.IOException;
 
 import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
 import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.TextPage;
 import com.gargoylesoftware.htmlunit.WebClient;
 import com.gargoylesoftware.htmlunit.html.HtmlPage;
 import org.apache.commons.io.FilenameUtils;
@@ -39,7 +40,10 @@ import org.ops4j.pax.exam.spi.PaxExamRun
 import org.ops4j.pax.tinybundles.core.TinyBundle;
 import org.osgi.framework.Constants;
 
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
@@ -132,6 +136,22 @@ public class ITWebConsoleRemote extends
         assertEquals("nosniff", nosniffHeader);
     }
 
+    @Test
+    public void tailerGrep() throws Exception{
+        TextPage page  = 
webClient.getPage(prepareUrl("slinglog/tailer.txt?name=FILE&tail=-1"));
+        String text = page.getContent();
+
+        assertThat(text, containsString(WebConsoleTestActivator.FOO_LOG));
+        assertThat(text, containsString(WebConsoleTestActivator.BAR_LOG));
+
+        page  = 
webClient.getPage(prepareUrl("slinglog/tailer.txt?name=FILE&tail=1000&grep="+WebConsoleTestActivator.FOO_LOG));
+        text = page.getContent();
+
+        //With grep pattern specified we should only see foo and not bar
+        assertThat(text, containsString(WebConsoleTestActivator.FOO_LOG));
+        assertThat(text, not(containsString(WebConsoleTestActivator.BAR_LOG)));
+    }
+
     @AfterClass
     public static void tearDownClass() {
         if (testContainer != null) {

Modified: 
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java?rev=1764602&r1=1764601&r2=1764602&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
 (original)
+++ 
sling/trunk/bundles/commons/log-webconsole/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
 Thu Oct 13 06:20:31 2016
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.Logger;
@@ -36,6 +37,7 @@ import ch.qos.logback.core.spi.FilterRep
 import org.apache.sling.commons.log.logback.ConfigProvider;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.slf4j.LoggerFactory;
 import org.slf4j.Marker;
 import org.xml.sax.InputSource;
 
@@ -44,6 +46,10 @@ import org.xml.sax.InputSource;
  * Used by ITWebConsoleRemote to assert output of the WebConsole Plugin
  */
 public class WebConsoleTestActivator implements BundleActivator {
+    private final org.slf4j.Logger log = LoggerFactory.getLogger(getClass());
+    public static final String FOO_LOG = "WebConsoleTestActivator-Foo";
+    public static final String BAR_LOG = "WebConsoleTestActivator-BAR";
+
     public static Class[] BUNDLE_CLASS_NAMES = {
         WebConsoleTestActivator.class,
         WebConsoleTestTurboFilter.class,
@@ -54,7 +60,6 @@ public class WebConsoleTestActivator imp
 
     @Override
     public void start(BundleContext context) throws Exception {
-
         context.registerService(TurboFilter.class.getName(),new 
WebConsoleTestTurboFilter(),null);
         context.registerService(ConfigProvider.class.getName(),new 
WebConsoleTestConfigProvider(),null);
 
@@ -74,6 +79,15 @@ public class WebConsoleTestActivator imp
 
         String configAsString = "<included> <!-- WebConsoleTestComment 
--></included>";
         context.registerService(String.class.getName(), configAsString, props);
+
+        emitLogs();
+    }
+
+    private void emitLogs() throws InterruptedException {
+        //Let system stabalize so that log statement gets logged to file 
instead of console
+        TimeUnit.SECONDS.sleep(2);
+        log.info(FOO_LOG);
+        log.info(BAR_LOG);
     }
 
     @Override

Added: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/FilteringListener.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/FilteringListener.java?rev=1764602&view=auto
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/FilteringListener.java
 (added)
+++ 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/FilteringListener.java
 Thu Oct 13 06:20:31 2016
@@ -0,0 +1,75 @@
+/*
+ * 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.commons.log.logback.internal;
+
+import java.io.PrintWriter;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+import org.apache.sling.commons.log.logback.internal.Tailer.TailerListener;
+
+class FilteringListener implements TailerListener {
+    public static final String MATCH_ALL = "*";
+    private final Pattern pattern;
+    private final String regex;
+    private final PrintWriter pw;
+
+    /**
+     * Constructs a FilteringListener which uses regex pattern to
+     * determine which lines need to be included
+     *
+     * @param pw writer to write the tailed line
+     * @param regex pattern used to filter line. If null or "*"
+     *              then all lines would be included. Regex can be simple
+     *              string also. In that case search would be done in a
+     *              case insensitive way
+     */
+    public FilteringListener(PrintWriter pw, String regex){
+        this.pw = pw;
+        this.regex = regex != null ? regex.toLowerCase(Locale.ENGLISH) : null;
+        this.pattern = createPattern(regex);
+    }
+
+    @Override
+    public void handle(String line) {
+        if (include(line)){
+            pw.println(line);
+        }
+    }
+
+    private boolean include(String line) {
+        if (pattern == null) {
+            return true;
+        }
+
+        String lc = line.toLowerCase(Locale.ENGLISH);
+        if (lc.contains(regex)){
+            return true;
+        }
+        return pattern.matcher(line).matches();
+    }
+
+    private static Pattern createPattern(String regex) {
+        if (regex == null || MATCH_ALL.equals(regex)){
+            return null;
+        }
+        return Pattern.compile(regex);
+    }
+}

Propchange: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/FilteringListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java?rev=1764602&r1=1764601&r2=1764602&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
 (original)
+++ 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/SlingLogPanel.java
 Thu Oct 13 06:20:31 2016
@@ -90,17 +90,11 @@ public class SlingLogPanel implements Lo
     private final LogbackManager logbackManager;
     private final BundleContext bundleContext;
 
-    private final String labelRes;
-
-    private final int labelResLen;
-
     private static final org.slf4j.Logger log = 
LoggerFactory.getLogger(SlingLogPanel.class);
 
     public SlingLogPanel(final LogbackManager logbackManager, final 
BundleContext bundleContext) {
         this.logbackManager = logbackManager;
         this.bundleContext = bundleContext;
-        this.labelRes = '/' + APP_ROOT + '/';
-        this.labelResLen = labelRes.length() - 1;
     }
 
     @Override
@@ -572,7 +566,7 @@ public class SlingLogPanel implements Lo
                         if (numOfLines == 0){
                             numOfLines = 
logbackManager.getLogConfigManager().getNumOfLines();
                         }
-                        new Tailer(pw, numOfLines).tail(file);
+                        new Tailer(new FilteringListener(pw, opts.getRegex()), 
numOfLines).tail(file);
                     }
                 }
                 return;
@@ -584,11 +578,13 @@ public class SlingLogPanel implements Lo
     private String getLinkedName(FileAppender<ILoggingEvent> appender) throws 
UnsupportedEncodingException {
         String fileName = appender.getFile();
         String name = appender.getName();
-        return String.format("File : [<a href=\"%s/%s?%s=%d&%s=%s\">%s</a>] 
%s",
+        return String.format("File : [<a 
href=\"%s/%s?%s=%d&%s=%s&%s=%s\">%s</a>] %s",
                 APP_ROOT,
                 PATH_TAILER,
-                PARAM_NUM_OF_LINES,
+                PARAM_TAIL_NUM_OF_LINES,
                 logbackManager.getLogConfigManager().getNumOfLines(),
+                PARAM_TAIL_GREP,
+                FilteringListener.MATCH_ALL,
                 PARAM_APPENDER_NAME,
                 URLEncoder.encode(name, "UTF-8"),
                 XmlUtil.escapeXml(name),

Modified: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/LogPanel.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/LogPanel.java?rev=1764602&r1=1764601&r2=1764602&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/LogPanel.java
 (original)
+++ 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/LogPanel.java
 Thu Oct 13 06:20:31 2016
@@ -29,11 +29,16 @@ public interface LogPanel {
     /**
      * Request param name to control number of lines to include in the log
      */
-    String PARAM_NUM_OF_LINES = "tail";
+    String PARAM_TAIL_NUM_OF_LINES = "tail";
     /**
      * Request param name for appender name
      */
     String PARAM_APPENDER_NAME = "name";
+
+    /**
+     * Request param capturing the regular expression to search
+     */
+    String PARAM_TAIL_GREP = "grep";
     /**
      * Let the path end with extension. In that case WebConsole logic would by 
pass this request's
      * response completely

Modified: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/TailerOptions.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/TailerOptions.java?rev=1764602&r1=1764601&r2=1764602&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/TailerOptions.java
 (original)
+++ 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/webconsole/TailerOptions.java
 Thu Oct 13 06:20:31 2016
@@ -21,9 +21,11 @@ package org.apache.sling.commons.log.log
 
 public final class TailerOptions {
     private final int numOfLines;
+    private final String regex;
 
-    public TailerOptions(int numOfLines) {
+    public TailerOptions(int numOfLines, String regex) {
         this.numOfLines = numOfLines;
+        this.regex = regex;
     }
 
     public boolean tailAll() {
@@ -33,4 +35,8 @@ public final class TailerOptions {
     public int getNumOfLines() {
         return numOfLines;
     }
+
+    public String getRegex() {
+        return regex;
+    }
 }

Added: 
sling/trunk/bundles/commons/log/src/test/java/org/apache/sling/commons/log/logback/internal/FilteringListenerTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/test/java/org/apache/sling/commons/log/logback/internal/FilteringListenerTest.java?rev=1764602&view=auto
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/test/java/org/apache/sling/commons/log/logback/internal/FilteringListenerTest.java
 (added)
+++ 
sling/trunk/bundles/commons/log/src/test/java/org/apache/sling/commons/log/logback/internal/FilteringListenerTest.java
 Thu Oct 13 06:20:31 2016
@@ -0,0 +1,78 @@
+/*
+ * 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.commons.log.logback.internal;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.sling.commons.log.logback.internal.Tailer.TailerListener;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.*;
+
+public class FilteringListenerTest {
+
+    private StringWriter sw = new StringWriter();
+    private PrintWriter pw = new PrintWriter(sw);
+
+    @Test
+    public void nullPattern() throws Exception{
+        TailerListener l = new FilteringListener(pw, null);
+        l.handle("foo");
+        assertThat(sw.toString(), containsString("foo"));
+    }
+
+    @Test
+    public void allPattern() throws Exception{
+        TailerListener l = new FilteringListener(pw, 
FilteringListener.MATCH_ALL);
+        l.handle("foo");
+        assertThat(sw.toString(), containsString("foo"));
+    }
+
+    @Test
+    public void basicPattern() throws Exception{
+        TailerListener l = new FilteringListener(pw, "foo");
+        l.handle("foo");
+        assertThat(sw.toString(), containsString("foo"));
+
+        l.handle("bar");
+        assertThat(sw.toString(), not(containsString("bar")));
+
+        l.handle("foo bar");
+        assertThat(sw.toString(), containsString("foo bar"));
+    }
+
+    @Test
+    public void regexPattern() throws Exception{
+        TailerListener l = new FilteringListener(pw, "foo.*bar");
+        l.handle("foo");
+        assertThat(sw.toString(), not(containsString("foo")));
+
+        l.handle("bar");
+        assertThat(sw.toString(), not(containsString("bar")));
+
+        l.handle("foo talks to bar");
+        assertThat(sw.toString(), containsString("bar"));
+        assertThat(sw.toString(), containsString("talks"));
+    }
+
+}
\ No newline at end of file

Propchange: 
sling/trunk/bundles/commons/log/src/test/java/org/apache/sling/commons/log/logback/internal/FilteringListenerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to