From 0b691d1c512fa2b03449c3208602fc818ce3dc18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20OLIVER?= Date: Wed, 5 May 2021 21:07:09 +0200 Subject: [PATCH 1/3] Create GelfLayoutAccessLog.java --- .../logbackgelf/GelfLayoutAccessLog.java | 316 ++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java diff --git a/src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java b/src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java new file mode 100644 index 0000000..94e40c3 --- /dev/null +++ b/src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java @@ -0,0 +1,316 @@ +package me.moocar.logbackgelf; + +import java.lang.reflect.Method; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; + +import me.moocar.logbackgelf.Field; +import me.moocar.logbackgelf.InternetUtils; +import ch.qos.logback.access.PatternLayout; +import ch.qos.logback.access.spi.IAccessEvent; +import ch.qos.logback.core.Layout; +import ch.qos.logback.core.LayoutBase; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * Responsible for formatting a log event into a GELF JSON string + */ +public class GelfLayoutAccessLog extends LayoutBase { + + private final String DEFAULT_FULL_MESSAGE_PATTERN = "combined"; + private final String DEFAULT_SHORT_MESSAGE_PATTERN = "combined"; + + private boolean useThreadName = false; + + private Map additionalFields = new HashMap(); + private Map fieldTypes = new HashMap(); + private Map staticFields = new HashMap(); + private String host = getLocalHostName(); + private final Gson gson; + private Layout fullMessageLayout; + private Layout shortMessageLayout; + private boolean includeFullMDC = false; + + static Map primitiveTypes; + + static { + primitiveTypes = new HashMap(); + try { + primitiveTypes.put("int", Integer.class.getDeclaredMethod("parseInt", String.class)); + primitiveTypes.put("Integer", Integer.class.getDeclaredMethod("parseInt", String.class)); + primitiveTypes.put("long", Long.class.getDeclaredMethod("parseLong", String.class)); + primitiveTypes.put("Long", Long.class.getDeclaredMethod("parseLong", String.class)); + primitiveTypes.put("float", Float.class.getDeclaredMethod("parseFloat", String.class)); + primitiveTypes.put("Float", Float.class.getDeclaredMethod("parseFloat", String.class)); + primitiveTypes.put("double", Double.class.getDeclaredMethod("parseDouble", String.class)); + primitiveTypes.put("Double", Double.class.getDeclaredMethod("parseDouble", String.class)); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + + public GelfLayoutAccessLog() { + + // Init GSON for underscores + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); + this.gson = gsonBuilder.create(); + } + + @Override + public void start() { + + if (fullMessageLayout == null) { + this.fullMessageLayout = initNewPatternLayout(DEFAULT_FULL_MESSAGE_PATTERN); + } + + if (shortMessageLayout == null) { + this.shortMessageLayout = initNewPatternLayout(DEFAULT_SHORT_MESSAGE_PATTERN); + } + + super.start(); + } + + private PatternLayout initNewPatternLayout(String pattern) { + PatternLayout layout = new PatternLayout(); + layout.setPattern(pattern); + layout.setContext(this.getContext()); + layout.start(); + return layout; + } + + @Override + public String doLayout(E event) { + return gson.toJson(mapFields(event)); + } + + /** + * Creates a map of properties that represent the GELF message. + * @param logEvent The log event + * @return map of gelf properties + */ + private Map mapFields(E logEvent) { + Map map = new HashMap(); + + map.put("host", host); + + map.put("full_message", fullMessageLayout.doLayout(logEvent)); + map.put("short_message", shortMessageLayout.doLayout(logEvent)); + + map.put("timestamp", logEvent.getTimeStamp() / 1000.0); + + map.put("version", "1.1"); + + additionalFields(map, logEvent); + + staticAdditionalFields(map); + + return map; + } + + /** + * Converts the additional fields into proper GELF JSON + * @param map The map of additional fields + * @param eventObject The Logging event that we are converting to GELF + */ + private void additionalFields(Map map, IAccessEvent eventObject) { + + if (useThreadName) { + map.put("_threadName", eventObject.getThreadName()); + } + + } + + private Object convertFieldType(Object value, final String type) { + if (primitiveTypes.containsKey(fieldTypes.get(type))) { + try { + value = primitiveTypes.get(fieldTypes.get(type)).invoke(null, + value); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + return value; + } + + private void staticAdditionalFields(Map map) { + + for (String key : staticFields.keySet()) { + map.put(key, (staticFields.get(key))); + } + } + + private String getLocalHostName() { + try { + return InternetUtils.getLocalHostName(); + } catch (SocketException e) { + return "UNKNOWN"; + } catch (UnknownHostException e) { + return "UNKNOWN"; + } + } + + // ////////// Logback Property Getter/Setters //////////////// + + /** + * If true, an additional field call "_threadName" will be added to each gelf message. Its contents will be the Name of the thread. + * Defaults to "false". + */ + public boolean isUseThreadName() { + return useThreadName; + } + + public void setUseThreadName(boolean useThreadName) { + this.useThreadName = useThreadName; + } + + /** + * additional fields to add to the gelf message. Here's how these work:
+ * Let's take an example. I want to log the client's ip address of every request that comes into my web server. To do this, I add the + * ipaddress to the slf4j MDC on each request as follows: ... MDC.put("ipAddress", "44.556.345.657"); ... Now, to include + * the ip address in the gelf message, i just add the following to my logback.groovy: + * appender("GELF", GelfAppender) { ... additionalFields = [identity:"_identity"] ... } in the additionalFields map, the key is + * the name of the MDC to look up. the value is the name that should be given to the key in the additional field in the gelf message. + */ + public Map getAdditionalFields() { + return additionalFields; + } + + public void setAdditionalFields(Map additionalFields) { + this.additionalFields = additionalFields; + } + + /** + * static additional fields to add to every gelf message. Key is the additional field key (and should thus begin with an underscore). + * The value is a static string. + */ + public Map getStaticFields() { + return staticFields; + } + + public void setStaticFields(Map staticFields) { + this.staticFields = staticFields; + } + + /** + * Indicates if all values from the MDC should be included in the gelf message or only the once listed as {@link #getAdditionalFields() + * additional fields}. + *

+ * If true, the gelf message will contain all values available in the MDC. Each MDC key will be converted to a gelf custom + * field by adding an underscore prefix. If an entry exists in {@link #getAdditionalFields() additional field} it will be used instead. + *

+ *

+ * If false, only the fields listed in {@link #getAdditionalFields() additional field} will be included in the message. + *

+ * @return the includeFullMDC + */ + public boolean isIncludeFullMDC() { + return includeFullMDC; + } + + public void setIncludeFullMDC(boolean includeFullMDC) { + this.includeFullMDC = includeFullMDC; + } + + /** + * Override the local host using a config option + * @return the local host (defaults to getLocalHost() if not overridden in config + */ + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Add an additional field. This is mainly here for compatibility with logback.xml + * @param keyValue This must be in format key:value where key is the MDC key, and value is the GELF field name. e.g + * "ipAddress:_ip_address" + */ + public void addAdditionalField(String keyValue) { + String[] splitted = keyValue.split(":"); + + if (splitted.length != 2) { + + throw new IllegalArgumentException("additionalField must be of the format key:value, where key is the MDC " + + "key, and value is the GELF field name. But found '" + keyValue + "' instead."); + } + + additionalFields.put(splitted[0], splitted[1]); + } + + /** + * Add a staticAdditional field. This is mainly here for compatibility with logback.xml + * @param keyValue This must be in format key:value where key is the additional field key, and value is a static string. e.g + * "_node_name:www013" + * @deprecated Use addStaticField instead + */ + @Deprecated + public void addStaticAdditionalField(String keyValue) { + String[] splitted = keyValue.split(":"); + + if (splitted.length != 2) { + + throw new IllegalArgumentException("staticAdditionalField must be of the format key:value, where key is the " + + "additional field key (therefore should have a leading underscore), and value is a static string. " + + "e.g. _node_name:www013"); + } + + staticFields.put(splitted[0], splitted[1]); + } + + /** + * Add a static field. A static field is a key/value pair that should be sent in each Gelf message. This supercedes static additional + * fields, which can't have colon characters in their value. + */ + public void addStaticField(Field entry) { + staticFields.put(entry.getKey(), entry.getValue()); + } + + public void addFieldType(String keyValue) { + String[] splitted = keyValue.split(":"); + + if (splitted.length != 2 || + !GelfLayoutAccessLog.primitiveTypes.containsKey(splitted[1])) { + throw new IllegalArgumentException( + "fieldType must be of the format key:value, where key is the " + + "field key, and value is the type to convert to (one of " + + GelfLayoutAccessLog.primitiveTypes.keySet() + + ")"); + } + + fieldTypes.put(splitted[0], splitted[1]); + + } + + public Map getFieldTypes() { + return fieldTypes; + } + + public void setFieldTypes(final Map fieldTypes) { + this.fieldTypes = fieldTypes; + } + + public Layout getFullMessageLayout() { + return fullMessageLayout; + } + + public void setFullMessageLayout(Layout fullMessageLayout) { + this.fullMessageLayout = fullMessageLayout; + } + + public Layout getShortMessageLayout() { + return shortMessageLayout; + } + + public void setShortMessageLayout(Layout shortMessageLayout) { + this.shortMessageLayout = shortMessageLayout; + } +} From e3dbcebf9134f4b737889b4f07170c39be0601f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20OLIVER?= Date: Wed, 5 May 2021 21:28:54 +0200 Subject: [PATCH 2/3] Update README.md --- README.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/README.md b/README.md index 0615e92..41d2c85 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,41 @@ default values: ``` +An complete example for logback-access + +```xml + + + somehost.com + 12201 + + UTF-8 + + + + common + + + combined + + true + Test + + application + Your-Application + + + + + + + + + +``` + + + ## GelfLayout `me.moocar.logbackgelf.GelfLayout` @@ -142,6 +177,33 @@ actually converts a log event into a GELF compatible JSON string. empty * **includeFullMDC**: See additional fields below. Default: `false` + +## GelfLayoutAccess + +`me.moocar.logbackgelf.GelfLayoutAccess` + +GelfLayoutAccess must be used if you want to use Gelf with "logback-access". For example, if you use the Tomcat LogbackValve. +http://logback.qos.ch/access.html#tomcat + +* **useThreadName**: If true, an additional field call "_threadName" + will be added to each gelf message. Its contents will be the name of + the thread. Default: `false` +* **host** The hostname of the host from which the log is being sent. + Displayed under `source` on web interface. Default: + `getLocalHostName()` +* **shortMessageLayout**: The + [Layout/logback-access](http://logback.qos.ch/manual/layouts.html#logback-access) used to create + the gelf `short_message` field. Shows up in the message column of + the log summary in the web interface. Default: `"combined"` + ([AccessPatternLayout](http://logback.qos.ch/manual/layouts.html#AccessPatternLayout)) +* **fullMessageLayout**: The + [Layout/logback-access](http://logback.qos.ch/manual/layouts.html#logback-access) used to create + the gelf `full_message` field. Shows up in the message field of the + log details in the web interface. Default: `"combined"` + ([AccessPatternLayout](http://logback.qos.ch/manual/layouts.html#AccessPatternLayout)) +* **staticFields**: See static fields below. Note, now that facility + is deprecated, use this to set a facility Default: empty + ## Transports Both UDP and TCP transports are supported. UDP is the recommended From fe54b5b14ab499503d952a5e2dd95b9e3157fea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20OLIVER?= Date: Wed, 5 May 2021 21:36:34 +0200 Subject: [PATCH 3/3] Update and rename GelfLayoutAccessLog.java to GelfLayoutAccess.java --- .../moocar/logbackgelf/GelfLayoutAccess.java | 185 ++++++++++ .../logbackgelf/GelfLayoutAccessLog.java | 316 ------------------ 2 files changed, 185 insertions(+), 316 deletions(-) create mode 100644 src/main/java/me/moocar/logbackgelf/GelfLayoutAccess.java delete mode 100644 src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java diff --git a/src/main/java/me/moocar/logbackgelf/GelfLayoutAccess.java b/src/main/java/me/moocar/logbackgelf/GelfLayoutAccess.java new file mode 100644 index 0000000..b1d8219 --- /dev/null +++ b/src/main/java/me/moocar/logbackgelf/GelfLayoutAccess.java @@ -0,0 +1,185 @@ +package me.moocar.logbackgelf; + +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; + +import me.moocar.logbackgelf.Field; +import me.moocar.logbackgelf.InternetUtils; +import ch.qos.logback.access.PatternLayout; +import ch.qos.logback.access.spi.IAccessEvent; +import ch.qos.logback.core.Layout; +import ch.qos.logback.core.LayoutBase; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * Responsible for formatting a log event into a GELF JSON string + */ +public class GelfLayoutAccess extends LayoutBase { + + private final String DEFAULT_FULL_MESSAGE_PATTERN = "combined"; + private final String DEFAULT_SHORT_MESSAGE_PATTERN = "combined"; + + private boolean useThreadName = false; + + private Map staticFields = new HashMap(); + private String host = getLocalHostName(); + private final Gson gson; + private Layout fullMessageLayout; + private Layout shortMessageLayout; + + public GelfLayoutAccess() { + + // Init GSON for underscores + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); + this.gson = gsonBuilder.create(); + } + + @Override + public void start() { + + if (fullMessageLayout == null) { + this.fullMessageLayout = initNewPatternLayout(DEFAULT_FULL_MESSAGE_PATTERN); + } + + if (shortMessageLayout == null) { + this.shortMessageLayout = initNewPatternLayout(DEFAULT_SHORT_MESSAGE_PATTERN); + } + + super.start(); + } + + private PatternLayout initNewPatternLayout(String pattern) { + PatternLayout layout = new PatternLayout(); + layout.setPattern(pattern); + layout.setContext(this.getContext()); + layout.start(); + return layout; + } + + @Override + public String doLayout(E event) { + return gson.toJson(mapFields(event)); + } + + /** + * Creates a map of properties that represent the GELF message. + * @param logEvent The log event + * @return map of gelf properties + */ + private Map mapFields(E logEvent) { + Map map = new HashMap(); + + map.put("host", host); + + map.put("full_message", fullMessageLayout.doLayout(logEvent)); + map.put("short_message", shortMessageLayout.doLayout(logEvent)); + + map.put("timestamp", logEvent.getTimeStamp() / 1000.0); + + map.put("version", "1.1"); + + additionalFields(map, logEvent); + + staticAdditionalFields(map); + + return map; + } + + /** + * Converts the additional fields into proper GELF JSON + * @param map The map of additional fields + * @param eventObject The Logging event that we are converting to GELF + */ + private void additionalFields(Map map, IAccessEvent eventObject) { + + if (useThreadName) { + map.put("_threadName", eventObject.getThreadName()); + } + + } + + private void staticAdditionalFields(Map map) { + + for (String key : staticFields.keySet()) { + map.put(key, (staticFields.get(key))); + } + } + + private String getLocalHostName() { + try { + return InternetUtils.getLocalHostName(); + } catch (SocketException e) { + return "UNKNOWN"; + } catch (UnknownHostException e) { + return "UNKNOWN"; + } + } + + // ////////// Logback Property Getter/Setters //////////////// + + /** + * If true, an additional field call "_threadName" will be added to each gelf message. Its contents will be the Name of the thread. + * Defaults to "false". + */ + public boolean isUseThreadName() { + return useThreadName; + } + + public void setUseThreadName(boolean useThreadName) { + this.useThreadName = useThreadName; + } + + /** + * static additional fields to add to every gelf message. Key is the additional field key (and should thus begin with an underscore). + * The value is a static string. + */ + public Map getStaticFields() { + return staticFields; + } + + public void setStaticFields(Map staticFields) { + this.staticFields = staticFields; + } + + /** + * Override the local host using a config option + * @return the local host (defaults to getLocalHost() if not overridden in config + */ + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + /** + * Add a static field. A static field is a key/value pair that should be sent in each Gelf message. This supercedes static additional + * fields, which can't have colon characters in their value. + */ + public void addStaticField(Field entry) { + staticFields.put(entry.getKey(), entry.getValue()); + } + + public Layout getFullMessageLayout() { + return fullMessageLayout; + } + + public void setFullMessageLayout(Layout fullMessageLayout) { + this.fullMessageLayout = fullMessageLayout; + } + + public Layout getShortMessageLayout() { + return shortMessageLayout; + } + + public void setShortMessageLayout(Layout shortMessageLayout) { + this.shortMessageLayout = shortMessageLayout; + } +} diff --git a/src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java b/src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java deleted file mode 100644 index 94e40c3..0000000 --- a/src/main/java/me/moocar/logbackgelf/GelfLayoutAccessLog.java +++ /dev/null @@ -1,316 +0,0 @@ -package me.moocar.logbackgelf; - -import java.lang.reflect.Method; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; - -import me.moocar.logbackgelf.Field; -import me.moocar.logbackgelf.InternetUtils; -import ch.qos.logback.access.PatternLayout; -import ch.qos.logback.access.spi.IAccessEvent; -import ch.qos.logback.core.Layout; -import ch.qos.logback.core.LayoutBase; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -/** - * Responsible for formatting a log event into a GELF JSON string - */ -public class GelfLayoutAccessLog extends LayoutBase { - - private final String DEFAULT_FULL_MESSAGE_PATTERN = "combined"; - private final String DEFAULT_SHORT_MESSAGE_PATTERN = "combined"; - - private boolean useThreadName = false; - - private Map additionalFields = new HashMap(); - private Map fieldTypes = new HashMap(); - private Map staticFields = new HashMap(); - private String host = getLocalHostName(); - private final Gson gson; - private Layout fullMessageLayout; - private Layout shortMessageLayout; - private boolean includeFullMDC = false; - - static Map primitiveTypes; - - static { - primitiveTypes = new HashMap(); - try { - primitiveTypes.put("int", Integer.class.getDeclaredMethod("parseInt", String.class)); - primitiveTypes.put("Integer", Integer.class.getDeclaredMethod("parseInt", String.class)); - primitiveTypes.put("long", Long.class.getDeclaredMethod("parseLong", String.class)); - primitiveTypes.put("Long", Long.class.getDeclaredMethod("parseLong", String.class)); - primitiveTypes.put("float", Float.class.getDeclaredMethod("parseFloat", String.class)); - primitiveTypes.put("Float", Float.class.getDeclaredMethod("parseFloat", String.class)); - primitiveTypes.put("double", Double.class.getDeclaredMethod("parseDouble", String.class)); - primitiveTypes.put("Double", Double.class.getDeclaredMethod("parseDouble", String.class)); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - } - - public GelfLayoutAccessLog() { - - // Init GSON for underscores - GsonBuilder gsonBuilder = new GsonBuilder(); - gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); - this.gson = gsonBuilder.create(); - } - - @Override - public void start() { - - if (fullMessageLayout == null) { - this.fullMessageLayout = initNewPatternLayout(DEFAULT_FULL_MESSAGE_PATTERN); - } - - if (shortMessageLayout == null) { - this.shortMessageLayout = initNewPatternLayout(DEFAULT_SHORT_MESSAGE_PATTERN); - } - - super.start(); - } - - private PatternLayout initNewPatternLayout(String pattern) { - PatternLayout layout = new PatternLayout(); - layout.setPattern(pattern); - layout.setContext(this.getContext()); - layout.start(); - return layout; - } - - @Override - public String doLayout(E event) { - return gson.toJson(mapFields(event)); - } - - /** - * Creates a map of properties that represent the GELF message. - * @param logEvent The log event - * @return map of gelf properties - */ - private Map mapFields(E logEvent) { - Map map = new HashMap(); - - map.put("host", host); - - map.put("full_message", fullMessageLayout.doLayout(logEvent)); - map.put("short_message", shortMessageLayout.doLayout(logEvent)); - - map.put("timestamp", logEvent.getTimeStamp() / 1000.0); - - map.put("version", "1.1"); - - additionalFields(map, logEvent); - - staticAdditionalFields(map); - - return map; - } - - /** - * Converts the additional fields into proper GELF JSON - * @param map The map of additional fields - * @param eventObject The Logging event that we are converting to GELF - */ - private void additionalFields(Map map, IAccessEvent eventObject) { - - if (useThreadName) { - map.put("_threadName", eventObject.getThreadName()); - } - - } - - private Object convertFieldType(Object value, final String type) { - if (primitiveTypes.containsKey(fieldTypes.get(type))) { - try { - value = primitiveTypes.get(fieldTypes.get(type)).invoke(null, - value); - } catch (Exception e1) { - e1.printStackTrace(); - } - } - return value; - } - - private void staticAdditionalFields(Map map) { - - for (String key : staticFields.keySet()) { - map.put(key, (staticFields.get(key))); - } - } - - private String getLocalHostName() { - try { - return InternetUtils.getLocalHostName(); - } catch (SocketException e) { - return "UNKNOWN"; - } catch (UnknownHostException e) { - return "UNKNOWN"; - } - } - - // ////////// Logback Property Getter/Setters //////////////// - - /** - * If true, an additional field call "_threadName" will be added to each gelf message. Its contents will be the Name of the thread. - * Defaults to "false". - */ - public boolean isUseThreadName() { - return useThreadName; - } - - public void setUseThreadName(boolean useThreadName) { - this.useThreadName = useThreadName; - } - - /** - * additional fields to add to the gelf message. Here's how these work:
- * Let's take an example. I want to log the client's ip address of every request that comes into my web server. To do this, I add the - * ipaddress to the slf4j MDC on each request as follows: ... MDC.put("ipAddress", "44.556.345.657"); ... Now, to include - * the ip address in the gelf message, i just add the following to my logback.groovy: - * appender("GELF", GelfAppender) { ... additionalFields = [identity:"_identity"] ... } in the additionalFields map, the key is - * the name of the MDC to look up. the value is the name that should be given to the key in the additional field in the gelf message. - */ - public Map getAdditionalFields() { - return additionalFields; - } - - public void setAdditionalFields(Map additionalFields) { - this.additionalFields = additionalFields; - } - - /** - * static additional fields to add to every gelf message. Key is the additional field key (and should thus begin with an underscore). - * The value is a static string. - */ - public Map getStaticFields() { - return staticFields; - } - - public void setStaticFields(Map staticFields) { - this.staticFields = staticFields; - } - - /** - * Indicates if all values from the MDC should be included in the gelf message or only the once listed as {@link #getAdditionalFields() - * additional fields}. - *

- * If true, the gelf message will contain all values available in the MDC. Each MDC key will be converted to a gelf custom - * field by adding an underscore prefix. If an entry exists in {@link #getAdditionalFields() additional field} it will be used instead. - *

- *

- * If false, only the fields listed in {@link #getAdditionalFields() additional field} will be included in the message. - *

- * @return the includeFullMDC - */ - public boolean isIncludeFullMDC() { - return includeFullMDC; - } - - public void setIncludeFullMDC(boolean includeFullMDC) { - this.includeFullMDC = includeFullMDC; - } - - /** - * Override the local host using a config option - * @return the local host (defaults to getLocalHost() if not overridden in config - */ - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - /** - * Add an additional field. This is mainly here for compatibility with logback.xml - * @param keyValue This must be in format key:value where key is the MDC key, and value is the GELF field name. e.g - * "ipAddress:_ip_address" - */ - public void addAdditionalField(String keyValue) { - String[] splitted = keyValue.split(":"); - - if (splitted.length != 2) { - - throw new IllegalArgumentException("additionalField must be of the format key:value, where key is the MDC " - + "key, and value is the GELF field name. But found '" + keyValue + "' instead."); - } - - additionalFields.put(splitted[0], splitted[1]); - } - - /** - * Add a staticAdditional field. This is mainly here for compatibility with logback.xml - * @param keyValue This must be in format key:value where key is the additional field key, and value is a static string. e.g - * "_node_name:www013" - * @deprecated Use addStaticField instead - */ - @Deprecated - public void addStaticAdditionalField(String keyValue) { - String[] splitted = keyValue.split(":"); - - if (splitted.length != 2) { - - throw new IllegalArgumentException("staticAdditionalField must be of the format key:value, where key is the " - + "additional field key (therefore should have a leading underscore), and value is a static string. " + - "e.g. _node_name:www013"); - } - - staticFields.put(splitted[0], splitted[1]); - } - - /** - * Add a static field. A static field is a key/value pair that should be sent in each Gelf message. This supercedes static additional - * fields, which can't have colon characters in their value. - */ - public void addStaticField(Field entry) { - staticFields.put(entry.getKey(), entry.getValue()); - } - - public void addFieldType(String keyValue) { - String[] splitted = keyValue.split(":"); - - if (splitted.length != 2 || - !GelfLayoutAccessLog.primitiveTypes.containsKey(splitted[1])) { - throw new IllegalArgumentException( - "fieldType must be of the format key:value, where key is the " + - "field key, and value is the type to convert to (one of " + - GelfLayoutAccessLog.primitiveTypes.keySet() + - ")"); - } - - fieldTypes.put(splitted[0], splitted[1]); - - } - - public Map getFieldTypes() { - return fieldTypes; - } - - public void setFieldTypes(final Map fieldTypes) { - this.fieldTypes = fieldTypes; - } - - public Layout getFullMessageLayout() { - return fullMessageLayout; - } - - public void setFullMessageLayout(Layout fullMessageLayout) { - this.fullMessageLayout = fullMessageLayout; - } - - public Layout getShortMessageLayout() { - return shortMessageLayout; - } - - public void setShortMessageLayout(Layout shortMessageLayout) { - this.shortMessageLayout = shortMessageLayout; - } -}