elastic / elastic/ecs-logging-java
feature request: objectMessageAsJsonObject
- Vorherrschende Sprache
- Java
- Sterne
- 148
- Forks
- 82
- Ø Merge
- 2 T. 17 Std.
- Gemergte PRs (30 T.)
- 3
Beschreibung
Log4j2 `ObjectMessage`s are automatically converted to json objects.
This makes the log statements fail, if the object cannot be converted to json or it generates invalid json.
I would propose a `objectMessageAsJsonObject` config.
Putting it to false would just put the objects `toString()` result into the `message` field, as described in the documentation of [log4j2](https://logging.apache.org/log4j/2.x/manual/messages.html#ObjectMessage).
e.g.
```java
public class EcsLogTest {
static class A {
String getA() {
Objects.requireNonNull(null);
return null;
}
}
@Test
void test() {
LogManager.getLogger().info(new A());
}
}
```
produces:
```
{"@timestamp":"2022-05-16T12:06:08.284Z", "log.level": "INFO", , "ecs.version": "1.2.0","process.thread.name":"main","log.logger":"EcsLogTest"}
```
This patch would probably enough to implement this feature:
```diff
diff --git a/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java b/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java
index 1a99742..41937c7 100644
--- a/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java
+++ b/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java
@@ -79,9 +79,10 @@ public class EcsLayout extends AbstractStringLayout {
private final boolean includeOrigin;
private final PatternFormatter[] exceptionPatternFormatter;
private final ConcurrentMap, Boolean> supportsJson = new ConcurrentHashMap, Boolean>();
+ private final boolean objectMessageAsJsonObject;
private EcsLayout(Configuration config, String serviceName, String serviceVersion, String serviceEnvironment, String serviceNodeName, String eventDataset, boolean includeMarkers,
- KeyValuePair[] additionalFields, boolean includeOrigin, String exceptionPattern, boolean stackTraceAsArray) {
+ KeyValuePair[] additionalFields, boolean includeOrigin, String exceptionPattern, boolean stackTraceAsArray, boolean objectMessageAsJsonObject) {
super(config, UTF_8, null, null);
this.serviceName = serviceName;
this.serviceVersion = serviceVersion;
@@ -92,6 +93,7 @@ public class EcsLayout extends AbstractStringLayout {
this.includeOrigin = includeOrigin;
this.stackTraceAsArray = stackTraceAsArray;
this.additionalFields = additionalFields;
+ this.objectMessageAsJsonObject = objectMessageAsJsonObject;
fieldValuePatternFormatter = new PatternFormatter[additionalFields.length][];
for (int i = 0; i < additionalFields.length; i++) {
KeyValuePair additionalField = additionalFields[i];
@@ -253,7 +255,7 @@ public class EcsLayout extends AbstractStringLayout {
} else {
serializeSimpleMessage(builder, gcFree, message, thrown);
}
- } else if (JACKSON_SERIALIZER != null && message instanceof ObjectMessage) {
+ } else if (JACKSON_SERIALIZER != null && message instanceof ObjectMessage && objectMessageAsJsonObject) {
final StringBuilder jsonBuffer = EcsJsonSerializer.getMessageStringBuilder();
JACKSON_SERIALIZER.formatTo(jsonBuffer, (ObjectMessage) message);
addJson(builder, jsonBuffer);
@@ -377,6 +379,8 @@ public class EcsLayout extends AbstractStringLayout {
private KeyValuePair[] additionalFields = new KeyValuePair[]{};
@PluginBuilderAttribute("includeOrigin")
private boolean includeOrigin = false;
+ @PluginBuilderAttribute("objectMessageAsJsonObject")
+ private boolean objectMessageAsJsonObject = true;
Builder() {
}
@@ -428,6 +432,10 @@ public class EcsLayout extends AbstractStringLayout {
return exceptionPattern;
}
+ public boolean isObjectMessageAsJsonObject() {
+ return objectMessageAsJsonObject;
+ }
+
/**
* Additional fields to set on each log event.
*
@@ -483,11 +491,16 @@ public class EcsLayout extends AbstractStringLayout {
return this;
}
+ public EcsLayout.Builder setObjectMessageAsJsonObject(boolean objectMessageAsJsonObject) {
+ this.objectMessageAsJsonObject = objectMessageAsJsonObject;
+ return this;
+ }
+
@Override
public EcsLayout build() {
return new EcsLayout(getConfiguration(), serviceName, serviceVersion, serviceEnvironment, serviceNodeName,
EcsJsonSerializer.computeEventDataset(eventDataset, serviceName),
- includeMarkers, additionalFields, includeOrigin, exceptionPattern, stackTraceAsArray);
+ includeMarkers, additionalFields, includeOrigin, exceptionPattern, stackTraceAsArray, objectMessageAsJsonObject);
}
}
}
```
Beitragsleitfaden
Rechercherichtung
Beginnen Sie in log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java und untersuchen Sie die Verarbeitung von ObjectMessage sowie die Konfiguration von EcsLayout.Builder. Überprüfen Sie das in EcsLogTest gezeigte Verhalten, einschließlich des Fehlerfalls, und fügen Sie anschließend Abdeckung für das Deaktivieren der Objekt-zu-JSON-Konvertierung hinzu. Fertig ist die Änderung, wenn die Konfiguration false akzeptiert und das Ergebnis von toString() des Objekts im message-Feld ausgegeben wird.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- java
- Bereich
- observability
- Issue-Typ
- Feature
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100