From a23ea5e5f104f9f3fea8c59ff41f085fd8139b1e Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Thu, 7 Oct 2010 18:39:03 +0000
Subject: [PATCH]     * configlogging.jsp:       - Add easy way to add an
 override       - Make file size specifier more flexible

---
 .../i2p/router/web/ConfigLoggingHandler.java  | 30 +++++--
 .../i2p/router/web/ConfigLoggingHelper.java   | 86 ++++++++++++++++---
 apps/routerconsole/jsp/configlogging.jsp      |  2 +
 core/java/src/net/i2p/util/LogManager.java    | 27 +++---
 4 files changed, 118 insertions(+), 27 deletions(-)

diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHandler.java
index 347cfdab7f..69013f60a4 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHandler.java
@@ -17,6 +17,8 @@ public class ConfigLoggingHandler extends FormHandler {
     private String _recordFormat;
     private String _dateFormat;
     private String _fileSize;
+    private String _newLogClass;
+    private String _newLogLevel = "WARN";
     
     @Override
     protected void processForm() {
@@ -26,7 +28,7 @@ public class ConfigLoggingHandler extends FormHandler {
             // noop
         }
     }
-    
+
     public void setShouldsave(String moo) { _shouldSave = true; }
     
     public void setLevels(String levels) {
@@ -47,6 +49,18 @@ public class ConfigLoggingHandler extends FormHandler {
     public void setLogfilesize(String size) {
         _fileSize = (size != null ? size.trim() : null);
     }
+
+    /** @since 0.8.1 */
+    public void setNewlogclass(String s) {
+        if (s != null && s.length() > 0)
+            _newLogClass = s;
+    }
+    
+    /** @since 0.8.1 */
+    public void setNewloglevel(String s) {
+        if (s != null)
+            _newLogLevel = s;
+    }
     
     /**
      * The user made changes to the config and wants to save them, so
@@ -56,14 +70,18 @@ public class ConfigLoggingHandler extends FormHandler {
     private void saveChanges() {
         boolean shouldSave = false;
         
-        if (_levels != null) {
+        if (_levels != null || _newLogClass != null) {
             try {
                 Properties props = new Properties();
-                props.load(new ByteArrayInputStream(_levels.getBytes()));
+                if (_levels != null)
+                    props.load(new ByteArrayInputStream(_levels.getBytes()));
+                if (_newLogClass != null)
+                    props.setProperty(_newLogClass, _newLogLevel);
                 _context.logManager().setLimits(props);
                 shouldSave = true;
-                addFormNotice("Log limits updated");
+                addFormNotice(_("Log overrides updated"));
             } catch (IOException ioe) {
+                // shouldn't ever happen (BAIS shouldnt cause an IOE)
                 _context.logManager().getLog(ConfigLoggingHandler.class).error("Error reading from the props?", ioe);
                 addFormError("Error updating the log limits - levels not valid");
             }
@@ -83,7 +101,7 @@ public class ConfigLoggingHandler extends FormHandler {
             }
         }
         
-        if (_dateFormat != null) {
+        if (_dateFormat != null && !_dateFormat.equals(_context.logManager().getDateFormatPattern())) {
             boolean valid = _context.logManager().setDateFormat(_dateFormat);
             if (valid) {
                 shouldSave = true;
@@ -139,7 +157,7 @@ public class ConfigLoggingHandler extends FormHandler {
             boolean saved = _context.logManager().saveConfig();
 
             if (saved) 
-                addFormNotice("Log configuration saved and applied successfully");
+                addFormNotice(_("Log configuration saved"));
             else
                 addFormNotice("Error saving the configuration (applied but not saved) - please see the error logs");
         }
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java
index bde9b08930..5b6c742d53 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java
@@ -1,9 +1,13 @@
 package net.i2p.router.web;
 
+import java.util.List;
 import java.util.Iterator;
 import java.util.Properties;
+import java.util.Set;
 import java.util.TreeSet;
 
+import net.i2p.data.DataHelper;
+import net.i2p.util.Log;
 
 public class ConfigLoggingHelper extends HelperBase {
     public ConfigLoggingHelper() {}
@@ -19,18 +23,13 @@ public class ConfigLoggingHelper extends HelperBase {
     }
     public String getMaxFileSize() {
         int bytes = _context.logManager().getFileSize();
-        if (bytes == 0) return "1m";
-        if (bytes > 1024*1024*1024)
-            return (bytes/(1024*1024*1024)) + "g";
-        else if (bytes > 1024*1024)
-            return (bytes/(1024*1024)) + "m";
-        else
-            return (bytes/(1024)) + "k";
+        if (bytes <= 0) return "1 MB";
+        return DataHelper.formatSize2(bytes) + 'B';
     }
     public String getLogLevelTable() {
         StringBuilder buf = new StringBuilder(32*1024);
         Properties limits = _context.logManager().getLimits();
-        TreeSet sortedLogs = new TreeSet();
+        TreeSet<String> sortedLogs = new TreeSet();
         for (Iterator iter = limits.keySet().iterator(); iter.hasNext(); ) {
             String prefix = (String)iter.next();
             sortedLogs.add(prefix);
@@ -46,6 +45,20 @@ public class ConfigLoggingHelper extends HelperBase {
         buf.append("<i>" + _("Add additional logging statements above. Example: net.i2p.router.tunnel=WARN") + "</i><br>");
         buf.append("<i>" + _("Or put entries in the logger.config file. Example: logger.record.net.i2p.router.tunnel=WARN") + "</i><br>");
         buf.append("<i>" + _("Valid levels are DEBUG, INFO, WARN, ERROR, CRIT") + "</i>\n");
+
+      /****
+        // this is too big and ugly
+        if (limits.size() <= 0)
+            return "";
+        buf.append("<table>");
+        for (String prefix : sortedLogs) {
+            buf.append("<tr><td>").append(prefix).append("</td><td>");
+            String level = limits.getProperty(prefix);
+            buf.append(getLogLevelBox("level-" + prefix, level, true)).append("</td></tr>");
+        }
+        buf.append("</table>");
+       ****/
+
         return buf.toString();
     }
 
@@ -53,18 +66,69 @@ public class ConfigLoggingHelper extends HelperBase {
 
     public String getDefaultLogLevelBox() {
         String cur = _context.logManager().getDefaultLimit();
+        return getLogLevelBox("defaultloglevel", cur, false);
+    }
+
+    private String getLogLevelBox(String name, String cur, boolean showRemove) {
         StringBuilder buf = new StringBuilder(128);
-        buf.append("<select name=\"defaultloglevel\">\n");
+        buf.append("<select name=\"").append(name).append("\">\n");
         
         for (int i = 0; i < levels.length; i++) {
             String l = levels[i];
-            buf.append("<option value=\"").append(l).append("\" ");
+            buf.append("<option value=\"").append(l).append('\"');
             if (l.equals(cur))
-                buf.append(" selected=\"true\" ");
+                buf.append(" selected=\"true\"");
             buf.append('>').append(_(l)).append("</option>\n");
         }        
         
+        if (showRemove)
+            buf.append("<option value=\"remove\">").append(_("Remove")).append("</option>");
+        buf.append("</select>\n");
+        return buf.toString();
+    }
+
+    /**
+     *  All the classes the log manager knows about, except ones that
+     *  already have overrides
+     *  @since 0.8.1
+     */
+    public String getNewClassBox() {
+        List<Log> logs = _context.logManager().getLogs();
+        Set limits = _context.logManager().getLimits().keySet();
+        TreeSet<String> sortedLogs = new TreeSet();
+
+        for (Log log : logs) {
+            String name = log.getName();
+            if (!limits.contains(name))
+                sortedLogs.add(name);
+
+            // add higher classes of length 3 or more
+            int dots = 0;
+            int lastdot = -1;
+            int nextdot = 0;
+            while ((nextdot = name.indexOf('.', lastdot + 1)) > 0) {
+                if (++dots >= 3) {
+                    String subst = name.substring(0, nextdot);
+                    if (!limits.contains(subst))
+                        sortedLogs.add(subst);
+                }
+                lastdot = nextdot;
+            }
+        }
+
+        StringBuilder buf = new StringBuilder(65536);
+        buf.append("<select name=\"newlogclass\">\n" +
+                   "<option value=\"\" selected=\"true\">")
+           .append(_("Select a class to add"))
+           .append("</option>\n");
+
+        for (String l : sortedLogs) {
+            buf.append("<option value=\"").append(l).append("\">")
+               .append(l).append("</option>\n");
+        }        
+        
         buf.append("</select>\n");
+        buf.append(getLogLevelBox("newloglevel", "WARN", false));
         return buf.toString();
     }
 }
diff --git a/apps/routerconsole/jsp/configlogging.jsp b/apps/routerconsole/jsp/configlogging.jsp
index 3de8d95bee..ca30423dc2 100644
--- a/apps/routerconsole/jsp/configlogging.jsp
+++ b/apps/routerconsole/jsp/configlogging.jsp
@@ -46,6 +46,8 @@
           </i></td>
         </tr><tr><td class="mediumtags" align="right"><b><%=intl._("Log level overrides")%>:</b></td>
           <td><jsp:getProperty name="logginghelper" property="logLevelTable" /></td>
+        </tr><tr><td class="mediumtags" align="right"><b><%=intl._("New override")%>:</b></td>
+          <td><jsp:getProperty name="logginghelper" property="newClassBox" /></td>
         </tr><tr><td colspan="2"><hr></td>
         </tr><tr class="tablefooter"><td colspan="2"> <div class="formaction">
           <input type="reset" value="<%=intl._("Cancel")%>" >
diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java
index 8bd344d653..d3ece13c56 100644
--- a/core/java/src/net/i2p/util/LogManager.java
+++ b/core/java/src/net/i2p/util/LogManager.java
@@ -156,7 +156,7 @@ public class LogManager {
         return rv;
     }
 
-    /** @deprecated unused */
+    /** now used by ConfigLogingHelper */
     public List<Log> getLogs() {
         return new ArrayList(_logs.values());
     }
@@ -415,15 +415,21 @@ public class LogManager {
 
     /** 
      * Determine how many bytes are in the given formatted string (5m, 60g, 100k, etc)
-     *
+     * Size may be k, m, or g; a trailing b is ignored. Upper-case is allowed.
+     * Spaces between the number and letter is are allowed.
+     * The number may be in floating point.
+     * 4096 min, 2 GB max (returns int)
      */
-    public int getFileSize(String size) {
-        int sz = -1;
+    public static int getFileSize(String size) {
         try {
-            String v = size;
-            char mod = size.toUpperCase().charAt(size.length() - 1);
-            if (!Character.isDigit(mod)) v = size.substring(0, size.length() - 1);
-            int val = Integer.parseInt(v);
+            String v = size.trim().toUpperCase();
+            if (v.length() < 2)
+                return -1;
+            if (v.endsWith("B"))
+                v = v.substring(0, v.length() - 1);
+            char mod = v.charAt(v.length() - 1);
+            if (!Character.isDigit(mod)) v = v.substring(0, v.length() - 1);
+            double val = Double.parseDouble(v);
             switch (mod) {
                 case 'K':
                     val *= 1024;
@@ -438,10 +444,11 @@ public class LogManager {
                     // blah, noop
                     break;
             }
-            return val;
+            if (val < 4096 || val > Integer.MAX_VALUE)
+                return -1;
+            return (int) val;
         } catch (Throwable t) {
             System.err.println("Error parsing config for filesize: [" + size + "]");
-            t.printStackTrace();
             return -1;
         }
     }
-- 
GitLab