You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by sh...@apache.org on 2008/08/04 08:03:46 UTC

svn commit: r682264 - in /lucene/solr/trunk: CHANGES.txt src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java src/webapp/web/WEB-INF/web.xml src/webapp/web/admin/index.jsp

Author: shalin
Date: Sun Aug  3 23:03:46 2008
New Revision: 682264

URL: http://svn.apache.org/viewvc?rev=682264&view=rev
Log:
SOLR-554 -- Hierarchical JDK log level selector for SOLR Admin replaces logging.jsp

Added:
    lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java   (with props)
Modified:
    lucene/solr/trunk/CHANGES.txt
    lucene/solr/trunk/src/webapp/web/WEB-INF/web.xml
    lucene/solr/trunk/src/webapp/web/admin/index.jsp

Modified: lucene/solr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?rev=682264&r1=682263&r2=682264&view=diff
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Sun Aug  3 23:03:46 2008
@@ -339,7 +339,9 @@
 
 67. SOLR-622: SpellCheckComponent supports auto-loading indices on startup and optionally, (re)builds indices
               on newSearcher event, if configured in solrconfig.xml
-              (shalin)              
+              (shalin)
+
+68. SOLR-554: Hierarchical JDK log level selector for SOLR Admin replaces logging.jsp (Sean Timm via shalin)                            
     
 Changes in runtime behavior
  1. SOLR-559: use Lucene updateDocument, deleteDocuments methods.  This

