elastic / elastic/ecs-logging-java

feature request: objectMessageAsJsonObject

Abierto
#187 1 comentario 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

agent-java community triage
Lenguaje dominante
Java
Estrellas
148
Forks
82
Merge medio
2 d 17 h
PR fusionados (30 d)
3

Descripción

Log4j2 ObjectMessages 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.

e.g.

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 --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<Class<? extends MultiformatMessage>, Boolean> supportsJson = new ConcurrentHashMap<Class<? extends MultiformatMessage>, 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);
         }
     }
 }

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comience en log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java e inspeccione el manejo de ObjectMessage y la configuración de EcsLayout.Builder. Verifique el comportamiento mostrado por EcsLogTest, incluido el caso de error, y después añada cobertura para deshabilitar la conversión de objeto a JSON. Se considera terminado cuando la configuración acepta false y el resultado de toString() del objeto se emite en el campo message.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
java
Área
observability
Tipo de issue
Nueva funcionalidad
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.