package net.i2p.router.web; import java.io.IOException; import java.io.Writer; import java.text.Collator; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; import java.util.TreeMap; import net.i2p.data.DataHelper; import net.i2p.router.util.EventLog; /** * /events.jsp */ public class EventLogHelper extends FormHandler { protected Writer _out; private long _from, _age; //private long _to = Long.MAX_VALUE; private String _event = ALL; // EventLog name to translated display string private final Map _xevents; private static final String ALL = "all"; private static final String[] _events = new String[] { EventLog.ABORTED, _x("Aborted startup"), EventLog.BECAME_FLOODFILL, _x("Enabled floodfill"), EventLog.CHANGE_IP, _x("Changed IP"), EventLog.CHANGE_PORT, _x("Changed port"), EventLog.CLOCK_SHIFT, _x("Clock shifted"), EventLog.CRASHED, _x("Crashed"), EventLog.CRITICAL, _x("Critical error"), EventLog.INSTALLED, _x("Installed new version"), EventLog.INSTALL_FAILED, _x("Install failed"), EventLog.NETWORK, _x("Network error"), EventLog.NEW_IDENT, _x("New router identity"), EventLog.NOT_FLOODFILL, _x("Disabled floodfill"), EventLog.OOM, _x("Out of memory error"), EventLog.REACHABILITY, _x("Reachability change"), EventLog.REKEYED, _x("New router identity"), EventLog.RESEED, _x("Reseeded router"), EventLog.SOFT_RESTART, _x("Soft restart"), EventLog.STARTED, _x("Started router"), EventLog.STOPPED, _x("Stopped router"), EventLog.UPDATED, _x("Updated router"), EventLog.WATCHDOG, _x("Watchdog warning") }; private static final long DAY = 24*60*60*1000L; private static final long[] _times = { 0, DAY, 7*DAY, 30*DAY, 365*DAY }; public EventLogHelper() { super(); _xevents = new HashMap(1 + (_events.length / 2)); } /** set the defaults after we have a context */ @Override public void setContextId(String contextId) { super.setContextId(contextId); for (int i = 0; i < _events.length; i += 2) { _xevents.put(_events[i], _(_events[i + 1])); } } public void storeWriter(Writer out) { _out = out; } public void setFrom(String s) { try { _age = Long.parseLong(s); if (_age > 0) _from = _context.clock().now() - _age; else _from = 0; } catch (NumberFormatException nfe) { _age = 0; _from = 0; } } //public void setTo(String s) { // _to = s; //} public void setType(String s) { _event = s; } public String getForm() { // too hard to use the standard formhandler.jsi / FormHandler.java session nonces // since graphs.jsp needs the refresh value in its . // So just use the "shared/console nonce". String nonce = CSSHelper.getNonce(); try { _out.write("

" + _("Display Events") + "

"); _out.write("
\n" + "\n" + "\n"); _out.write(_("Events since") + ":
"); _out.write(_("Event type") + ": " + "
"); } catch (IOException ioe) { ioe.printStackTrace(); } return ""; } private void writeOption(String key, String val) throws IOException { _out.write("\n"); } private void writeOption(long age) throws IOException { _out.write("\n"); } public String getEvents() { EventLog ev = _context.router().eventLog(); // oldest first Map events; boolean isAll = ALL.equals(_event); if (isAll) events = ev.getEvents(_from); else events = ev.getEvents(_event, _from); String xev = _xevents.get(_event); if (xev == null) xev = _event; xev = DataHelper.escapeHTML(xev); if (events.isEmpty()) { if (isAll) { if (_age == 0) return _("No events found"); return _("No events found in previous {0}", DataHelper.formatDuration2(_age)); } if (_age == 0) return _("No \"{0}\" events found", xev); return _("No \"{0}\" events found in previous {1}", xev, DataHelper.formatDuration2(_age)); } StringBuilder buf = new StringBuilder(2048); buf.append(""); SimpleDateFormat fmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM); // the router sets the JVM time zone to UTC but saves the original here so we can get it String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); if (systemTimeZone != null) fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); List> entries = new ArrayList>(events.entrySet()); Collections.reverse(entries); for (Map.Entry e : entries) { long time = e.getKey().longValue(); String event = e.getValue(); buf.append(""); } buf.append("
"); buf.append(_("Time")); buf.append(""); if (isAll) { buf.append(_("Event")); buf.append(""); buf.append(_("Details")); } else { buf.append(xev); } buf.append("
"); buf.append(fmt.format(new Date(time))); buf.append(""); if (isAll) { String[] s = event.split(" ", 2); String xs = _xevents.get(s[0]); if (xs == null) xs = s[0]; buf.append(xs); buf.append(""); if (s.length > 1) buf.append(s[1]); } else { buf.append(event); } buf.append("
"); return buf.toString(); } }