SLING-6142 - Add grep like support in Log Tailer

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1764602 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java b/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
index 74084a3..3c3770f 100644
--- a/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
+++ b/src/main/java/org/apache/sling/commons/log/webconsole/internal/LogWebConsolePlugin.java
@@ -34,7 +34,8 @@
 
 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 @@
         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;
             }
diff --git a/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java b/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
index 30289a2..fb76661 100644
--- a/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
+++ b/src/test/java/org/apache/sling/commons/log/webconsole/ITWebConsoleRemote.java
@@ -24,6 +24,7 @@
 
 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.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 @@
         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) {
diff --git a/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java b/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
index 83686bf..d0239a5 100644
--- a/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
+++ b/src/test/java/org/apache/sling/commons/log/webconsole/remote/WebConsoleTestActivator.java
@@ -23,6 +23,7 @@
 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 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 @@
  * 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 @@
 
     @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 @@
 
         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