public SyslogMessage parse() throws SyslogParserException {
    final SyslogMessage syslogMessage = new SyslogMessage();

    String message = getText();

    int lbIdx = message.indexOf('<');
    int rbIdx = message.indexOf('>');

    if (lbIdx < 0 || rbIdx < 0 || lbIdx >= (rbIdx - 1)) {
      LogUtils.warnf(this, "Syslogd received an unparsable message!");
    }

    int priCode = 0;
    String priStr = message.substring(lbIdx + 1, rbIdx);

    try {
      priCode = Integer.parseInt(priStr);
    } catch (final NumberFormatException ex) {
      LogUtils.debugf(this, "ERROR Bad priority code '%s'", priStr);
    }

    LogUtils.tracef(this, "priority code = %d", priCode);

    syslogMessage.setFacility(SyslogFacility.getFacilityForCode(priCode));
    syslogMessage.setSeverity(SyslogSeverity.getSeverityForCode(priCode));

    message = message.substring(rbIdx + 1, message.length());

    final Matcher idMatcher = m_messageIdPattern.matcher(message);
    if (idMatcher.find()) {
      final String messageId = idMatcher.group(2);
      LogUtils.tracef(this, "found message ID '%s'", messageId);
      syslogMessage.setMessageID(messageId);
      message = message.substring(idMatcher.group(1).length() - 1);
    }

    LogUtils.tracef(this, "message = %s", message);

    Matcher oldDateMatcher = m_oldDatePattern.matcher(message);
    if (!oldDateMatcher.find()) {
      oldDateMatcher = null;
    }
    LogUtils.tracef(this, "stdMsg = %s", Boolean.toString(oldDateMatcher != null));

    if (!this.find()) {
      if (traceEnabled()) {
        LogUtils.tracef(
            this, "Lenient Syslog pattern '%s' did not match '%s'", getPattern(), getText());
      }
      return null;
    }

    String timestamp;

    if (oldDateMatcher == null) {
      final Matcher stampMatcher = m_datePattern.matcher(message);
      if (stampMatcher.find()) {
        timestamp = stampMatcher.group(2);
        LogUtils.tracef(this, "found timestamp '%s'", timestamp);
        //                message = message.substring(stampMatcher.group(1).length());
      } else {
        try {
          timestamp = SyslogTimeStamp.getInstance().format(new Date());
        } catch (final IllegalArgumentException ex) {
          LogUtils.debugf(this, "ERROR INTERNAL DATE ERROR!");
          timestamp = "";
        }
      }
    } else {
      timestamp = oldDateMatcher.group(1);
      message = oldDateMatcher.replaceFirst("");
    }

    LogUtils.tracef(this, "timestamp = %s", timestamp);
    syslogMessage.setDate(parseDate(timestamp));

    // These 2 debugs will aid in analyzing the regexes as syslog seems
    // to differ a lot depending on implementation or message structure.

    if (LogUtils.isTraceEnabled(this)) {
      LogUtils.tracef(this, "message = %s", message);
      LogUtils.tracef(this, "pattern = %s", m_forwardingPattern);
      LogUtils.tracef(this, "host group = %d", m_matchingGroupHost);
      LogUtils.tracef(this, "message group = %d", m_matchingGroupMessage);
    }

    // We will also here find out if, the host needs to
    // be replaced, the message matched to a UEI, and
    // last if we need to actually hide the message.
    // this being potentially helpful in avoiding showing
    // operator a password or other data that should be
    // confidential.

    final Pattern pattern = m_forwardingPattern;
    final Matcher m = pattern.matcher(message);

    /*
     * We matched on a regexp for host/message pair.
     * This can be a forwarded message as in BSD Style
     * or syslog-ng.
     */

    if (m.matches()) {

      final String matchedMessage = m.group(m_matchingGroupMessage);
      syslogMessage.setMatchedMessage(matchedMessage);

      if (LogUtils.isTraceEnabled(this)) {
        LogUtils.tracef(
            this, "Syslog message '%s' matched regexp '%s'", message, m_forwardingPattern);
        LogUtils.tracef(this, "Found host '%s'", m.group(m_matchingGroupHost));
        LogUtils.tracef(this, "Found message '%s'", matchedMessage);
      }

      syslogMessage.setHostName(m.group(m_matchingGroupHost));

      message = matchedMessage;
    } else {
      LogUtils.debugf(this, "Regexp not matched: %s", message);
      return null;
    }

    lbIdx = message.indexOf('[');
    rbIdx = message.indexOf(']');
    final int colonIdx = message.indexOf(':');
    final int spaceIdx = message.indexOf(' ');

    int processId = 0;
    String processName = "";
    String processIdStr = "";

    if (lbIdx < (rbIdx - 1) && colonIdx == (rbIdx + 1) && spaceIdx == (colonIdx + 1)) {
      processName = message.substring(0, lbIdx);
      processIdStr = message.substring(lbIdx + 1, rbIdx);
      message = message.substring(colonIdx + 2);

      try {
        processId = Integer.parseInt(processIdStr);
      } catch (final NumberFormatException ex) {
        LogUtils.debugf(this, "Bad process id '%s'", processIdStr);
        processId = 0;
      }
    } else if (lbIdx < 0 && rbIdx < 0 && colonIdx > 0 && spaceIdx == (colonIdx + 1)) {
      processName = message.substring(0, colonIdx);
      message = message.substring(colonIdx + 2);
    }

    syslogMessage.setProcessId(processId);
    syslogMessage.setProcessName(processName);
    syslogMessage.setMessage(message.trim());

    return syslogMessage;
  }
