From 7e35aee6fe5da80fa12aa597dfa080e1fc723116 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 11 Apr 2025 12:22:22 -0400 Subject: [PATCH] Console: /logs page improvements - Add filter for console log types - Show recent event logs on /logs page - Don't translate log types inside loop --- .../router/web/helpers/EventLogHelper.java | 28 +++- .../i2p/router/web/helpers/LogsHelper.java | 124 ++++++++++++++++-- apps/routerconsole/jsp/logs.jsp | 14 +- .../jsp/themes/console/dark/console.css | 13 +- 4 files changed, 154 insertions(+), 25 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/EventLogHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/EventLogHelper.java index 21bc26b8f..9df6db738 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/EventLogHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/EventLogHelper.java @@ -22,6 +22,8 @@ import net.i2p.util.SystemVersion; */ public class EventLogHelper extends FormHandler { private long _from, _age; + private int _max; + private boolean _reverse = true; //private long _to = Long.MAX_VALUE; private String _event = ALL; // EventLog name to translated display string @@ -82,7 +84,23 @@ public class EventLogHelper extends FormHandler { } catch (NumberFormatException nfe) { _age = 0; _from = 0; - } + } + } + + /** + * @since 0.9.66 for /logs + */ + public void setMax(String s) { + try { + _max = Integer.parseInt(s); + } catch (NumberFormatException nfe) {} + } + + /** + * @since 0.9.66 for /logs + */ + public void setReverse(String s) { + _reverse = Boolean.parseBoolean(s); } //public void setTo(String s) { @@ -191,7 +209,11 @@ public class EventLogHelper extends FormHandler { buf.append(""); List> entries = new ArrayList>(events.entrySet()); - Collections.reverse(entries); + int sz = entries.size(); + if (_max > 0 && sz > _max) + entries = entries.subList(sz - _max, sz); + if (_reverse) + Collections.reverse(entries); for (Map.Entry e : entries) { long time = e.getKey().longValue(); String event = e.getValue(); @@ -210,7 +232,7 @@ public class EventLogHelper extends FormHandler { } else { buf.append(event); } - buf.append(""); + buf.append("\n"); } buf.append(""); return buf.toString(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java index f63e3c8ce..b0a46db93 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java @@ -81,7 +81,17 @@ public class LogsHelper extends HelperBase { * Does not call logManager.flush(); call getCriticalLogs() first to flush */ public String getLogs() { - String str = formatMessages(_context.logManager().getBuffer().getMostRecentMessages()); + return getLogs(null); + } + + /** + * Does not call logManager.flush(); call getCriticalLogs() first to flush + * + * @param filter log type or null + * @since 0.9.66 + */ + public String getLogs(String filter) { + String str = formatMessages(_context.logManager().getBuffer().getMostRecentMessages(), filter); return "

" + _t("File location") + ": " + DataHelper.escapeHTML(_context.logManager().currentFile()) + "

" + str; } @@ -96,7 +106,7 @@ public class LogsHelper extends HelperBase { if (cmgr != null) cmgr.setBubble(PortMapper.SVC_LOGS, 0, null); } - return formatMessages(msgs); + return formatMessages(msgs, null); } /** @@ -260,12 +270,89 @@ public class LogsHelper extends HelperBase { private final static String NL = System.getProperty("line.separator"); /** formats in forward order */ - private String formatMessages(List msgs) { + private String formatMessages(List msgs, String filter) { if (msgs.isEmpty()) return "

" + _t("No log messages") + "

