java.lang.Object
net.i2p.router.MessageHistory

public class MessageHistoryextends Object
Logs router message traffic for debugging and network analysis. Records inbound and outbound messages with timestamps when enabled, providing detailed traffic history for troubleshooting.

This is always instantiated in context and WriteJob runs every minute, (except on Android, we don't set up the WriteJob) but unless router.keepHistory=true it does nothing. It generates a LARGE log file.

  • Field Details

    • _log

      private final Log _log
      Logger for the message history.
    • _context

      private final RouterContext _context
      The router context.
    • _unwrittenEntries

      private final Queue<String> _unwrittenEntries
      The entries not yet written to the file.
    • _historyFile

      private String _historyFile
      The file the entries are written to.
    • _localIdent

      private String _localIdent
      The router hash, written into each entry.
    • _doLog

      private volatile boolean _doLog
      True while logging is enabled.
    • _doPause

      private volatile boolean _doPause
      True to pause the writes briefly.
    • _reinitializeJob

      private final MessageHistory.ReinitializeJob _reinitializeJob
      Job reopening the history file.
    • _writeJob

      private final MessageHistory.WriteJob _writeJob
      Job writing the queued entries.
    • _firstPass

      private volatile boolean _firstPass
      True until the first write completes.
    • NL

      private static final byte[] NL
      The platform line separator bytes.
    • FLUSH_SIZE

      private static final int FLUSH_SIZE
      Entries forcing a write to the file.
      See Also:
    • PROP_KEEP_MESSAGE_HISTORY

      public static final String PROP_KEEP_MESSAGE_HISTORY
      Config property determining whether we want to debug with the message history - default false.
      See Also:
    • PROP_MESSAGE_HISTORY_FILENAME

      public static final String PROP_MESSAGE_HISTORY_FILENAME
      Config property determining where we want to log the message history, if we're keeping one.
      See Also:
    • DEFAULT_MESSAGE_HISTORY_FILENAME

      public static final String DEFAULT_MESSAGE_HISTORY_FILENAME
      Default file name for the message history log.
      See Also:
    • WRITE_DELAY

      private static final long WRITE_DELAY
      Write out the message history once per minute, if not sooner.
      See Also:
  • Constructor Details

    • MessageHistory

      public MessageHistory(RouterContext context)
      Message history for the given context.
      Parameters:
      context - the router context
  • Method Details

    • shutdown

      public void shutdown()
      Shutdown the message history.
    • getDoLog

      public boolean getDoLog()
      Whether the history logging is turned on.
      Returns:
      true if the entries are being logged
    • getFilename

      String getFilename()
      History file name.
      Returns:
      the path of the history log file
    • updateSettings

      private void updateSettings()
      Reads the logging settings from the config.
    • initialize

      public void initialize(boolean forceReinitialize)
      Initialize the message history according to the router's configuration. Call this whenever the router identity changes.
      Parameters:
      forceReinitialize - whether to force reinit
    • tunnelJoined

      public void tunnelJoined(String state, TunnelInfo tunnel)
      The local router has joined the given tunnel operating in the given state.
      Parameters:
      state - {"free inbound", "allocated inbound", "inactive inbound", "outbound", "participant", "pending"}
      tunnel - the tunnel that was joined; a null value logs nothing
    • tunnelJoined

      public void tunnelJoined(String state, HopConfig tunnel)
      The local router has joined the given tunnel operating in the given state.
      Parameters:
      state - {"free inbound", "allocated inbound", "inactive inbound", "outbound", "participant", "pending"}
      tunnel - the tunnel that was joined; a null value logs nothing
    • tunnelDispatched

      public void tunnelDispatched(String info)
      Note that a message was dispatched to a tunnel.
      Parameters:
      info - description of what was dispatched, logged verbatim
    • tunnelDispatched

      public void tunnelDispatched(long messageId, long tunnelId, String type)
      Note that a message was dispatched to a tunnel.
      Parameters:
      messageId - the message ID
      tunnelId - the tunnel ID
      type - the message type being sent
    • tunnelDispatched

      public void tunnelDispatched(long messageId, long tunnelId, long toTunnel, Hash toPeer, String type)
      Note that a message was dispatched to a tunnel.
      Parameters:
      messageId - the message ID
      tunnelId - the tunnel ID
      toTunnel - the ID of the tunnel the message is being forwarded to
      toPeer - the gateway peer, which may be null for a null-hop tunnel
      type - the message type being sent
    • tunnelDispatched

      public void tunnelDispatched(long messageId, long innerMessageId, long tunnelId, String type)
      Note that a message was dispatched to a tunnel.
      Parameters:
      messageId - the message ID
      innerMessageId - the inner message ID
      tunnelId - the tunnel ID
      type - the message type being sent
    • tunnelFailed

      public void tunnelFailed(TunnelId tunnel)
      The local router has detected a failure in the given tunnel.
      Parameters:
      tunnel - the tunnel that failed; a null value logs nothing
    • tunnelValid

      public void tunnelValid(TunnelInfo tunnel, long timeToTest)
      Note that we have reason to believe that the given tunnel is valid, since we could do something through it in the given amount of time.
      Parameters:
      tunnel - tunnel in question
      timeToTest - milliseconds to verify the tunnel
    • tunnelRejected

      public void tunnelRejected(Hash peer, TunnelId tunnel, Hash replyThrough, String reason)
      The peer did not accept the tunnel join for the given reason.
      Parameters:
      peer - the router that rejected the join
      tunnel - the tunnel whose join was refused
      replyThrough - the reply-through router
      reason - the reason reported by the rejecting router
    • tunnelParticipantRejected

      public void tunnelParticipantRejected(Hash peer, String msg)
      Note that a router rejected our request to participate in a tunnel.
      Parameters:
      peer - the router that refused to take part
      msg - the rejection message reported by the peer
    • tunnelRequestTimedOut

      public void tunnelRequestTimedOut(Hash peer, TunnelId tunnel)
      The peer did not accept the tunnel join for the given reason (this may be because of a timeout or an explicit refusal).
      Parameters:
      peer - the peer we tried to build the tunnel with
      tunnel - the tunnel the peer refused to join
    • droppedTunnelMessage

      public void droppedTunnelMessage(TunnelId id, long msgId, Date expiration, Hash from)
      We don't know about the given tunnel, so we are dropping a message sent to us by the given router.
      Parameters:
      id - tunnel ID we received a message for
      msgId - the ID of the dropped message
      expiration - the absolute time the dropped message was due to expire
      from - peer that sent us this message (if known)
    • droppedOtherMessage

      public void droppedOtherMessage(I2NPMessage message, Hash from)
      We received another message we weren't waiting for and don't know how to handle.
      Parameters:
      message - the unexpected message that arrived
      from - the peer that sent it, or null if the sender is unknown
    • droppedInboundMessage

      public void droppedInboundMessage(long messageId, Hash from, String info)
      Note that an inbound message was dropped.
      Parameters:
      messageId - message ID dropped
      from - peer that sent the message (if known)
      info - the reason the message was dropped
    • replyTimedOut

      public void replyTimedOut(OutNetMessage sentMessage)
      The message wanted a reply but no reply came in the time expected.
      Parameters:
      sentMessage - message sent that didn't receive a reply
    • messageProcessingError

      public void messageProcessingError(long messageId, String messageType, String error)
      There was an error processing the given message that was received.
      Parameters:
      messageId - the ID of the message whose processing failed
      messageType - type of message received
      error - error message related to the processing of the message
    • banlist

      public void banlist(Hash peer, String reason)
      We banlisted the peer.
      Parameters:
      peer - the peer added to the banlist
      reason - the ban reason recorded alongside the peer
    • unbanlist

      public void unbanlist(Hash peer)
      We unbanlisted the peer.
      Parameters:
      peer - the peer removed from the banlist
    • sendMessage

      public void sendMessage(String messageType, long messageId, long expiration, Hash peer, boolean sentOk, String info)
      We just sent a message to the peer.
      Parameters:
      messageType - class name for the message object (e.g. DatabaseFindNearestMessage, TunnelMessage, etc)
      messageId - the unique message id of the message being sent (not including any tunnel or garlic wrapped message ids)
      expiration - the expiration for the message sent
      peer - router that the message was sent to
      sentOk - whether the message was sent successfully
      info - extra detail appended to the log line
    • receiveMessage

      public void receiveMessage(String messageType, long messageId, long expiration, Hash from, boolean isValid)
      Note that we just received a message from the peer.
      Parameters:
      messageType - class name for the message object (e.g. DatabaseFindNearestMessage, TunnelMessage, etc)
      messageId - the unique message id of the message received (not including any tunnel or garlic wrapped message ids)
      expiration - the expiration for the message received
      from - router that the message was sent from (or null if we don't know)
      isValid - whether the message is valid (non duplicates, etc)
    • receiveMessage

      public void receiveMessage(String messageType, long messageId, long expiration, boolean isValid)
      Note that we just received a message with no known origin.
      Parameters:
      messageType - class name for the message object (e.g. DatabaseFindNearestMessage, TunnelMessage, etc)
      messageId - the unique message id of the message received
      expiration - the expiration for the message received
      isValid - whether the message is valid (non duplicates, etc)
    • wrap

      public void wrap(String bodyMessageType, long bodyMessageId, String containerMessageType, long containerMessageId)
      Note that we're wrapping the given message within another message (via tunnel/garlic).
      Parameters:
      bodyMessageType - class name for the message contained (e.g. DatabaseFindNearestMessage, DataMessage, etc)
      bodyMessageId - the unique message id of the message
      containerMessageType - class name for the message containing the body message (e.g. TunnelMessage, GarlicMessage, etc)
      containerMessageId - the unique message id of the message
    • receivePayloadMessage

      public void receivePayloadMessage(long messageId)
      Receive a payload message to distribute to a client.
      Parameters:
      messageId - the ID of the payload message received
    • sendPayloadMessage

      public void sendPayloadMessage(long messageId, boolean successfullySent, long timeToSend)
      Note that the sending of a payload message completed (successfully or as a failure).
      Parameters:
      messageId - message that the payload message was sent in
      successfullySent - whether the message was delivered to the peer successfully
      timeToSend - how long it took to send the message
    • receiveTunnelFragment

      public void receiveTunnelFragment(long messageId, int fragmentId, Object status)
      Note that we received a fragment of a tunneled message.
      Parameters:
      messageId - message ID the fragment belongs to
      fragmentId - the index of this fragment within the message, not a message ID
      status - status object for the fragment
    • receiveTunnelFragmentComplete

      public void receiveTunnelFragmentComplete(long messageId)
      Note that all fragments of a tunneled message were received.
      Parameters:
      messageId - message ID that completed
    • droppedFragmentedMessage

      public void droppedFragmentedMessage(long messageId, String status)
      Note that a fragmented message was dropped.
      Parameters:
      messageId - message ID dropped
      status - the reason it was dropped
    • fragmentMessage

      public void fragmentMessage(long messageId, int numFragments, int totalLength, List<Long> messageIds, String msg)
      Note that a message was split into fragments.
      Parameters:
      messageId - message ID fragmented
      numFragments - number of fragments
      totalLength - total length of the message
      messageIds - the fragment message IDs
      msg - extra text appended to the entry, or null to omit it
    • fragmentMessage

      public void fragmentMessage(long messageId, int numFragments, int totalLength, List<Long> messageIds, Object tunnel, String msg)
      Note that a message was split into fragments.
      Parameters:
      messageId - message ID fragmented
      numFragments - number of fragments
      totalLength - total length of the message
      messageIds - the fragment message IDs
      tunnel - tunnel the fragments were sent on
      msg - extra text appended to the entry, or null to omit it
    • droppedTunnelDataMessageUnknown

      public void droppedTunnelDataMessageUnknown(long msgId, long tunnelId)
      Note that a data message for an unknown tunnel was dropped.
      Parameters:
      msgId - message ID dropped
      tunnelId - tunnel ID the message was for
    • droppedTunnelGatewayMessageUnknown

      public void droppedTunnelGatewayMessageUnknown(long msgId, long tunnelId)
      Note that a gateway message for an unknown tunnel was dropped.
      Parameters:
      msgId - message ID dropped
      tunnelId - tunnel ID the message was for
    • getName

      private static final String getName(Hash router)
      Prettify the hash by doing a base64 and returning the first 6 characters.
      Parameters:
      router - the router hash to prettify, may be null
      Returns:
      the first 6 characters of the hash in base64 form, or "UNKNOWN" if the hash is null and "INVALID" if it cannot be encoded
    • getPrefix

      private final String getPrefix()
      Returns the prefix naming this router.
      Returns:
      the prefix text
    • getTime

      private final String getTime(long when)
      Formats a time for a history entry.
      Parameters:
      when - the time to format
      Returns:
      the formatted text
    • addEntry

      private void addEntry(String entry)
      Responsible for adding the entry, flushing if necessary. This is the only thing that adds to _unwrittenEntries.
      Parameters:
      entry - the log entry line to add, ignored if null
    • flushEntries

      private void flushEntries()
      Write out any unwritten entries, and clear the pending list.
    • writeEntries

      private void writeEntries()
      Actually write the specified entries.