diff --git a/README.md b/README.md index 8f7fcff..8d30331 100644 --- a/README.md +++ b/README.md @@ -113,12 +113,12 @@ Originally the layout class was called `JSONEventLayout`. This was originally wr - `@version` - `@timestamp` (optional - will be inferred from event receipt time -Because of this, when adding support for the new format, `JSONEventLayoutV1` was used to allow backwards compatibility. As of `1.6` of the jsonevent-layout library, we've now gone to fully versioned appenders. There is no longer a `JSONEventLayout`. Instead there is: +Because of this, when adding support for the new format, `JSONEventLayoutV1` was used to allow backwards compatibility. As of `1.6` of the jsonevent-layout library, we've now gone to fully versioned appenders. Always use either: - `JSONEventLayoutV0` - `JSONEventLayoutV1` -Work has stopped on V0 but it won't be removed. No new features are added to V0 (custom UserFields for instance). +Work has stopped on V0 but it won't be removed. No new features are added to V0 (custom UserFields for instance). For convenience, `JSONEventLayout` is an alias to `JSONEventLayoutV0` but its use is discouraged. # Custom User Fields As of version 1.6, you can now add your own metadata to the event in the form of comma-separated key:value pairs. This can be set in either the log4jconfig OR set on the java command-line: diff --git a/src/main/java/net/logstash/log4j/JSONEventLayout.java b/src/main/java/net/logstash/log4j/JSONEventLayout.java new file mode 100644 index 0000000..26e670b --- /dev/null +++ b/src/main/java/net/logstash/log4j/JSONEventLayout.java @@ -0,0 +1,18 @@ +package net.logstash.log4j; + +import net.logstash.log4j.JSONEventLayoutV0; +import org.apache.log4j.helpers.LogLog; + +public class JSONEventLayout extends JSONEventLayoutV0 { + + public JSONEventLayout() { + this(true); + } + + public JSONEventLayout(boolean locationInfo) { + super(locationInfo); + String whoami = this.getClass().getSimpleName(); + LogLog.warn("["+whoami+"] JSONEventLayout use is discouraged, use JSONEventLayoutV0 instead"); + } + +} diff --git a/src/test/java/net/logstash/log4j/JSONEventLayoutTest.java b/src/test/java/net/logstash/log4j/JSONEventLayoutTest.java new file mode 100644 index 0000000..a0dd199 --- /dev/null +++ b/src/test/java/net/logstash/log4j/JSONEventLayoutTest.java @@ -0,0 +1,60 @@ +package net.logstash.log4j; + +import junit.framework.Assert; +import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.NDC; +import org.apache.log4j.MDC; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +public class JSONEventLayoutTest { + static Logger logger; + static MockAppender appender; + static final String[] logstashFields = new String[]{ + "@message", + "@source_host", + "@fields", + "@timestamp" + }; + + @BeforeClass + public static void setupTestAppender() { + appender = new MockAppender(new JSONEventLayout()); + logger = Logger.getRootLogger(); + appender.setThreshold(Level.TRACE); + appender.setName("mockappender"); + appender.activateOptions(); + logger.addAppender(appender); + } + + @After + public void clearTestAppender() { + NDC.clear(); + appender.clear(); + appender.close(); + } + + @Test + public void testJSONEventLayoutIsJSON() { + logger.info("this is an info message"); + String message = appender.getMessages()[0]; + Assert.assertTrue("Event is not valid JSON", JSONValue.isValidJsonStrict(message)); + } + + @Test + public void testJSONEventLayoutHasKeys() { + logger.info("this is a test message"); + String message = appender.getMessages()[0]; + Object obj = JSONValue.parse(message); + JSONObject jsonObject = (JSONObject) obj; + + for (String fieldName : logstashFields) { + Assert.assertTrue("Event does not contain field: " + fieldName, jsonObject.containsKey(fieldName)); + } + } +} diff --git a/src/test/java/net/logstash/log4j/JSONEventLayoutV0Test.java b/src/test/java/net/logstash/log4j/JSONEventLayoutV0Test.java index 969ccc7..edbbc9e 100644 --- a/src/test/java/net/logstash/log4j/JSONEventLayoutV0Test.java +++ b/src/test/java/net/logstash/log4j/JSONEventLayoutV0Test.java @@ -34,7 +34,7 @@ public static void setupTestAppender() { appender = new MockAppenderV0(new JSONEventLayoutV0()); logger = Logger.getRootLogger(); appender.setThreshold(Level.TRACE); - appender.setName("mockappender"); + appender.setName("mockappenderv0"); appender.activateOptions(); logger.addAppender(appender); } diff --git a/src/test/java/net/logstash/log4j/MockAppender.java b/src/test/java/net/logstash/log4j/MockAppender.java new file mode 100644 index 0000000..ef92048 --- /dev/null +++ b/src/test/java/net/logstash/log4j/MockAppender.java @@ -0,0 +1,37 @@ +package net.logstash.log4j; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.Layout; + +public class MockAppender extends AppenderSkeleton { + + private static List messages = new ArrayList(); + + public MockAppender(Layout layout){ + this.layout = layout; + } + @Override + protected void append(LoggingEvent event){ + messages.add(layout.format(event)); + } + + public void close(){ + messages.clear(); + } + + public boolean requiresLayout(){ + return true; + } + + public static String[] getMessages() { + return (String[]) messages.toArray(new String[messages.size()]); + } + + public void clear() { + messages.clear(); + } +}