Added: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java?rev=682264&view=auto
==============================================================================
--- lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java (added)
+++ lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java Sun Aug  3 23:03:46 2008
@@ -0,0 +1,288 @@
+/**
+ * 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.solr.servlet;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+
+/**
+ * Admin JDK Logger level report and selection servlet.
+ *
+ * @version $Id$
+ * @since solr 1.3
+ */
+public final class LogLevelSelection extends HttpServlet {
+  public void init() throws ServletException {
+  }
+
+  /**
+   * Processes an HTTP GET request and changes the logging level as
+   * specified.
+   */
+  public void doGet(HttpServletRequest request,
+                    HttpServletResponse response)
+          throws IOException, ServletException {
+    // Output page
+
+    response.setContentType("text/html");
+    PrintWriter out = response.getWriter();
+    out.write("<html><head>\n");
+    out.write("<title>Solr Admin: JDK Log Level Selector</title>\n");
+    out.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"solr-admin.css\" />");
+    out.write("</head><body>\n");
+    out.write("<a href=\".\"><img border=\"0\" align=\"right\" height=\"61\" width=\"142\" src=\"solr-head.gif\" alt=\"Solr\"></a>");
+    out.write("<h1>JDK Log Level Selector</h1>");
+
+    out.write("<p>Below is the complete JDK Log hierarchy with " +
+            "intermediate logger/categories synthesized.  " +
+            "The effective logging level is shown to the " +
+            "far right. If a logger has unset level, then " +
+            "the effective level is that of the nearest ancestor " +
+            "with a level setting.  Note that this only shows " +
+            "JDK Log levels.</p>\n");
+
+    out.write("<form action='");
+    out.write(request.getRequestURI());
+    out.write("' method='POST'>\n");
+
+    out.write("<input type='submit' name='submit' value='set' " +
+            "class='button'>\n");
+    out.write("<input type='submit' name='submit' value='cancel' " +
+            "class='button'>\n");
+    out.write("<br><br>\n");
+
+    out.write("<table cellspacing='2' cellpadding='2'>");
+
+    out.write("<tr bgcolor='#CCCCFF'>" +
+            "<th align=left>Logger/Category name<br>" +
+            "<th colspan=9>Level</th>" +
+            "</tr><tr bgcolor='#CCCCFF'>" +
+            "<td bgcolor='#AAAAAA'>" +
+            "(Dark rows don't yet exist.)</td>");
+
+    for (int j = 0; j < LEVELS.length; ++j) {
+      out.write("<th align=left>");
+      if (LEVELS[j] != null) out.write(LEVELS[j].toString());
+      else out.write("unset");
+      out.write("</th>");
+    }
+    out.write("<th align=left>Effective</th>\n");
+    out.write("</tr>\n");
+
+    Iterator iWrappers = buildWrappers().iterator();
+    while (iWrappers.hasNext()) {
+
+      LogWrapper wrapper = (LogWrapper) iWrappers.next();
+
+      out.write("<tr");
+      if (wrapper.logger == null) {
+        out.write(" bgcolor='#AAAAAA'");
+      }
+      //out.write( ( wrapper.logger != null ) ? "#DDDDDD" : "#AAAAAA" );
+      out.write("><td>");
+      if ("".equals(wrapper.name)) {
+        out.write("root");
+      } else {
+        out.write(wrapper.name);
+      }
+      out.write("</td>\n");
+      for (int j = 0; j < LEVELS.length; ++j) {
+        out.write("<td align=center>");
+        if (!wrapper.name.equals("root") ||
+                (LEVELS[j] != null)) {
+          out.write("<input type='radio' name='");
+          if ("".equals(wrapper.name)) {
+            out.write("root");
+          } else {
+            out.write(wrapper.name);
+          }
+          out.write("' value='");
+          if (LEVELS[j] != null) out.write(LEVELS[j].toString());
+          else out.write("unset");
+          out.write('\'');
+          if (LEVELS[j] == wrapper.level()) out.write(" checked");
+          out.write('>');
+        }
+        out.write("</td>\n");
+      }
+      out.write("<td align=center>");
+      if (wrapper.logger != null) {
+        out.write(getEffectiveLevel(wrapper.logger).toString());
+      }
+      out.write("</td></tr>\n");
+    }
+    out.write("</table>\n");
+
+    out.write("<br>\n");
+    out.write("<input type='submit' name='submit' value='set' " +
+            "class='button'>\n");
+    out.write("<input type='submit' name='submit' value='cancel' " +
+            "class='button'>\n");
+
+    out.write("</form>\n");
+
+    out.write("</body></html>\n");
+  }
+
+
+  public void doPost(HttpServletRequest request,
+                     HttpServletResponse response)
+          throws IOException, ServletException {
+    if (request.getParameter("submit").equals("set")) {
+
+      Map paramMap = request.getParameterMap();
+
+      Iterator iParams = paramMap.entrySet().iterator();
+      while (iParams.hasNext()) {
+        Map.Entry p = (Map.Entry) iParams.next();
+        String name = (String) p.getKey();
+        String value = ((String[]) p.getValue())[0];
+
+        if (name.equals("submit")) continue;
+        Logger logger;
+        LogManager logManager = LogManager.getLogManager();
+        if ("root".equals(name)) {
+          logger = logManager.getLogger("");
+        } else logger = logManager.getLogger(name);
+
+        if ("unset".equals(value)) {
+          if ((logger != null) && (logger.getLevel() != null)) {
+            logger.setLevel(null);
+            log.info("Unset log level on '" + name + "'.");
+          }
+        } else {
+          Level level = Level.parse(value);
+          if (logger == null) logger = Logger.getLogger(name);
+          if (logger.getLevel() != level) {
+            logger.setLevel(level);
+            log.info("Set '" + name + "' to " +
+                    level + " level.");
+          }
+        }
+      }
+    } else {
+      log.fine("Selection form cancelled");
+    }
+
+    // Redirect back to standard get page.
+    response.sendRedirect(request.getRequestURI());
+  }
+
+
+  private Collection buildWrappers() {
+    // Use tree to get sorted results
+    SortedSet<LogWrapper> roots = new TreeSet<LogWrapper>();
+
+    roots.add(LogWrapper.ROOT);
+
+    LogManager logManager = LogManager.getLogManager();
+
+    Enumeration<String> loggerNames = logManager.getLoggerNames();
+    while (loggerNames.hasMoreElements()) {
+      String name = loggerNames.nextElement();
+      Logger logger = Logger.getLogger(name);
+      LogWrapper wrapper = new LogWrapper(logger);
+      roots.remove(wrapper); // Make sure add occurs
+      roots.add(wrapper);
+
+      while (true) {
+        int dot = name.lastIndexOf(".");
+        if (dot < 0) break;
+        name = name.substring(0, dot);
+        roots.add(new LogWrapper(name)); // if not already
+      }
+    }
+
+    return roots;
+  }
+
+  private Level getEffectiveLevel(Logger logger) {
+    Level level = logger.getLevel();
+    if (level != null) {
+      return level;
+    }
+    for (Level l : LEVELS) {
+      if (l == null) {
+        continue;
+      }
+      if (logger.isLoggable(l)) {
+        level = l;
+      }
+    }
+    return level;
+  }
+
+  private static class LogWrapper
+          implements Comparable {
+    public static LogWrapper ROOT =
+            new LogWrapper(LogManager.getLogManager().getLogger(""));
+
+    public LogWrapper(Logger logger) {
+      this.logger = logger;
+      this.name = logger.getName();
+    }
+
+    public LogWrapper(String name) {
+      this.name = name;
+    }
+
+
+    public int compareTo(Object other) {
+      if (this.equals(other)) return 0;
+      if (this == ROOT) return -1;
+      if (other == ROOT) return 1;
+
+      return name.compareTo(((LogWrapper) other).name);
+    }
+
+    public boolean equals(Object other) {
+      return name.equals(((LogWrapper) other).name);
+    }
+
+    public Level level() {
+      if (logger != null) return logger.getLevel();
+      return null;
+    }
+
+    public Logger logger = null;
+    public String name;
+  }
+
+  private static Level[] LEVELS = {
+          null, // aka unset
+          Level.FINEST,
+          Level.FINE,
+          Level.CONFIG,
+          Level.INFO,
+          Level.WARNING,
+          Level.SEVERE,
+          Level.OFF
+          // Level.ALL -- ignore.  It is useless.
+  };
+
+  private Logger log = Logger.getLogger(getClass().getName());
+}