Ejemplo n.º 2
0
  public static SyslogMessage parseMessage(byte[] bytes) {
    ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
    byteBuffer.put(bytes);
    byteBuffer.rewind();

    Character charFound = (char) byteBuffer.get();

    SyslogFacility foundFacility = null;
    SyslogSeverity foundSeverity = null;

    while (charFound != '<') {
      // Ignore noise in beginning of message.
      charFound = (char) byteBuffer.get();
    }
    char priChar = 0;
    if (charFound == '<') {
      int facility = 0;

      while (Character.isDigit(priChar = (char) (byteBuffer.get() & 0xff))) {
        facility *= 10;
        facility += Character.digit(priChar, 10);
      }
      foundFacility = SyslogFacility.values()[facility >> 3];
      foundSeverity = SyslogSeverity.values()[facility & 0x07];
    }

    if (priChar != '>') {
      // Invalid character - this is not a well defined syslog message.
      LOG.error("Invalid syslog message, missing a > in the Facility/Priority part");
    }

    SyslogMessage syslogMessage = new SyslogMessage();
    boolean isRfc5424 = false;
    // Read next character
    charFound = (char) byteBuffer.get();
    // If next character is a 1, we have probably found an rfc 5424 message
    // message
    if (charFound == '1') {
      syslogMessage = new Rfc5424SyslogMessage();
      isRfc5424 = true;
    } else {
      // go back one to parse the rfc3164 date
      byteBuffer.position(byteBuffer.position() - 1);
    }

    syslogMessage.setFacility(foundFacility);
    syslogMessage.setSeverity(foundSeverity);

    if (!isRfc5424) {
      // Parse rfc 3164 date
      syslogMessage.setTimestamp(parseRfc3164Date(byteBuffer));
    } else {

      charFound = (char) byteBuffer.get();
      if (charFound != ' ') {
        LOG.error("Invalid syslog message, missing a mandatory space after version");
      }

      // This should be the timestamp
      StringBuilder date = new StringBuilder();
      while ((charFound = (char) (byteBuffer.get() & 0xff)) != ' ') {
        date.append(charFound);
      }

      syslogMessage.setTimestamp(DatatypeConverter.parseDateTime(date.toString()));
    }

    // The host is the char sequence until the next ' '

    StringBuilder host = new StringBuilder();
    while ((charFound = (char) (byteBuffer.get() & 0xff)) != ' ') {
      host.append(charFound);
    }

    syslogMessage.setHostname(host.toString());

    if (isRfc5424) {
      Rfc5424SyslogMessage rfc5424SyslogMessage = (Rfc5424SyslogMessage) syslogMessage;
      StringBuilder appName = new StringBuilder();
      while ((charFound = (char) (byteBuffer.get() & 0xff)) != ' ') {
        appName.append(charFound);
      }
      rfc5424SyslogMessage.setAppName(appName.toString());

      StringBuilder procId = new StringBuilder();
      while ((charFound = (char) (byteBuffer.get() & 0xff)) != ' ') {
        procId.append(charFound);
      }
      rfc5424SyslogMessage.setProcId(procId.toString());

      StringBuilder msgId = new StringBuilder();
      while ((charFound = (char) (byteBuffer.get() & 0xff)) != ' ') {
        msgId.append(charFound);
      }
      rfc5424SyslogMessage.setMsgId(msgId.toString());

      StringBuilder structuredData = new StringBuilder();
      boolean inblock = false;
      while (((charFound = (char) (byteBuffer.get() & 0xff)) != ' ') || inblock) {
        if (charFound == '[') {
          inblock = true;
        }
        if (charFound == ']') {
          inblock = false;
        }
        structuredData.append(charFound);
      }
      rfc5424SyslogMessage.setStructuredData(structuredData.toString());
    }

    StringBuilder msg = new StringBuilder();
    while (byteBuffer.hasRemaining()) {
      charFound = (char) (byteBuffer.get() & 0xff);
      msg.append(charFound);
    }

    syslogMessage.setLogMessage(msg.toString());
    LOG.trace("Syslog message : {}", syslogMessage.toString());

    return syslogMessage;
  }