1. RFC5424 compatibility in timestamp format and message length 2. Introduced a new log method which accepts Date as an argument to create a syslog with the original timestamp.
This commit is contained in:
parent
e3c9709ee9
commit
ec7df03bce
src/main/java/org/graylog2/syslog4j
@ -24,6 +24,9 @@ public interface SyslogConstants extends Serializable {
|
||||
|
||||
public static final String STRUCTURED_DATA_NILVALUE = "-";
|
||||
public static final String STRUCTURED_DATA_EMPTY_VALUE = "[0@0]";
|
||||
public static final String SYSLOG_DATEFORMAT_RFC5424 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
public static final int MAX_MESSAGE_LENGTH_RFC5424 = 2048;
|
||||
public static final int MIN_MESSAGE_LENGTH_RFC5424 = 480;
|
||||
|
||||
public static final String CHAR_SET_DEFAULT = "UTF-8";
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.graylog2.syslog4j;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* SyslogIF provides a common interface for all Syslog4j client implementations.
|
||||
* <p/>
|
||||
@ -20,9 +22,11 @@ public interface SyslogIF extends SyslogConstants {
|
||||
public void backLog(int level, String message, Throwable reasonThrowable);
|
||||
|
||||
public void backLog(int level, String message, String reason);
|
||||
|
||||
|
||||
public void log(int level, String message);
|
||||
|
||||
public void log(int level, String message, Date datetime);
|
||||
|
||||
public void debug(String message);
|
||||
|
||||
public void info(String message);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.graylog2.syslog4j;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* SyslogMessageProcessorIF provides an extensible interface for writing custom
|
||||
@ -19,4 +20,6 @@ public interface SyslogMessageProcessorIF extends Serializable {
|
||||
public byte[] createPacketData(byte[] header, byte[] message, int start, int length);
|
||||
|
||||
public byte[] createPacketData(byte[] header, byte[] message, int start, int length, byte[] splitBeginText, byte[] splitEndText);
|
||||
|
||||
public String createSyslogHeader(int facility, int level, String localName, boolean sendLocalName, Date datetime);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import org.graylog2.syslog4j.impl.message.structured.StructuredSyslogMessageIF;
|
||||
import org.graylog2.syslog4j.util.SyslogUtility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -123,6 +124,17 @@ public abstract class AbstractSyslog implements SyslogIF {
|
||||
log(getMessageProcessor(), level, message);
|
||||
}
|
||||
}
|
||||
|
||||
public void log(int level, String message, Date datetime) {
|
||||
if (this.syslogConfig.isUseStructuredData()) {
|
||||
StructuredSyslogMessageIF structuredMessage = new StructuredSyslogMessage(null, null, null, message);
|
||||
|
||||
log(getStructuredMessageProcessor(), level, structuredMessage.createMessage(), datetime);
|
||||
|
||||
} else {
|
||||
log(getMessageProcessor(), level, message, datetime);
|
||||
}
|
||||
}
|
||||
|
||||
public void log(int level, SyslogMessageIF message) {
|
||||
if (message instanceof StructuredSyslogMessageIF) {
|
||||
@ -223,7 +235,8 @@ public abstract class AbstractSyslog implements SyslogIF {
|
||||
}
|
||||
|
||||
try {
|
||||
write(messageProcessor, level, _message);
|
||||
String header = messageProcessor.createSyslogHeader(this.syslogConfig.getFacility(), level, this.syslogConfig.getLocalName(), this.syslogConfig.isSendLocalTimestamp(), this.syslogConfig.isSendLocalName());
|
||||
write(messageProcessor, level, _message, header);
|
||||
|
||||
} catch (SyslogRuntimeException sre) {
|
||||
if (sre.getCause() != null) {
|
||||
@ -239,15 +252,50 @@ public abstract class AbstractSyslog implements SyslogIF {
|
||||
}
|
||||
}
|
||||
|
||||
protected void write(SyslogMessageProcessorIF messageProcessor, int level, String message) throws SyslogRuntimeException {
|
||||
String header = messageProcessor.createSyslogHeader(this.syslogConfig.getFacility(), level, this.syslogConfig.getLocalName(), this.syslogConfig.isSendLocalTimestamp(), this.syslogConfig.isSendLocalName());
|
||||
public void log(SyslogMessageProcessorIF messageProcessor, int level, String message, Date datetime) {
|
||||
String _message = null;
|
||||
|
||||
if (this.syslogConfig.isIncludeIdentInMessageModifier()) {
|
||||
_message = prefixMessage(message, IDENT_SUFFIX_DEFAULT);
|
||||
_message = modifyMessage(level, _message);
|
||||
|
||||
} else {
|
||||
_message = modifyMessage(level, message);
|
||||
_message = prefixMessage(_message, IDENT_SUFFIX_DEFAULT);
|
||||
}
|
||||
|
||||
try {
|
||||
String header = messageProcessor.createSyslogHeader(this.syslogConfig.getFacility(), level, this.syslogConfig.getLocalName(), this.syslogConfig.isSendLocalName(), datetime);
|
||||
write(messageProcessor, level, _message, header);
|
||||
|
||||
} catch (SyslogRuntimeException sre) {
|
||||
if (sre.getCause() != null) {
|
||||
backLog(level, _message, sre.getCause());
|
||||
|
||||
} else {
|
||||
backLog(level, _message, sre);
|
||||
}
|
||||
|
||||
if (this.syslogConfig.isThrowExceptionOnWrite()) {
|
||||
throw sre;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void write(SyslogMessageProcessorIF messageProcessor, int level, String message, String header) throws SyslogRuntimeException {
|
||||
|
||||
byte[] h = SyslogUtility.getBytes(this.syslogConfig, header);
|
||||
byte[] m = SyslogUtility.getBytes(this.syslogConfig, message);
|
||||
|
||||
int mLength = m.length;
|
||||
int hLength = h.length;
|
||||
int expectedMinLength = this.syslogConfig.getMinMessageLength();
|
||||
|
||||
if (mLength < expectedMinLength) {
|
||||
throw new SyslogRuntimeException("Message length is: " + String.valueOf(mLength) + " but expected to be at least: " + String.valueOf(expectedMinLength));
|
||||
}
|
||||
|
||||
int availableLen = this.syslogConfig.getMaxMessageLength() - h.length;
|
||||
int availableLen = this.syslogConfig.getMaxMessageLength() - hLength;
|
||||
|
||||
if (this.syslogConfig.isTruncateMessage()) {
|
||||
if (availableLen > 0 && mLength > availableLen) {
|
||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.graylog2.syslog4j.SyslogBackLogHandlerIF;
|
||||
import org.graylog2.syslog4j.SyslogConstants;
|
||||
import org.graylog2.syslog4j.SyslogMessageModifierIF;
|
||||
import org.graylog2.syslog4j.SyslogRuntimeException;
|
||||
import org.graylog2.syslog4j.impl.backlog.printstream.SystemErrSyslogBackLogHandler;
|
||||
@ -45,6 +46,7 @@ public abstract class AbstractSyslogConfig implements AbstractSyslogConfigIF {
|
||||
protected boolean throwExceptionOnInitialize = THROW_EXCEPTION_ON_INITIALIZE_DEFAULT;
|
||||
|
||||
protected int maxMessageLength = MAX_MESSAGE_LENGTH_DEFAULT;
|
||||
protected int minMessageLength = 0;
|
||||
protected byte[] splitMessageBeginText = SPLIT_MESSAGE_BEGIN_TEXT_DEFAULT.getBytes();
|
||||
protected byte[] splitMessageEndText = SPLIT_MESSAGE_END_TEXT_DEFAULT.getBytes();
|
||||
|
||||
@ -127,6 +129,14 @@ public abstract class AbstractSyslogConfig implements AbstractSyslogConfigIF {
|
||||
public void setMaxMessageLength(int maxMessageLength) {
|
||||
this.maxMessageLength = maxMessageLength;
|
||||
}
|
||||
|
||||
public int getMinMessageLength() {
|
||||
return this.minMessageLength;
|
||||
}
|
||||
|
||||
public void setMinMessageLength(int minMessageLength) {
|
||||
this.minMessageLength = minMessageLength;
|
||||
}
|
||||
|
||||
public boolean isSendLocalTimestamp() {
|
||||
return this.sendLocalTimestamp;
|
||||
@ -370,6 +380,8 @@ public abstract class AbstractSyslogConfig implements AbstractSyslogConfigIF {
|
||||
|
||||
public void setUseStructuredData(boolean useStructuredData) {
|
||||
this.useStructuredData = useStructuredData;
|
||||
setMaxMessageLength(SyslogConstants.MAX_MESSAGE_LENGTH_RFC5424);
|
||||
setMinMessageLength(SyslogConstants.MIN_MESSAGE_LENGTH_RFC5424);
|
||||
}
|
||||
|
||||
public Class getSyslogWriterClass() {
|
||||
|
@ -62,4 +62,8 @@ public interface AbstractSyslogConfigIF extends SyslogConfigIF {
|
||||
* @param maxQueueSize
|
||||
*/
|
||||
public void setMaxQueueSize(int maxQueueSize);
|
||||
|
||||
public int getMinMessageLength();
|
||||
|
||||
public void setMinMessageLength(int minMessageLength);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package org.graylog2.syslog4j.impl.message.processor;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.graylog2.syslog4j.SyslogConstants;
|
||||
import org.graylog2.syslog4j.SyslogMessageProcessorIF;
|
||||
@ -74,21 +72,6 @@ public abstract class AbstractSyslogMessageProcessor implements SyslogMessagePro
|
||||
buffer.append(">");
|
||||
}
|
||||
|
||||
protected void appendLocalTimestamp(StringBuffer buffer) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(SYSLOG_DATEFORMAT, Locale.ENGLISH);
|
||||
|
||||
String datePrefix = dateFormat.format(new Date());
|
||||
|
||||
int pos = buffer.length() + 4;
|
||||
|
||||
buffer.append(datePrefix);
|
||||
|
||||
// RFC 3164 requires leading space for days 1-9
|
||||
if (buffer.charAt(pos) == '0') {
|
||||
buffer.setCharAt(pos, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
protected void appendLocalName(StringBuffer buffer, String localName) {
|
||||
if (localName != null) {
|
||||
buffer.append(localName);
|
||||
@ -99,20 +82,7 @@ public abstract class AbstractSyslogMessageProcessor implements SyslogMessagePro
|
||||
|
||||
buffer.append(' ');
|
||||
}
|
||||
|
||||
public String createSyslogHeader(int facility, int level, String localName, boolean sendLocalTimestamp, boolean sendLocalName) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
appendPriority(buffer, facility, level);
|
||||
|
||||
if (sendLocalTimestamp) {
|
||||
appendLocalTimestamp(buffer);
|
||||
}
|
||||
|
||||
if (sendLocalName) {
|
||||
appendLocalName(buffer, localName);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
protected abstract void appendTimestamp(StringBuffer buffer, Date datetime);
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package org.graylog2.syslog4j.impl.message.processor;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* SyslogMessageProcessor wraps AbstractSyslogMessageProcessor.
|
||||
@ -32,4 +36,67 @@ public class SyslogMessageProcessor extends AbstractSyslogMessageProcessor {
|
||||
public static SyslogMessageProcessor getDefault() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.graylog2.syslog4j.impl.message.processor.AbstractSyslogMessageProcessor#appendTimestamp(java.lang.StringBuffer, java.util.Date)
|
||||
*
|
||||
* This is compatible with BSD protocol
|
||||
*/
|
||||
@Override
|
||||
public void appendTimestamp(StringBuffer buffer, Date datetime) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(SYSLOG_DATEFORMAT, Locale.ENGLISH);
|
||||
|
||||
String datePrefix = dateFormat.format(datetime);
|
||||
|
||||
int pos = buffer.length() + 4;
|
||||
|
||||
buffer.append(datePrefix);
|
||||
|
||||
// RFC 3164 requires leading space for days 1-9
|
||||
if (buffer.charAt(pos) == '0') {
|
||||
buffer.setCharAt(pos, ' ');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.graylog2.syslog4j.SyslogMessageProcessorIF#createSyslogHeader(int, int, java.lang.String, boolean, boolean)
|
||||
*
|
||||
* This is compatible with BSD protocol
|
||||
*/
|
||||
public String createSyslogHeader(int facility, int level, String localName, boolean sendLocalTimestamp, boolean sendLocalName) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
appendPriority(buffer, facility, level);
|
||||
|
||||
if (sendLocalTimestamp) {
|
||||
appendTimestamp(buffer, new Date());
|
||||
}
|
||||
|
||||
if (sendLocalName) {
|
||||
appendLocalName(buffer, localName);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.graylog2.syslog4j.SyslogMessageProcessorIF#createSyslogHeader(int, int, java.lang.String, boolean, java.util.Date)
|
||||
*
|
||||
* This is compatible with BSD protocol
|
||||
*/
|
||||
public String createSyslogHeader(int facility, int level, String localName, boolean sendLocalName, Date datetime) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
appendPriority(buffer, facility, level);
|
||||
|
||||
appendTimestamp(buffer, datetime);
|
||||
|
||||
if (sendLocalName) {
|
||||
appendLocalName(buffer, localName);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,12 @@
|
||||
package org.graylog2.syslog4j.impl.message.processor.structured;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.graylog2.syslog4j.SyslogConstants;
|
||||
import org.graylog2.syslog4j.impl.message.processor.AbstractSyslogMessageProcessor;
|
||||
import org.graylog2.syslog4j.impl.message.structured.StructuredSyslogMessage;
|
||||
|
||||
@ -29,16 +34,16 @@ import org.graylog2.syslog4j.impl.message.structured.StructuredSyslogMessage;
|
||||
* @version $Id: StructuredSyslogMessageProcessor.java,v 1.4 2011/01/11 05:11:13 cvs Exp $
|
||||
*/
|
||||
public class StructuredSyslogMessageProcessor extends AbstractSyslogMessageProcessor {
|
||||
private static final long serialVersionUID = -1563777226913475257L;
|
||||
|
||||
private static final long serialVersionUID = -1563777226913475257L;
|
||||
|
||||
public static String VERSION = "1";
|
||||
|
||||
private static final StructuredSyslogMessageProcessor INSTANCE = new StructuredSyslogMessageProcessor();
|
||||
|
||||
private static final StructuredSyslogMessageProcessor INSTANCE = new StructuredSyslogMessageProcessor();
|
||||
protected static StructuredSyslogMessageProcessor defaultInstance = INSTANCE;
|
||||
|
||||
private String applicationName = STRUCTURED_DATA_APP_NAME_DEFAULT_VALUE;
|
||||
private String processId = STRUCTURED_DATA_PROCESS_ID_DEFAULT_VALUE;
|
||||
|
||||
private String applicationName = STRUCTURED_DATA_APP_NAME_DEFAULT_VALUE;
|
||||
private String processId = STRUCTURED_DATA_PROCESS_ID_DEFAULT_VALUE;
|
||||
private DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime();
|
||||
|
||||
public static void setDefault(StructuredSyslogMessageProcessor messageProcessor) {
|
||||
@ -84,23 +89,53 @@ public class StructuredSyslogMessageProcessor extends AbstractSyslogMessageProce
|
||||
this.processId = processId;
|
||||
}
|
||||
|
||||
public String createSyslogHeader(final int facility, final int level, String localName, final boolean sendLocalTimestamp, final boolean sendLocalName) {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
/* (non-Javadoc)
|
||||
* @see org.graylog2.syslog4j.impl.message.processor.AbstractSyslogMessageProcessor#appendTimestamp(java.lang.StringBuffer, java.util.Date)
|
||||
*
|
||||
* This is compatible with RFC5424 protocol.
|
||||
*/
|
||||
@Override
|
||||
public void appendTimestamp(StringBuffer buffer, Date datetime) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(SyslogConstants.SYSLOG_DATEFORMAT_RFC5424);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(datetime.getTime());
|
||||
String formatedTimestamp = formatter.format(calendar.getTime());
|
||||
buffer.append(formatedTimestamp);
|
||||
buffer.append(' ');
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.graylog2.syslog4j.SyslogMessageProcessorIF#createSyslogHeader(int, int, java.lang.String, boolean, boolean)
|
||||
*
|
||||
* This is compatible with RFC5424 protocol.
|
||||
*
|
||||
* RFC5424 does not allow flags of sendLocalTimestamp and sendLocalName be off and therefore the incoming flags will not be used in this method.
|
||||
*
|
||||
*/
|
||||
public String createSyslogHeader(int facility, int level, String localName, boolean sendLocalTimestamp, boolean sendLocalName) {
|
||||
return createSyslogHeaderInner(facility, level, localName, new Date());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.graylog2.syslog4j.SyslogMessageProcessorIF#createSyslogHeader(int, int, java.lang.String, boolean, java.util.Date)
|
||||
*
|
||||
* This is compatible with RFC5424 protocol.
|
||||
*
|
||||
* RFC5424 does not allow sendLocalName flag to be off and therefore sendLocalName will not be used in this method.
|
||||
*/
|
||||
public String createSyslogHeader(int facility, int level, String localName, boolean sendLocalName, Date datetime) {
|
||||
return createSyslogHeaderInner(facility, level, localName, datetime);
|
||||
}
|
||||
|
||||
private String createSyslogHeaderInner(int facility, int level, String localName, Date datetime) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
appendPriority(buffer, facility, level);
|
||||
buffer.append(VERSION);
|
||||
buffer.append(' ');
|
||||
|
||||
getDateTimeFormatter().printTo(buffer, System.currentTimeMillis());
|
||||
buffer.append(' ');
|
||||
|
||||
appendTimestamp(buffer, datetime);
|
||||
appendLocalName(buffer, localName);
|
||||
|
||||
buffer.append(StructuredSyslogMessage.nilProtect(this.applicationName))
|
||||
.append(' ');
|
||||
|
||||
buffer.append(StructuredSyslogMessage.nilProtect(this.applicationName)).append(' ');
|
||||
buffer.append(StructuredSyslogMessage.nilProtect(this.processId)).append(' ');
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.graylog2.syslog4j.impl.multiple;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.graylog2.syslog4j.Syslog;
|
||||
import org.graylog2.syslog4j.SyslogConfigIF;
|
||||
import org.graylog2.syslog4j.SyslogConstants;
|
||||
@ -171,4 +173,9 @@ public class MultipleSyslog implements SyslogIF {
|
||||
public String getProtocol() {
|
||||
return this.syslogProtocol;
|
||||
}
|
||||
|
||||
public void log(int level, String message, Date datetime) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user