it-swarm.com.de

Gibt es ein Logback-Layout, das JSON-Objekte mit Nachrichtenparametern als Attributen erstellt?

Ich möchte Protokollereignisse an Loggly als JSON-Objekte mit parametrisierten Zeichenfolgenachrichten senden. Unser Projekt enthält derzeit eine Menge Code, der folgendermaßen aussieht:

String someParameter = "1234";
logger.log("This is a log message with a parameter {}", someParameter);

Wir verwenden derzeit Logback als SLF4J-Backend und JsonLayout von Logback, um unsere ILogEvent-Objekte in JSON zu serialisieren. Wenn also unsere Protokollereignisse an Loggly gesendet werden, sehen sie folgendermaßen aus:

{
    "message": "This is a log message with a parameter 1234",
    "level": INFO,
    ....
}

Während dies funktioniert, sendet es für jeden Wert von message eine andere someParameter-Zeichenfolge, wodurch die automatischen Filter von Loggly nahezu nutzlos werden.

Stattdessen möchte ich ein Layout haben, das JSON erstellt, das folgendermaßen aussieht:

{
    "message": "This is a log message with a parameter {}",
    "level": INFO,
    "parameters": [
        "1234"
    ]
}

Dieses Format würde es Loggly ermöglichen, alle Protokollereignisse mit der Nachricht This is a log message with a parameter zusammenzufassen, unabhängig vom Wert von someParameter.

Es sieht so aus, als ob Logstashs KV-Filter so etwas tut - gibt es eine Möglichkeit, diese Aufgabe mit Logback zu erledigen, ohne ein eigenes Layout zu schreiben, das eine benutzerdefinierte Serialisierung des ILogEvent-Objekts durchführt?

22
MusikPolice

Sie können einen Mapped Diagnostic Context verwenden, um für jede Art von Protokollnachrichten einen Stempel zu setzen, nach dem Sie dann einmal im Protokoll filtern könnten.

Entsprechend der Quelle von JsonLayout wird der Stempel als separater Wert in der JSON gespeichert. 

5
muttonUp

Es gibt einen JSON-Logstash-Encoder für Logback, Logstash-Logback-Encoder

13
Mark Roper

Also habe ich versucht, die Ausführungszeiten zu protokollieren. Ich habe einen Pojo namens ExecutionTime mit Namen, Methode, Klasse und Dauer erstellt.

Ich konnte es dann erstellen:

ExecutionTime time = new ExecutionTime("Controller Hit", methodName, className, sw.getTotalTimeMillis());

Zum Loggen habe ich dann verwendet:

private final Logger logger = LoggerFactory.getLogger(this.getClass());
logger.info(append("metric", time), time.toString());

Stell sicher dass du hast: 

import static net.logstash.logback.marker.Markers.append;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Dies wird so etwas protokollieren:

{  
   "ts":"2017-02-16T07:41:36.680-08:00",
   "msg":"ExecutionTime [name=Controller Hit, method=setupSession, className=class com.xxx.services.controllers.SessionController, duration=3225]",
   "logger":"com.xxx.services.metrics.ExecutionTimeLogger",
   "level":"INFO",
   "metric":{  
      "name":"Controller Hit",
      "method":"setupSession",
      "className":"class com.xxx.services.controllers.SessionController",
      "duration":3225
   }
}

Könnte eine andere Einstellung sein, da ich logback-spring.xml zur Ausgabe meiner Protokolle an json verwendet habe:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <property name="PROJECT_ID" value="my_service"/>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>app/logs/${PROJECT_ID}.json.log</File>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <fieldNames>
                <timestamp>ts</timestamp>
                <message>msg</message>
                <thread>[ignore]</thread>
                <levelValue>[ignore]</levelValue>
                <logger>logger</logger>
                <version>[ignore]</version>
            </fieldNames>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <maxIndex>10</maxIndex>
            <FileNamePattern>app/logs/${PROJECT_ID}.json.log.%i</FileNamePattern>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>20MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <logger name="com.xxx" additivity="false" level="DEBUG">
        <appender-ref ref="FILE"/>
        <appender-ref ref="CONSOLE"/>
    </logger>
    <root level="WARN">
        <appender-ref ref="FILE"/>
    </root>
</configuration>
5
user2022484

Hier ist ein kürzlich erstelltes Projekt, das eine JSON-spezifische Protokollierungs-API bereitstellt und mit SLF4J zusammenarbeitet:

https://github.com/savoirtech/slf4j-json-logger

4
ash

Wie bereits beantwortet erhalten Sie einen eindimensionalen JSON-Baum mit MDC und/oder einen Marker mit Logstash-Logback-Encoder.

Wenn Sie auch folgendes suchen:

  • codebücher zur Definition des protokollierten Datentypschlüssels und -typs,
  • konfiguration von Protokollaggregationswerkzeugen (wie Elasticsearch)
  • erzeugter Java-Helper-Code für eine effiziente und korrekte Protokollierung

versuchen Sie dann ein von mir erstelltes Projekt: json-log-domain . Es definiert eine einfache Definition des YAML-Formats, aus der das Obige generiert werden kann.

Ein Beispiel für eine Helper-Code-Anweisung wäre

logger.info(Host("localhost").port(8080), "Hello world");

während erzeugter Abschlag möchte so etwas wie this .

0
ThomasRS