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; }
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; }