"; boolean colorize = _context.getBooleanPropertyDefaultTrue("routerconsole.logs.color"); StringBuilder buf = new StringBuilder(16*1024); - buf.append("
    "); + buf.append(""); + + // translate once, out of the loops + String tCRIT = _c("CRIT"); + String tERROR = _c("ERROR"); + String tWARN = _c("WARN"); + String tINFO = _c("INFO"); + String tDEBUG = _c("DEBUG"); + + // filter buttons + int crits = 0, errors = 0, warns = 0, infos = 0, debugs = 0, types = 0; + for (String msg : msgs) { + if (msg.contains(tCRIT)) { + if (crits == 0) types++; + crits++; + } else if (msg.contains(tERROR)) { + if (errors == 0) types++; + errors++; + } else if (msg.contains(tWARN)) { + if (warns == 0) types++; + warns++; + } else if (msg.contains(tINFO)) { + if (infos == 0) types++; + infos++; + } else if (msg.contains(tDEBUG)) { + if (debugs == 0) types++; + debugs++; + } + } + if (types > 1) { + buf.append("

    ").append(_t("Filter")).append(": "); + buf.append("    \n"); + if (crits > 0) { + if ("crit".equals(filter)) + buf.append("" + tCRIT + " (" + crits + ")"); + else + buf.append("" + tCRIT + " (" + crits + ")"); + buf.append("     \n"); + } + if (errors > 0) { + if ("error".equals(filter)) + buf.append("" + tERROR + " (" + errors + ")"); + else + buf.append("" + tERROR + " (" + errors + ")"); + buf.append("    \n"); + } + if (warns > 0) { + if ("warn".equals(filter)) + buf.append("" + tWARN + " (" + warns + ")"); + else + buf.append("" + tWARN + " (" + warns + ")"); + buf.append("    \n"); + } + if (infos > 0) { + if ("info".equals(filter)) + buf.append("" + tINFO + " (" + infos + ")"); + else + buf.append("" + tINFO + " (" + infos + ")"); + buf.append("    \n"); + } + if (debugs > 0) { + if ("debug".equals(filter)) + buf.append("" + tDEBUG + " (" + debugs + ")"); + else + buf.append("" + tDEBUG + " (" + debugs + ")"); + buf.append("    \n"); + } + if (filter != null) { + buf.append("\"")\n"); + } + buf.append("

    \n"); + } + + buf.append("
      "); // newest first // for (int i = msgs.size() - 1; i >= 0; i--) { // oldest first @@ -287,33 +374,46 @@ public class LogsHelper extends HelperBase { // replace \n so that exception stack traces will format correctly and will paste nicely into pastebin msg = msg.replace("\n", "
          \n"); msg = msg.replace("\t", "    "); - buf.append("
    • "); if (colorize) { // TODO this would be a lot easier if LogConsoleBuffer stored LogRecords instead of formatted strings String color; // Homeland Security Advisory System // http://www.dhs.gov/xinfoshare/programs/Copy_of_press_release_0046.shtm // but pink instead of yellow for WARN - if (msg.contains(_c("CRIT"))) + if (msg.contains(tCRIT)) { + if (filter != null && !filter.equals("crit")) + continue; color = "#cc0000"; - else if (msg.contains(_c("ERROR"))) + } else if (msg.contains(tERROR)) { + if (filter != null && !filter.equals("error")) + continue; color = "#ff3300"; - else if (msg.contains(_c("WARN"))) + } else if (msg.contains(tWARN)) { // color = "#ff00cc"; poor legibility on light backgrounds + if (filter != null && !filter.equals("warn")) + continue; color = "#bf00df"; - else if (msg.contains(_c("INFO"))) + } else if (msg.contains(tINFO)) { + if (filter != null && !filter.equals("info")) + continue; color = "#333399"; - else + } else { + // skip the "similar messages" lines when filtering + if (filter != null && (!filter.equals("debug") || msg.contains("↑↑↑"))) + continue; color = "#006600"; - buf.append(""); + } + buf.append("
    • "); buf.append(msg); buf.append(""); } else { + // don't bother filtering, colorize is the default + buf.append("
    • "); buf.append(msg); } buf.append("
    • \n"); } - buf.append("
    \n"); + buf.append("

\n"); return buf.toString(); } diff --git a/apps/routerconsole/jsp/logs.jsp b/apps/routerconsole/jsp/logs.jsp index 4b1fc543f..20418cd7b 100644 --- a/apps/routerconsole/jsp/logs.jsp +++ b/apps/routerconsole/jsp/logs.jsp @@ -101,7 +101,13 @@
- +<% + String filter = request.getParameter("f"); + if (filter != null) + out.write(logsHelper.getLogs(filter)); + else + out.write(logsHelper.getLogs()); +%>
@@ -111,6 +117,12 @@

<%=intl._t("View event logs")%>

+ + + + + +

<%=intl._t("Service (Wrapper) Logs")%><% StringBuilder buf = new StringBuilder(24*1024); diff --git a/apps/routerconsole/jsp/themes/console/dark/console.css b/apps/routerconsole/jsp/themes/console/dark/console.css index 4df009fa5..a4b9c2046 100644 --- a/apps/routerconsole/jsp/themes/console/dark/console.css +++ b/apps/routerconsole/jsp/themes/console/dark/console.css @@ -1905,10 +1905,6 @@ p { line-height: 160%; } -p img:first-child { - display: none !important; -} - p:empty { /* kills empty paragraphs that are likely erroneous eg. see top of /profiles?f=1, /profiles */ display: none; @@ -2781,7 +2777,6 @@ li.noevents { /* /eventlogs */ table#eventlog { - margin-top: -21px; margin-bottom: 10px; } @@ -3901,7 +3896,7 @@ form[action="events"]>.formaction { margin-left: -21px; } -.eventspanel th { +#eventlog th { text-align: left; padding-left: 10px; font-size: 10pt; @@ -3909,15 +3904,15 @@ form[action="events"]>.formaction { word-spacing: 0.1em; } -.eventspanel table { +#eventlog table { font-size: 9pt; } -.eventspanel table tr:hover { +#eventlog table tr:hover { background: #002000; } -.eventspanel table td { +#eventlog table td { padding: 5px 10px; }