How to modify log4j JsonLayout field names How to modify log4j JsonLayout field names json json

How to modify log4j JsonLayout field names


You can customize JacksonFactory class to include only field names that you want in log entry. Default implementation in JacksonFactory is excluding only two fields from log entry which are location and properties (that too based on parameters properties and source). But if you want to exclude more fields you could add more field names to exclude in set of properties to exclude, Here is the example

ObjectWriter newWriter(final boolean locationInfo, final boolean properties, final boolean compact) {        final SimpleFilterProvider filters = new SimpleFilterProvider();        final Set<String> except = new HashSet<>(5);        if (!locationInfo) {            except.add(this.getPropertNameForSource());        }        if (!properties) {            except.add(this.getPropertNameForContextMap());    }    except.add(this.getPropertNameForNanoTime());    except.add("loggerFqcn");    except.add("endOfBatch");    filters.addFilter(Log4jLogEvent.class.getName(), SimpleBeanPropertyFilter.serializeAllExcept(except));    final ObjectWriter writer = this.newObjectMapper().writer(compact ? this.newCompactPrinter() : this.newPrettyPrinter());    return writer.with(filters);}


I'm basing my response on this manual reference.

1) Apparently the only parameters the JSONLayout takes are charset, compact, complete, properties, and locationInfo. Unfortunately based on my limited research, removing endOfBatch and loggerFqcn doesn't appear possible. (This is odd, however, since the example output in the referenced manual does not include these fields.)

2) This is almost certainly not possible. The concept of a log entry in log4j involves a string message, possibly a throwable, a log level, and a few other static things. Custom fields aren't possible without writing a custom class. This SO question describes doing that, though for the purpose of that question, MDC was used in the end. MDC wouldn't serve your purposes since you want to have custom fields that are different in each entry. I'm not sure what you mean by "flatten."

3) Unfortunately this doesn't look like it's available either. PatternLayout is much more customizable; AFAIK you will have to customize JSONLayout yourself.


user JsonTemplateLayout:

Pom.xml:

<dependency>    <groupId>org.apache.logging.log4j</groupId>    <artifactId>log4j-layout-template-json</artifactId>    <version>2.14.1</version></dependency>

log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?><Configuration status="INFO">    <Appenders>        <Console name="console" target="SYSTEM_OUT">            <JsonTemplateLayout eventTemplateUri="classpath:JsonTemplateLayout.json" />        </Console>    </Appenders>    <Loggers>        <Logger name="com.logging.a.b" level="error" additivity="false">            <AppenderRef ref="console" />        </Logger>    </Loggers></Configuration>

src/main/resources/JsonTemplateLayout.json:

{    "version": "1.1",    "hostName": "${hostName}",    "field1": "${env:JAVA_HOME}",    "field2": "${sys:os.name}",    "time": {        "$resolver": "timestamp",        "pattern": {            "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",            "timeZone": "UTC"        }    },    "level": {        "$resolver": "level",        "field": "name"    },    "loggerName": {        "$resolver": "logger",        "field": "name"    },    "message": {        "$resolver": "message",        "stringified": true    },    "source": {        "class": {            "$resolver": "source",            "field": "className"        },        "method": {            "$resolver": "source",            "field": "methodName"        },        "file": {            "$resolver": "source",            "field": "fileName"        },        "line": {            "$resolver": "source",            "field": "lineNumber"        }    },}

You can add and remove fields, or change name of fields by changing the above template file.See more examples here: json template file