Propchange: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/LogLevelSelection.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: lucene/solr/trunk/src/webapp/web/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/web/WEB-INF/web.xml?rev=682264&r1=682263&r2=682264&view=diff
==============================================================================
--- lucene/solr/trunk/src/webapp/web/WEB-INF/web.xml (original)
+++ lucene/solr/trunk/src/webapp/web/WEB-INF/web.xml Sun Aug  3 23:03:46 2008
@@ -101,6 +101,11 @@
     <load-on-startup>2</load-on-startup>
   </servlet>
 
+  <servlet>
+    <servlet-name>Logging</servlet-name>
+    <servlet-class>org.apache.solr.servlet.LogLevelSelection</servlet-class>
+  </servlet>
+
   <!-- @Deprecated -->
   <servlet>
     <servlet-name>ping</servlet-name>
@@ -117,6 +122,11 @@
     <url-pattern>/update/*</url-pattern>
   </servlet-mapping>
 
+  <servlet-mapping>
+    <servlet-name>Logging</servlet-name>
+    <url-pattern>/admin/logging</url-pattern>
+  </servlet-mapping>
+
   <!-- @Deprecated -->
   <servlet-mapping>
     <servlet-name>ping</servlet-name>

Modified: lucene/solr/trunk/src/webapp/web/admin/index.jsp
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/web/admin/index.jsp?rev=682264&r1=682263&r2=682264&view=diff
==============================================================================
--- lucene/solr/trunk/src/webapp/web/admin/index.jsp (original)
+++ lucene/solr/trunk/src/webapp/web/admin/index.jsp Sun Aug  3 23:03:46 2008
@@ -43,7 +43,7 @@
     [<a href="registry.jsp">Info</a>]
     [<a href="distributiondump.jsp">Distribution</a>]
     [<a href="ping">Ping</a>]
-    [<a href="logging.jsp">Logging</a>]
+    [<a href="logging">Logging</a>]
   </td>
 </tr>