diff --git a/README.md b/README.md
index 633c0cf..82bf55e 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ In your `logback.xml`:
false100
+ falsehost
@@ -110,6 +111,7 @@ Configuration Reference
* `includeMdc` (optional, default false): If set to `true`, then all [MDC](http://www.slf4j.org/api/org/slf4j/MDC.html) values will be mapped to properties on the JSON payload.
* `maxMessageSize` (optional, default -1): If set to a number greater than 0, truncate messages larger than this length, then append "`..`" to denote that the message was truncated
* `authentication` (optional): Add the ability to send authentication headers (see below)
+ * `enableContextMap` (optional): If the latest parameter in logger call is of type java.util.Map then all content of it will be traversed and written with prefix `context.*`. For event-specific custom fields.
The fields `@timestamp` and `message` are always sent and can not currently be configured. Additional fields can be sent by adding `` elements to the `` set.
@@ -154,3 +156,17 @@ Included is also an Elasticsearch appender for Logback Access. The configuration
* The Appender class name is `com.internetitem.logback.elasticsearch.ElasticsearchAccessAppender`
* The `value` for each `property` uses the [Logback Access conversion words](http://logback.qos.ch/manual/layouts.html#logback-access).
+
+Event-specific custom fields
+============================
+Log line:
+
+ log.info("Service started in {} seconds", duration/1000, Collections.singletonMap("duration", duration));
+
+Result:
+
+ {
+ "@timestamp": "2014-06-04T15:26:14.464+02:00",
+ "message": "Service started in 12 seconds",
+ "duration": 12368,
+ }
\ No newline at end of file
diff --git a/src/main/java/com/internetitem/logback/elasticsearch/AbstractElasticsearchAppender.java b/src/main/java/com/internetitem/logback/elasticsearch/AbstractElasticsearchAppender.java
index a1e48ea..f13c765 100644
--- a/src/main/java/com/internetitem/logback/elasticsearch/AbstractElasticsearchAppender.java
+++ b/src/main/java/com/internetitem/logback/elasticsearch/AbstractElasticsearchAppender.java
@@ -133,4 +133,8 @@ public void setAuthentication(Authentication auth) {
public void setMaxMessageSize(int maxMessageSize) {
settings.setMaxMessageSize(maxMessageSize);
}
+
+ public void setEnableContextMap(boolean enableContextMap) {
+ settings.setEnableContextMap(enableContextMap);
+ }
}
diff --git a/src/main/java/com/internetitem/logback/elasticsearch/ClassicElasticsearchPublisher.java b/src/main/java/com/internetitem/logback/elasticsearch/ClassicElasticsearchPublisher.java
index 3a0a08e..f34af58 100644
--- a/src/main/java/com/internetitem/logback/elasticsearch/ClassicElasticsearchPublisher.java
+++ b/src/main/java/com/internetitem/logback/elasticsearch/ClassicElasticsearchPublisher.java
@@ -9,6 +9,7 @@
import com.internetitem.logback.elasticsearch.config.Settings;
import com.internetitem.logback.elasticsearch.util.AbstractPropertyAndEncoder;
import com.internetitem.logback.elasticsearch.util.ClassicPropertyAndEncoder;
+import com.internetitem.logback.elasticsearch.util.ContextMapWriter;
import com.internetitem.logback.elasticsearch.util.ErrorReporter;
import java.io.IOException;
@@ -16,8 +17,11 @@
public class ClassicElasticsearchPublisher extends AbstractElasticsearchPublisher {
+ protected ContextMapWriter contextMapWriter;
+
public ClassicElasticsearchPublisher(Context context, ErrorReporter errorReporter, Settings settings, ElasticsearchProperties properties, HttpRequestHeaders headers) throws IOException {
super(context, errorReporter, settings, properties, headers);
+ contextMapWriter = new ContextMapWriter();
}
@Override
@@ -49,5 +53,9 @@ protected void serializeCommonFields(JsonGenerator gen, ILoggingEvent event) thr
gen.writeObjectField(entry.getKey(), entry.getValue());
}
}
+
+ if (settings.isEnableContextMap()) {
+ contextMapWriter.writeContextMap(gen, event);
+ }
}
}
diff --git a/src/main/java/com/internetitem/logback/elasticsearch/config/Settings.java b/src/main/java/com/internetitem/logback/elasticsearch/config/Settings.java
index 983ba06..61c2e20 100644
--- a/src/main/java/com/internetitem/logback/elasticsearch/config/Settings.java
+++ b/src/main/java/com/internetitem/logback/elasticsearch/config/Settings.java
@@ -23,6 +23,7 @@ public class Settings {
private int maxQueueSize = 100 * 1024 * 1024;
private Authentication authentication;
private int maxMessageSize = -1;
+ private boolean enableContextMap;
public String getIndex() {
return index;
@@ -162,4 +163,12 @@ public int getMaxMessageSize() {
public void setMaxMessageSize(int maxMessageSize) {
this.maxMessageSize = maxMessageSize;
}
+
+ public boolean isEnableContextMap() {
+ return enableContextMap;
+ }
+
+ public void setEnableContextMap(boolean enableContextMap) {
+ this.enableContextMap = enableContextMap;
+ }
}
diff --git a/src/main/java/com/internetitem/logback/elasticsearch/util/ContextMapWriter.java b/src/main/java/com/internetitem/logback/elasticsearch/util/ContextMapWriter.java
new file mode 100644
index 0000000..5e555e7
--- /dev/null
+++ b/src/main/java/com/internetitem/logback/elasticsearch/util/ContextMapWriter.java
@@ -0,0 +1,62 @@
+package com.internetitem.logback.elasticsearch.util;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import com.fasterxml.jackson.core.JsonGenerator;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+
+public class ContextMapWriter {
+
+ public void writeContextMap(JsonGenerator gen, ILoggingEvent event) throws IOException {
+ Object[] arguments = event.getArgumentArray();
+ if (arguments == null || arguments.length == 0) {
+ return;
+ }
+ Object lastElement = arguments[arguments.length - 1];
+ if (lastElement instanceof Map) {
+ Map indexes = traverseMap(new HashMap<>(), "context", (Map