2016-09-22 3 views
2

Я использую log4j для проектов разных типов и имею некоторый опыт работы с log4j2. Во всех реализациях использовались компоновщик и макет по умолчанию. В настоящее время мне нужно написать приложение, которое записывается в формате json. Поэтому я попробовал компоновку log4j2 JSONLayout, установив очень простой log4j2-регистратор.Лучший способ писать пользовательские сообщения json с помощью log4j2

public class JSONLogger { 

    private static final Logger LOGGER = LogManager.getLogger(); 

    public static void main(String[] args) { 
     JSONLogger jsonlogger = new JSONLogger() ; 
    } 

    public JSONLogger() { 
     LOGGER.log(Level.FATAL, "hi mum!") ; 

     int val1 = 10, val2 = 11, val3 = 12; 

     LOGGER.log(Level.FATAL,"val1={}, val2={}, val3={}", val1, val2, val3); 
    } 

} 

jsonLoggerProperties.xml

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration status="DEBUG"> 
    <Properties> 
     <Property name="log-path">/Users/petervannes/NetBeansProjects/JSONLogger/logfiles</Property> 
    </Properties> 

    <Appenders> 
     <RollingFile name="json_file_appender" fileName="${log-path}/jsonlogger.json" 
        filePattern="${log-path}/%d{yyyyMMdd}_jsonlogger-%i.json" > 
      <JSONLayout complete="true" compact="false"/> 
      <Policies> 
       <SizeBasedTriggeringPolicy size="1 KB" /> 
      </Policies> 
      <DefaultRolloverStrategy max="4"/> 
     </RollingFile> 

    </Appenders> 


    <Loggers> 
     <root level="debug" additivity="false"> 
      <AppenderRef ref="json_file_appender"/> 
     </root> 
    </Loggers> 
</Configuration> 

В результате в записи журнала аналогично;

, { 
    "timeMillis" : 1474573600359, 
    "thread" : "main", 
    "level" : "FATAL", 
    "loggerName" : "JSONLogger", 
    "message" : "val1=10, val2=11, val3=12", 
    "contextStack" : [ "fieldName2" ], 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 1, 
    "threadPriority" : 5 
} 

Что мне нужно, чтобы войти в формат JSON следующим образом:

, { 
    "DateTime" : "08/01/2016 21:33:22.334", 
    "level" : "FATAL", 
    "Summary" : "Something has gone wrong", 
    "ChainManager" : "Manager A", 
    "Optionals" : { "Key_1": "Value1", 
        "Key_2": "Value2" } 
} 

Это possibile с log4j2 JSONLayout или есть любой другой макет я могу использовать, чтобы получить этот формат?

ответ

2

Я нашел решение, которое работает для меня; slf4j-json-logger. Это рама slf4j, поэтому она должна быть включена в pom.xml. Примеры файлов проекта;

pom.xml

<?xml version="1.0" encoding="UTF-8"?> 
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.reddipped</groupId> 
    <artifactId>JSONLogger_2</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 
    <properties> 

     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <maven.compiler.source>1.6</maven.compiler.source> 
     <maven.compiler.target>1.6</maven.compiler.target> 

     <mainClass>com.reddipped.jsonlogger_2.Test</mainClass> 

     <slf4j.version>1.7.21</slf4j.version> 
     <!-- current log4j 2 release --> 
     <log4j.version>2.6.2</log4j.version> 

    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>slf4j-api</artifactId> 
      <version>${slf4j.version}</version> 
     </dependency> 
     <!-- Binding for Log4J --> 
     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-slf4j-impl</artifactId> 
      <version>${log4j.version}</version> 
     </dependency> 
     <!-- Log4j API and Core implementation required for binding --> 
     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-api</artifactId> 
      <version>${log4j.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.apache.logging.log4j</groupId> 
      <artifactId>log4j-core</artifactId> 
      <version>${log4j.version}</version> 
     </dependency> 
     <!-- Logger slf4j-json-logger --> 
     <dependency> 
      <groupId>com.savoirtech.logging</groupId> 
      <artifactId>slf4j-json-logger</artifactId> 
      <version>2.0.2</version> 
     </dependency> 
    </dependencies> 
    </project> 

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?> 

    <!-- 

    Use java property log4j.configurationFile to specify log4j2.xml location 
    if not available in classpath 

    - Dlog4j.configurationFile="/Users/petervannes/NetBeansProjects/JSONLogger_2/src/mann/java/resources/log4j2.xml" 

    --> 
    <configuration status="trace"> 
    <Properties> 
     <Property name="log-path">/Users/petervannes/NetBeansProjects/JSONLogger_2/logfiles</Property> 
    </Properties> 
    <appenders> 
     <RollingFile name="RollingFile" fileName="${log-path}/jsonlogger.json" 
        filePattern="${log-path}/%d{yyyyMMdd}_jsonlogger-%i.json" > 
      <PatternLayout> 
       <pattern>%m%n</pattern> 
      </PatternLayout> 
      <Policies> 
       <TimeBasedTriggeringPolicy /> 
       <SizeBasedTriggeringPolicy size="1 KB" /> 
      </Policies> 
      <DefaultRolloverStrategy max="4"/> 
     </RollingFile> 
    </appenders> 
    <Loggers> 
     <Logger name="JSONLogger" level="debug" additivity="false"> 
      <AppenderRef ref="RollingFile" /> 
     </Logger> 
     <Root level="debug"> 
      <AppenderRef ref="RollingFile" /> 
     </Root> 
    </Loggers> 
    </configuration> 

Пример Java-код

package com.reddipped.jsonlogger_2; 

    import com.savoirtech.logging.slf4j.json.LoggerFactory; 
    import java.util.HashMap; 
    import java.util.Map; 

    /** 
    * 
    * @author petervannes 
    */ 
    public class Test { 
     public static void main(String[] args) { 
     Test t = new Test() ; 
    } 


    public Test() { 

     LoggerFactory.setIncludeLoggerName(false); 
     LoggerFactory.setDateFormatString("yyyy-MM-dd HH:mm:ss.SSS"); 

     com.savoirtech.logging.slf4j.json.logger.Logger LOGGER = LoggerFactory.getLogger("JSONLogger"); 

    Map<String, String> optionalFields = new HashMap(); 
    optionalFields.put("CaseNumber", "C12.12343"); 
    optionalFields.put("Step","Assignment") ; 
    optionalFields.put("Department","BPM") ; 

    String LOB = "Business Administration" ; 
    String Service = "DocumentService" ; 
    String Process = "AddAttachements" ; 
    String Reason = "Technical" ; 

    LOGGER.error().message("Conversion error 'incompatible PDF document'") 
      .field("LOB",LOB) 
      .field("Service", Service) 
      .field("Process",Process) 
      .field("Reason", Reason) 
      .map("OptionalFields", optionalFields).log() ; 
    } 

    } 

JSON Вход Вход

{ 
    "message": "Conversion error 'incompatible PDF document'", 
    "LOB": "Business Administration", 
    "Service": "DocumentService", 
    "Process": "AddAttachements", 
    "Reason": "Technical", 
    "OptionalFields": { 
    "Step": "Assignment", 
    "Department": "BPM", 
    "CaseNumber": "C12.12343" 
    }, 
    "level": "ERROR", 
    "thread_name": "main", 
    "class": "com.reddipped.jsonlogger_2.Test", 
    "@timestamp": "2016-09-23 10:18:06.623" 
    } 
+0

Nice, но я хочу, чтобы я мог достичь этой цели без sl4j. log4j2.8 все еще имеет поддержку – prayagupd

+0

Вы можете, мне пришлось искать альтернативный путь, потому что slF4j интерферировал. – pcvnes

+0

В моем комментарии я хочу сказать, что «log4j 2.8 все еще не поддерживает json logs». Он печатает в формате json, но не в сообщении, которое я добавляю. – prayagupd

 Смежные вопросы

  • Нет связанных вопросов^_^