Giter Site home page Giter Site logo

log4j2-logstash-layout's Introduction

log4j2-logstash-layout is not maintained anymore! Since Log4j 2.14.0, it is superseded by log4j-layout-template-json shipping JsonTemplateLayout, which is a successor of LogstashLayout. We strongly advise all LogstashLayout users to migrate to JsonTemplateLayout. We will do our best to bring bug fixes to LogstashLayout, but all the new development efforts will be focused on JsonTemplateLayout.

Actions Status Maven Central License

LogstashLayout is the fastest Log4j 2 JSON layout allowing schema customization and Logstash-friendly output.

By default, LogstashLayout ships the official JSONEventLayoutV1 stated by log4j-jsonevent-layout Log4j 1.x plugin. Compared to JSONLayout included in Log4j 2 and log4j-jsonevent-layout, LogstashLayout provides the following additional features:

  • Superior performance
  • Customizable JSON schema (see eventTemplate[Uri] and stackTraceElementTemplate[Uri] parameters)
  • Customizable timestamp formatting (see dateTimeFormatPattern and timeZoneId parameters)

Table of Contents

Usage

Add the log4j2-logstash-layout dependency to your POM file

<dependency>
    <groupId>com.vlkan.log4j2</groupId>
    <artifactId>log4j2-logstash-layout</artifactId>
    <version>${log4j2-logstash-layout.version}</version>
</dependency>

in combination with a valid log4j-core dependency:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>${log4j2.version}</version>
</dependency>

(Note that the Java 9 module name is com.vlkan.log4j2.logstash.layout.)

Below you can find a sample log4j2.xml snippet employing LogstashLayout.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
    <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <LogstashLayout dateTimeFormatPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZZZ"
                            eventTemplateUri="classpath:LogstashJsonEventLayoutV1.json"
                            prettyPrintEnabled="true"
                            stackTraceEnabled="true"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="CONSOLE"/>
        </Root>
    </Loggers>
</Configuration>

Or using the log4j2.properties file instead:

status = warn

appender.console.name = CONSOLE
appender.console.type = CONSOLE
appender.console.target = SYSTEM_OUT

appender.console.logstash.type = LogstashLayout
appender.console.logstash.dateTimeFormatPattern = yyyy-MM-dd'T'HH:mm:ss.SSSZZZ
appender.console.logstash.eventTemplateUri = classpath:LogstashJsonEventLayoutV1.json
appender.console.logstash.prettyPrintEnabled = true
appender.console.logstash.stackTraceEnabled = true

rootLogger.level = info
rootLogger.appenderRef.stdout.ref = CONSOLE

This generates an output as follows:

{
  "exception": {
    "exception_class": "java.lang.RuntimeException",
    "exception_message": "test",
    "stacktrace": "java.lang.RuntimeException: test\n\tat com.vlkan.log4j2.logstash.layout.demo.LogstashLayoutDemo.main(LogstashLayoutDemo.java:11)\n"
  },
  "line_number": 12,
  "class": "com.vlkan.log4j2.logstash.layout.demo.LogstashLayoutDemo",
  "@version": 1,
  "source_host": "varlik",
  "message": "Hello, error!",
  "thread_name": "main",
  "@timestamp": "2017-05-25T19:56:23.370+02:00",
  "level": "ERROR",
  "file": "LogstashLayoutDemo.java",
  "method": "main",
  "logger_name": "com.vlkan.log4j2.logstash.layout.demo.LogstashLayoutDemo"
}

LogstashLayout is configured with the following parameters:

Parameter Name Type Description
prettyPrintEnabled boolean enables pretty-printer (defaults to false)
locationInfoEnabled boolean includes the filename and line number in the output (defaults to false)
stackTraceEnabled boolean includes stack traces (defaults to false)
emptyPropertyExclusionEnabled boolean exclude empty and null properties (defaults to false)
dateTimeFormatPattern String timestamp formatter pattern (defaults to yyyy-MM-dd'T'HH:mm:ss.SSSZZZ)
timeZoneId String time zone id (defaults to TimeZone.getDefault().getID())
locale String locale in one of the following forms: <language>, <language>_<country>, or <language>_<country>_<variant> (defaults to Locale.getDefault())
mdcKeyPattern String regex to filter MDC keys (does not apply to direct mdc:key access)
ndcPattern String regex to filter NDC items
eventTemplate String inline JSON template for rendering LogEvents (has priority over eventTemplateUri)
eventTemplateUri String JSON template for rendering LogEvents (defaults to classpath:LogstashJsonEventLayoutV1.json)
eventTemplateAdditionalFields1 KeyValuePair additional key-value pairs appended to the root of the event template
stackTraceElementTemplate String inline JSON template for rendering StackTraceElements (has priority over stackTraceElementTemplateUri)
stackTraceElementTemplateUri String JSON template for rendering StackTraceElements (defaults to classpath:Log4j2StackTraceElementLayout.json)
lineSeparator String used to separate log outputs (defaults to System.lineSeparator())
maxByteCount int used to cap the internal byte[] buffer used for serialization (defaults to 16 KiB)
maxStringLength2 int truncate string values longer than the specified limit (defaults to 0)
objectMapperFactoryMethod String custom object mapper factory method (defaults to com.fasterxml.jackson.databind.ObjectMapper.new)
mapMessageFormatterIgnored boolean as a temporary work around for LOG4J2-2703, serialize MapMessages using Jackson rather than MapMessage#getFormattedMessage() (defaults to true)

1 One can configure additional event template fields as follows:

<LogstashLayout ...>
    <EventTemplateAdditionalFields>
        <KeyValuePair key="serviceName" value="auth-service"/>
        <KeyValuePair key="containerId" value="6ede3f0ca7d9"/>
    </EventTemplateAdditionalFields>
</LogstashLayout>

2 Note that string value truncation via maxStringLength can take place both in object keys and values, and this operation does not leave any trace behind. maxStringLength is intended as a soft protection against bogus input and one should always rely on maxByteCount for a hard limit.

eventTemplateUri denotes the URI pointing to the JSON template that will be used while formatting the LogEvents. By default, LogstashLayout ships LogstashJsonEventLayoutV1.json providing the official Logstash JSONEventLayoutV1.

{
  "mdc": "${json:mdc}",
  "ndc": "${json:ndc}",
  "exception": {
    "exception_class": "${json:exception:className}",
    "exception_message": "${json:exception:message}",
    "stacktrace": "${json:exception:stackTrace:text}"
  },
  "line_number": "${json:source:lineNumber}",
  "class": "${json:source:className}",
  "@version": 1,
  "source_host": "${hostName}",
  "message": "${json:message}",
  "thread_name": "${json:thread:name}",
  "@timestamp": "${json:timestamp}",
  "level": "${json:level}",
  "file": "${json:source:fileName}",
  "method": "${json:source:methodName}",
  "logger_name": "${json:logger:name}"
}

Similarly, stackTraceElementUri denotes the URI pointing to the JSON template that will be used while formatting the StackTraceElements. By default, LogstashLayout ships classpath:Log4j2StackTraceElementLayout.json providing an identical stack trace structure produced by Log4j 2 JSONLayout.

{
  "class": "${json:stackTraceElement:className}",
  "method": "${json:stackTraceElement:methodName}",
  "file": "${json:stackTraceElement:fileName}",
  "line": "${json:stackTraceElement:lineNumber}"
}

In case of need, you can create your own templates with a structure tailored to your needs. That is, you can add new fields, remove or rename existing ones, change the structure, etc. Please note that eventTemplateUri parameter only supports file and classpath URI schemes.

Below is the list of allowed LogEvent template variables that will be replaced while rendering the JSON output.

Variable Name Description
endOfBatch logEvent.isEndOfBatch()
exception:className logEvent.getThrown().getClass().getCanonicalName()
exception:message logEvent.getThrown().getMessage()
exception:stackTrace logEvent.getThrown().getStackTrace() (inactive when stackTraceEnabled=false)
exception:stackTrace:text logEvent.getThrown().printStackTrace() (inactive when stackTraceEnabled=false)
exceptionRootCause:className the innermost exception:className in causal chain
exceptionRootCause:message the innermost exception:message in causal chain
exceptionRootCause:stackTrace[:text] the innermost exception:stackTrace[:text] in causal chain
level logEvent.getLevel()
level:severity Syslog severity keyword of logEvent.getLevel()
level:severity:code Syslog severity code of logEvent.getLevel()
logger:fqcn logEvent.getLoggerFqcn()
logger:name logEvent.getLoggerName()
main:<key> performs Main Argument Lookup for the given key
map:<key> performs Map Lookup for the given key
marker:name logEvent.getMarker.getName()
mdc Mapped Diagnostic Context Map<String, String> returned by logEvent.getContextData()
mdc:<key> Mapped Diagnostic Context String associated with key (mdcKeyPattern is discarded)
message logEvent.getFormattedMessage()
message:json if logEvent.getMessage() is of type MultiformatMessage and supports JSON, its read value, otherwise, {"message": <formattedMessage>} object
ndc Nested Diagnostic Context String[] returned by logEvent.getContextStack()
source:className logEvent.getSource().getClassName()
source:fileName logEvent.getSource().getFileName() (inactive when locationInfoEnabled=false)
source:lineNumber logEvent.getSource().getLineNumber() (inactive when locationInfoEnabled=false)
source:methodName logEvent.getSource().getMethodName()
thread:id logEvent.getThreadId()
thread:name logEvent.getThreadName()
thread:priority logEvent.getThreadPriority()
timestamp logEvent.getTimeMillis() formatted using dateTimeFormatPattern and timeZoneId
timestamp:epoch epoch nanoseconds derived from logEvent.getInstant()
timestamp:epoch:divisor=<divisor> epoch nanoseconds derived from logEvent.getInstant() divided by provided divisor (of type double)
timestamp:epoch:divisor=<divisor>,integral epoch nanoseconds derived from logEvent.getInstant() divided by provided divisor (of type double) and casted to long

JSON field lookups are performed using the ${json:<variable-name>} scheme where <variable-name> is defined as <resolver-name>[:<resolver-key>]. Characters following colon (:) are treated as the resolver-key.

Log4j 2 Lookups (e.g., ${java:version}, ${env:USER}, ${date:MM-dd-yyyy}) are supported in templates too. Though note that while ${json:...} template variables are expected to occupy an entire field, that is, "level": "${json:level}", a lookup can be mixed within a regular text: "myCustomField": "Hello, ${env:USER}!".

Similarly, below is the list of allowed StackTraceElement template variables:

Variable Name Description
stackTraceElement:className stackTraceElement.getClassName()
stackTraceElement:methodName stackTraceElement.getMethodName()
stackTraceElement:fileName stackTraceElement.getFileName()
stackTraceElement:lineNumber stackTraceElement.getLineNumber()

As in LogEvent templates, StackTraceElement templates support Log4j 2 lookups too.

See layout-demo directory for a sample application demonstrating the usage of LogstashLayout.

Predefined Templates

log4j2-logstash-layout artifact contains the following predefined templates:

Features

Below is a feature comparison matrix between LogstashLayout and alternatives.

Feature LogstashLayout JsonLayout EcsLayout
Java version 8 73 6
Dependencies Jackson Jackson None
Full schema customization?
Timestamp customization?
(Almost) garbage-free?
Custom typed Message serialization? 4
Custom typed MDC value serialization?
Rendering stack traces as array?
Enabling/Disabling JSON pretty print?
Additional fields?

3 Log4j 2.4 and greater requires Java 7, versions 2.0-alpha1 to 2.3 required Java 6.

4 Only for ObjectMessages and if Jackson is in the classpath.

Fat JAR

Project also contains a log4j2-logstash-layout-fatjar artifact which includes all its transitive dependencies in a separate shaded package (to avoid the JAR Hell) with the exception of log4j-core, that you need to include separately.

This might come handy if you want to use this plugin along with already compiled applications, e.g., Elasticsearch 5.x and 6.x versions, which requires Log4j 2.

Appender Support

log4j2-logstash-layout is all about providing a highly customizable JSON schema for your logs. Though this does not necessarily mean that all of its features are expected to be supported by every appender in the market. For instance, while prettyPrintEnabled=true works fine with log4j2-redis-appender, it should be turned off for Logstash's log4j-json file input type. (See Pretty printing in Logstash issue.) Make sure you configure log4j2-logstash-layout properly in a way that is aligned with your appender of preference.

Performance

The source code contains a benchmark comparing LogstashLayout performance with JsonLayout (shipped by default in Log4j 2) and EcsLayout (shipped by Elastic). There JMH is used to assess the rendering performance of these layouts. In the tests, different LogEvent profiles are employed:

  • full: LogEvent contains MDC, NDC, and an exception.
  • lite: LogEvent has no MDC, NDC, or exception attachment.

To give an idea, we ran the benchmark with the following settings:

  • CPU: Intel i7 2.70GHz (x86-64, confined java process to a single core using taskset -c 0)
  • JVM: OpenJDK 64-Bit, AdoptOpenJDK, build 25.232-b09
    • -XX:+TieredCompilation
    • -Dlog4j2.garbagefreeThreadContextMap=true
    • -Dlog4j2.enableDirectEncoders=true
    • -Dlog4j2.enable.threadlocals=true
    • -Dlog4j2.is.webapp=false
  • OS: Xubuntu 18.04.3 (4.15.0-70-generic, x86-64)
  • LogstashLayout4{Ecs,Json,Gelf}Layout used default settings with the following exceptions:
    • stackTraceEnabled: true
    • maxByteCount: (4096) 4KiB
  • JsonLayout used in two different flavors:
    • DefaultJsonLayout: default settings
    • CustomJsonLayout: default settings with an additional "@version": 1 field (this forces instantiation of a wrapper class to obtain the necessary Jackson view)
  • EcsLayout used with the following configurations:
    • serviceName: benchmark
    • additionalFields: new KeyValuePair[0]
  • GelfLayout used with the following configurations:
    • compressionType: off

The figures for serializing 1,000 LogEvents at each operation are as follows. (See layout-benchmark directory for the full report.)

Benchmark ops/sec5 B/op5
liteLogstashLayout4GelfLayout 1,517,062 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ (100%) 0.0
liteLogstashLayout4EcsLayout 1,196,255 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ (79%) 0.0
liteGelfLayout 1,184,922 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ (78%) 0.0
liteLogstashLayout4JsonLayout 870,012 ▉▉▉▉▉▉▉▉▉▉▉ (57%) 0.0
liteEcsLayout 836,648 ▉▉▉▉▉▉▉▉▉▉▉ (55%) 0.0
liteDefaultJsonLayout 506,985 ▉▉▉▉▉▉▉ (33%) 5,331,680.0
liteCustomJsonLayout 446,243 ▉▉▉▉▉▉ (29%) 5,740,400.0
fullLogstashLayout4JsonLayout 118,294 ▉▉ (8%) 104,000.1
fullLogstashLayout4GelfLayout 73,102 ▉ (5%) 35,663,200.3
fullLogstashLayout4EcsLayout 60,569 ▉ (4%) 35,631,200.4
fullEcsLayout 27,887 ▉ (2%) 46,479,200.5
fullGelfLayout 21,458 ▉ (1%) 58,911,200.7
fullDefaultJsonLayout 13,513 ▉ (1%) 234,102,401.5
fullCustomJsonLayout 13,511 ▉ (1%) 234,238,401.5

5 99th percentile

Let us try to answer some common questions:

  • How come log4j2-logstash-layout can yield superior performance compared to Log4j 2 JsonLayout? Log4j 2 JsonLayout employs a single Jackson view to generate JSON, XML, and YAML outputs. For this purpose, it uses Jackson ObjectMapper, which needs to walk over the class fields via reflection and perform heavy branching and intermediate object instantiation. On the contrary, log4j2-logstash-layout parses the given template once and compiles a (mostly) garbage- and (to a certain extent) branching-free JSON generator employing Jackson JsonGenerator.

  • Why is log4j2-logstash-layout is not totally garbage-free?

    • Since Throwable#getStackTrace() clones the original StackTraceElement[], accesses to (and hence rendering) stack traces can never be garbage-free.

    • Rendering of context data (that is, MDC) field values is garbage-free if the value is either null, or of type String, Short, Integer, Long, or byte[].

  • How can one run the benchmark on his/her machine? After a fresh mvn clean verify within the source directory, run layout-benchmark/benchmark.py.

  • What about thread-local allocations? Even though Log4j 2 exposes a log4j2.enable.threadlocals flag to toggle TLAs, neither EcsLayout, nor Log4j 2 JsonLayout and GelfLayout honor it. Historically, LogstashLayout used to have TLAs taking the log4j2.enable.threadlocals flag into account. In version 0.18, we switched to simple memory-efficient object pools, though that incurred extra synchronization costs. Since version 0.22, LogstashLayout switched back to TLAs taking log4j2.enable.threadlocals into account.

F.A.Q.

  • How can one enable thread-local allocations? For performance reasons, it is highly recommended to turn TLAs on. For this purpose, you need to make sure log4j2.enable.threadlocals=true and log4j2.is.webapp=false.

  • Is there a fat JAR of the plugin? Project also contains a log4j2-logstash-layout-fatjar artifact which includes all its transitive dependencies in a separate shaded package (to avoid the JAR Hell) with the exception of log4j-core, that you need to include separately. Fat JAR might come handy if you want to use this plugin along with certain applications, e.g., Elasticsearch 5.x and 6.x versions, which requires Log4j 2.

  • Why do I get irrelevant stack traces from exception[RootCause]:stackTrace[:text] directives? LogstashLayout uses Throwable#printStackTrace(PrintWriter) and Throwable#getStackTrace() methods to resolve these directives. Under certain circumstances, these methods may throw exception as well. Put another way, trying to access the stack trace of an exception might cause another exception. In such a case, LogstashLayout continues the directive resolution using the new exception and keeps on repeating until it manages to resolve a stack trace to at least provide some insight into the underlying cause.

Contributors

License

Copyright © 2017-2020 Volkan Yazıcı

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

log4j2-logstash-layout's People

Contributors

dependabot[bot] avatar emschwar avatar justinsaliba avatar labakomchev avatar mikaelstrand avatar rgomezcasas avatar vy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

log4j2-logstash-layout's Issues

Stacktraces larger than maxStringLength are not truncated

Stacktraces larger than resolverContext.writerCapacity causes an ArrayIndexOutOfBoundsException in the call to System::arraycopy from BufferedWriter::write because it attempts to write past the end of the buffer. The message is lost.
For stacktraces, maxStringLength has different semantics than for normal values: Instead of causing truncation, the buffer capacity is set from maxStringLength instead of maxByteCount if set.

The minimal solution would be that BufferedWriter detects if it is going to write past the buffer size and truncates.
The ideal solution would be to truncate as described based on maxStringLength if set and also use a growable buffer to avoid message loss. You could use the same mechanism as ByteArrayOutputStream (c.f. the private method grow) instead of char[].

LogstashLayout with log4j2-elasticsearch appender

I'm trying to use logstash layout with project https://github.com/rfoltyns/log4j2-elasticsearch

        <Elasticsearch name="elasticsearchAsyncBatch">
            <IndexName indexName="log4j2"/>
                <LogstashLayout dateTimeFormatPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZZZ"
                                eventTemplateUri="classpath:EcsLayout.json"
                                prettyPrintEnabled="true"
                                stackTraceEnabled="true">
                    <EventTemplateAdditionalFields>
                        <KeyValuePair key="correlationId" value="$${CorrelationId:}"/>
                        <KeyValuePair key="serviceName" value="$${ServiceName:}"/>
                        <KeyValuePair key="environment" value="marx"/>
                        <KeyValuePair key="@timestamp" value="${date:yyyy-MM-dd HH:mm:ss.SSS}"/>
                        <KeyValuePair key="host_name" value="${hostName}"/>
                    </EventTemplateAdditionalFields>
                </LogstashLayout>
            <AsyncBatchDelivery>
                <JestHttp serverUris="http://localhost:9200/_bulk"/>
            </AsyncBatchDelivery>
        </Elasticsearch>

However I'm getting error:

2020-01-13 15:25:20,025 main ERROR Could not create plugin of type class org.appenders.log4j2.elasticsearch.ElasticsearchAppender for element Elasticsearch: java.lang.IllegalArgumentException: Can not set org.apache.logging.log4j.core.layout.AbstractLayout field org.appenders.log4j2.elasticsearch.ElasticsearchAppender$Builder.layout to com.vlkan.log4j2.logstash.layout.LogstashLayout java.lang.IllegalArgumentException: Can not set org.apache.logging.log4j.core.layout.AbstractLayout field org.appenders.log4j2.elasticsearch.ElasticsearchAppender$Builder.layout to com.vlkan.log4j2.logstash.layout.LogstashLayout
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
	at java.base/java.lang.reflect.Field.set(Field.java:780)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.injectFields(PluginBuilder.java:188)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:121)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:964)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:904)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:896)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:514)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:238)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:250)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:548)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:620)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:637)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:231)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.commons.logging.LogAdapter$Log4jLog.<clinit>(LogAdapter.java:155)
	at org.apache.commons.logging.LogAdapter$Log4jAdapter.createLog(LogAdapter.java:122)
	at org.apache.commons.logging.LogAdapter.createLog(LogAdapter.java:89)
	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:67)
	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:59)
	at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:195)
	at com.ydc.discovery.Application.main(Application.java:26)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:543)
	at java.base/java.lang.Thread.run(Thread.java:831)

2020-01-13 15:25:20,036 main ERROR Unable to invoke factory method in class org.appenders.log4j2.elasticsearch.ElasticsearchAppender for element Elasticsearch: java.lang.IllegalStateException: No factory method found for class org.appenders.log4j2.elasticsearch.ElasticsearchAppender java.lang.IllegalStateException: No factory method found for class org.appenders.

Referenced issue: rfoltyns/log4j2-elasticsearch#32

BufferOverflowException get thrown for messages of a larger size

We have seen for many instances that the 1.0.0 version has a problem with messages of a larger size. It starts throwing BufferOverflowException exceptions when a certain threshold is reached. The exception that is logged to the console is as follows:

AsyncAppender-REDIS_GENERAL_LOG_ASYNC ERROR An exception occurred processing Appender REDIS_GENERAL_LOG java.lang.RuntimeException: failed serializing JSON
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.toByteArray(LogstashLayout.java:213)
	at com.vlkan.log4j2.redis.appender.RedisAppender.append(RedisAppender.java:138)
	at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
	at org.apache.logging.log4j.core.appender.AsyncAppender$AsyncThread.callAppenders(AsyncAppender.java:454)
	at org.apache.logging.log4j.core.appender.AsyncAppender$AsyncThread.run(AsyncAppender.java:407)
Caused by: java.nio.BufferOverflowException
	at java.base/java.nio.HeapByteBuffer.put(HeapByteBuffer.java:225)
	at com.vlkan.log4j2.logstash.layout.util.ByteBufferOutputStream.write(ByteBufferOutputStream.java:48)
	at com.vlkan.log4j2.logstash.layout.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2137)
	at com.vlkan.log4j2.logstash.layout.jackson.core.json.UTF8JsonGenerator._writeStringSegment2(UTF8JsonGenerator.java:1413)
	at com.vlkan.log4j2.logstash.layout.jackson.core.json.UTF8JsonGenerator._writeStringSegment(UTF8JsonGenerator.java:1366)
	at com.vlkan.log4j2.logstash.layout.jackson.core.json.UTF8JsonGenerator._writeStringSegments(UTF8JsonGenerator.java:1307)
	at com.vlkan.log4j2.logstash.layout.jackson.core.json.UTF8JsonGenerator.writeString(UTF8JsonGenerator.java:574)
	at com.vlkan.log4j2.logstash.layout.resolver.StackTraceTextResolver.resolve(StackTraceTextResolver.java:43)
	at com.vlkan.log4j2.logstash.layout.resolver.ExceptionRootCauseResolver$1.lambda$createStackTraceTextResolver$2(ExceptionRootCauseResolver.java:71)
	at com.vlkan.log4j2.logstash.layout.resolver.ExceptionRootCauseResolver.resolve(ExceptionRootCauseResolver.java:103)
	at com.vlkan.log4j2.logstash.layout.resolver.ExceptionRootCauseResolver.resolve(ExceptionRootCauseResolver.java:26)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.lambda$ofObjectNode$5(TemplateResolvers.java:146)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.lambda$ofObjectNode$5(TemplateResolvers.java:146)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.lambda$ofObjectNode$5(TemplateResolvers.java:146)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:262)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.toByteArray(LogstashLayout.java:209)

I am not sure what the exact size is when this starts the happen. But testing with by increasing the message size has shown me that these exceptions starts the occur when the message contains +-15.700 characters. I believe the issue occurs when the total size of the serialised json data is getting to be, and that it is not specific to the message. We see these BufferOverflowException exceptions as well when a MDC field contains a large amount of data.

When reverting back to 0.21 we don't see this issue anymore

LogStash Appender Question

I understand this project focuses only on the layout but I am wondering what appender to use instead of appending to a file and then uploading using logstash.

MDC properties

org.apache.log4j.MDC properties not logged on the json file.

Is there a way to enable MDC on the LogstashLayout properties?

Close because using org.apache.logging.log4j.ThreadContext solves the problem.

Nullpointer exceptions at LogstashLayoutSerializationContexts$StringTruncatingGeneratorDelegate

We see Nullpointer exceptions with the following stack trace:

 AsyncAppender-REDIS_GENERAL_LOG_ASYNC ERROR An exception occurred processing Appender REDIS_GENERAL_LOG java.lang.RuntimeException: failed serializing JSON
 	at com.vlkan.log4j2.logstash.layout.LogstashLayout.toByteArray(LogstashLayout.java:213)
 	at com.vlkan.log4j2.redis.appender.RedisAppender.append(RedisAppender.java:138)
 	at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
 	at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
 	at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
 	at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
 	at org.apache.logging.log4j.core.appender.AsyncAppender$AsyncThread.callAppenders(AsyncAppender.java:454)
 	at org.apache.logging.log4j.core.appender.AsyncAppender$AsyncThread.run(AsyncAppender.java:407)
 Caused by: java.lang.NullPointerException
 	at com.vlkan.log4j2.logstash.layout.LogstashLayoutSerializationContexts$StringTruncatingGeneratorDelegate.writeString(LogstashLayoutSerializationContexts.java:128)
 	at com.vlkan.log4j2.logstash.layout.resolver.ExceptionResolver$1.lambda$createMessageResolver$1(ExceptionResolver.java:51)
 	at com.vlkan.log4j2.logstash.layout.resolver.ExceptionResolver.resolve(ExceptionResolver.java:98)
 	at com.vlkan.log4j2.logstash.layout.resolver.ExceptionResolver.resolve(ExceptionResolver.java:25)
 	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.lambda$ofObjectNode$5(TemplateResolvers.java:146)
 	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.lambda$ofObjectNode$5(TemplateResolvers.java:146)
 	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.lambda$ofObjectNode$5(TemplateResolvers.java:146)
 	at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:262)
 	at com.vlkan.log4j2.logstash.layout.LogstashLayout.toByteArray(LogstashLayout.java:209)
 	... 7 more

If the StringTruncatingGeneratorDelegate#writeString method gets a null then it fails on the first if check, as it tries to call length on a null reference:

if (maxStringLength <= 0 || maxStringLength >= text.length()) {
    super.writeString(text);
} else {
    StringReader textReader = new StringReader(text);
    super.writeString(textReader, maxStringLength);
}

It can get the null value from the ExceptionResolver when emptyPropertyExclusionEnabled is not set to true, which is the default.

I am not sure if this should be fixed in this write method or it needs to be fixed at the call sites of this method.

Stackoverflow "BOMB" after any unhandled exception

Hi guys!
recently i ran into problem , i got StackOverflowError and a lot of JsonGenerationException.
java.lang.StackOverflowError at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213) at com.fasterxml.jackson.core.filter.TokenFilterContext._writePath(TokenFilterContext.java:213)

After some investigation i found that after any non JsonGenerationException state of JsonGenerator become corrupted and after while leads to StackOverflowError.
I wrote test to demonstrate case, just follow the link bakomchik@f933ba0
I 've already made pull request.
#27

Caused by: java.lang.RuntimeException: failed serializing JSON

Hi Volkan,

Since we use the JSONEventLayoutV0 of the Logstash implementation, I created my own template. Within the written log file, the JSON string is fragmented in many places and no longer valid. In our application logs I can see several exceptions. All exceptions refer to the used ByteBuffer.

log4j2.xml

<LogstashLayout dateTimeFormatPattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
  timeZoneId="UTC"
  eventTemplateUri="classpath:JSONEventLayoutV0.json"
  locationInfoEnabled="true"
  prettyPrintEnabled="false"
  stackTraceEnabled="true"/>

JSONEventLayoutV0.json

{
  "@version": null,
  "@message": "${json:message}",
  "@timestamp": "${json:timestamp}",
  "@source_host": "${hostName}",
  "@fields": {
    "exception": {
      "stacktrace": "${json:exception:stackTrace:text}",
      "exception_class": "${json:exception:className}",
      "exception_message": "${json:exception:message}"
    },
    "file": "${json:source:fileName}",
    "method": "${json:source:methodName}",
    "level": "${json:level}",
    "line_number": "${json:source:lineNumber}",
    "loggerName": "${json:logger:name}",
    "class": "${json:source:className}",
    "mdc": "${json:mdc}",
    "ndc": "${json:ndc}",
    "threadName": "${json:thread:name}"
  }
}

Stacktrace

org.apache.logging.log4j.core.appender.AppenderLoggingException: An exception occurred processing Appender RollingFileJson
        at org.apache.logging.log4j.core.appender.DefaultErrorHandler.error(DefaultErrorHandler.java:75) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.handleAppenderError(AppenderControl.java:165) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:158) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:464) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:448) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:431) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:406) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:63) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:146) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2170) ~[log4j-api-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2125) ~[log4j-api-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2108) ~[log4j-api-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2007) ~[log4j-api-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1866) ~[log4j-api-2.11.1.jar!/:2.11.1]
        at org.apache.logging.slf4j.Log4jLogger.debug(Log4jLogger.java:119) ~[log4j-slf4j-impl-2.11.1.jar!/:2.11.1]
        at com.mongodb.diagnostics.logging.SLF4JLogger.debug(SLF4JLogger.java:56) ~[mongo-java-driver-3.8.2.jar!/:?]
        at com.mongodb.internal.connection.LoggingCommandEventSender.sendStartedEvent(LoggingCommandEventSender.java:68) ~[mongo-java-driver-3.8.2.jar!/:?]
        at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:246) ~[mongo-java-driver-3.8.2.jar!/:?]
        at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83) ~[mongo-java-driver-3.8.2.jar!/:?]
        at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:38) ~[mongo-java-driver-3.8.2.jar!/:?]
        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:180) ~[mongo-java-driver-3.8.2.jar!/:?]
        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:124) ~[mongo-java-driver-3.8.2.jar!/:?]
        at java.lang.Thread.run(Thread.java:834) ~[?:?]
Caused by: java.lang.RuntimeException: failed serializing JSON
        at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:143) ~[log4j2-logstash-layout-0.16.jar!/:?]
        at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:34) ~[log4j2-logstash-layout-0.16.jar!/:?]
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:309) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156) ~[log4j-core-2.11.1.jar!/:2.11.1]
        ... 23 more
Caused by: java.lang.IllegalArgumentException: newPosition > limit: (547 > 8192)
        at java.nio.Buffer.createPositionException(Buffer.java:318) ~[?:?]
        at java.nio.Buffer.position(Buffer.java:293) ~[?:?]
        at java.nio.ByteBuffer.position(ByteBuffer.java:1086) ~[?:?]
        at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:237) ~[?:?]
        at org.apache.logging.log4j.core.layout.ByteBufferDestinationHelper.writeToUnsynchronized(ByteBufferDestinationHelper.java:47) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:141) ~[log4j2-logstash-layout-0.16.jar!/:?]
        at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:34) ~[log4j2-logstash-layout-0.16.jar!/:?]
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:309) ~[log4j-core-2.11.1.jar!/:2.11.1]
        at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156) ~[log4j-core-2.11.1.jar!/:2.11.1]
        ... 23 more
org.apache.logging.log4j.core.appender.AppenderLoggingException: An exception occurred processing Appender RollingFileJson
at org.apache.logging.log4j.core.appender.DefaultErrorHandler.error(DefaultErrorHandler.java:75) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.handleAppenderError(AppenderControl.java:165) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:158) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:464) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:448) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:431) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:406) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:63) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.Logger.logMessage(Logger.java:146) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.slf4j.Log4jLogger.log(Log4jLogger.java:376) ~[log4j-slf4j-impl-2.11.1.jar!/:2.11.1]
at org.slf4j.bridge.SLF4JBridgeHandler.callLocationAwareLogger(SLF4JBridgeHandler.java:221) ~[jul-to-slf4j-1.7.25.jar!/:1.7.25]
at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:303) ~[jul-to-slf4j-1.7.25.jar!/:1.7.25]
at java.util.logging.Logger.log(Logger.java:979) ~[?:?]
at java.util.logging.Logger.doLog(Logger.java:1006) ~[?:?]
at java.util.logging.Logger.logp(Logger.java:1283) ~[?:?]
at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:175) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.juli.logging.DirectJDKLog.error(DirectJDKLog.java:141) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:236) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:685) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[?:?]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.12.jar!/:9.0.12]
at java.lang.Thread.run(Thread.java:834) ~[?:?]
Caused by: java.lang.RuntimeException: failed serializing JSON
at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:143) ~[log4j2-logstash-layout-0.16.jar!/:?]
at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:34) ~[log4j2-logstash-layout-0.16.jar!/:?]
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:309) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156) ~[log4j-core-2.11.1.jar!/:2.11.1]
... 35 more
Caused by: java.lang.IllegalArgumentException: newPosition > limit: (16384 > 8192)
at java.nio.Buffer.createPositionException(Buffer.java:318) ~[?:?]
at java.nio.Buffer.position(Buffer.java:293) ~[?:?]
at java.nio.ByteBuffer.position(ByteBuffer.java:1086) ~[?:?]
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:237) ~[?:?]
at org.apache.logging.log4j.core.layout.ByteBufferDestinationHelper.writeToUnsynchronized(ByteBufferDestinationHelper.java:43) ~[log4j-core-2.11.1.jar!/:2.11.1]
at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:141) ~[log4j2-logstash-layout-0.16.jar!/:?]
at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:34) ~[log4j2-logstash-layout-0.16.jar!/:?]
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:309) ~[log4j-core-2.11.1.jar!/:2.11.1]
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156) ~[log4j-core-2.11.1.jar!/:2.11.1]
... 35 more

magic bug,one line json become mutiple message

verison of 0.19
logstash 7.2

i use the tcp to logstash

 <Socket name="logstash-tcp" host="${ctx:LOGSTASH_HOST}" port="${ctx:LOGSTASH_PORT}" protocol="TCP">
  <LogstashLayout dateTimeFormatPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZZZ"
                                    eventTemplateUri="classpath:LogstashJsonEventLayoutV1.json"
                                    prettyPrintEnabled="true"
                                    stackTraceEnabled="true"/>
</Socket>

sql

)

expected ,it shuoud be one line json

No new lines after some time

Hi,
Using this configuration
<Console name="Console" target="SYSTEM_OUT"> <LogstashLayout dateTimeFormatPattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" templateUri="classpath:LogstashJsonEventLayoutV1.json" prettyPrintEnabled="false" stackTraceEnabled="true" timeZoneId="TimeZone.GMT_ID" /> </Console>

everything works as expected for the first several hundreds of lines: that is, one log message is printed per line (start and end with { and }).

After that it happens that one new line is omitted: so, two messages appear at a single line. After several more lines, new lines are not printed anymore and everything is appended to the last line of the log:

...ger"}{"@version":1,...

Any idea if it is a bug, or if I can work around it somehow?

NoClassDefFoundError: logstash.layout.resolver.TemplateResolvers (initialization failure)

Hi, I'm getting the following error when I use Logstash Layout.
The project is not a maven project but so I put the jar files manually.

Any idea why this happens?

java.lang.NoClassDefFoundError: com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers (initialization failure)

Full log:

[10/1/20 14:39:01:791 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,791 WebContainer : 1 INFO Log4j appears to be running in a Servlet environment, but there's no log4j-web module available. If you want better web container support, please add the log4j-web JAR to your web archive or server lib directory.
[10/1/20 14:39:01:795 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,795 WebContainer : 1 DEBUG Closing BufferedInputStream java.io.BufferedInputStream@40edbe51
[10/1/20 14:39:01:802 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,802 WebContainer : 1 DEBUG Apache Log4j Core 2.13.3 initializing configuration XmlConfiguration[location=/Was/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/MYSERVER019Cell01/MyWebAppX.ear/MyWebAppX.war/WEB-INF/classes/log4j2.xml]
[10/1/20 14:39:01:803 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,803 WebContainer : 1 DEBUG Installed 1 script engine
[10/1/20 14:39:01:821 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,821 WebContainer : 1 DEBUG Oracle Nashorn version: 1.8.0, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory
[10/1/20 14:39:01:822 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,822 WebContainer : 1 DEBUG PluginManager 'Core' found 125 plugins
[10/1/20 14:39:01:823 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,823 WebContainer : 1 DEBUG PluginManager 'Level' found 0 plugins
[10/1/20 14:39:01:826 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,825 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:827 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,826 WebContainer : 1 DEBUG createProperty(name="filead", value="/Was/sgk/logs/MyWebAppX/MyWebAppX")
[10/1/20 14:39:01:827 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,827 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:828 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,828 WebContainer : 1 DEBUG createProperty(name="env", value="test")
[10/1/20 14:39:01:828 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,828 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:829 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,829 WebContainer : 1 DEBUG createProperty(name="app", value="muhtasar")
[10/1/20 14:39:01:830 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,830 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:831 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,830 WebContainer : 1 DEBUG createProperty(name="module", value="gib")
[10/1/20 14:39:01:831 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,831 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:832 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,832 WebContainer : 1 DEBUG createProperty(name="appPassword", value="123")
[10/1/20 14:39:01:833 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,832 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:833 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,833 WebContainer : 1 DEBUG createProperty(name="kafkaVisioAdres", value="kafka1.intra:9092,kafka2.intra:9092,kafka3.intra:9092")
[10/1/20 14:39:01:834 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,834 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:835 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,834 WebContainer : 1 DEBUG createProperty(name="visologVersion", value="2")
[10/1/20 14:39:01:835 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,835 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:836 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,836 WebContainer : 1 DEBUG createProperty(name="locationInfoEnabled", value="true")
[10/1/20 14:39:01:836 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,836 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:837 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,837 WebContainer : 1 DEBUG createProperty(name="stackTraceEnabled", value="true")
[10/1/20 14:39:01:838 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,838 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:838 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,838 WebContainer : 1 DEBUG createProperty(name="syncSend", value="true")
[10/1/20 14:39:01:839 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,839 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:840 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,839 WebContainer : 1 DEBUG createProperty(name="acks", value="all")
[10/1/20 14:39:01:840 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,840 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:841 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,841 WebContainer : 1 DEBUG createProperty(name="retention1", value="2688")
[10/1/20 14:39:01:841 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,841 WebContainer : 1 DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
[10/1/20 14:39:01:842 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,842 WebContainer : 1 DEBUG createProperty(name="timeZoneId", value="Asia/Istanbul")
[10/1/20 14:39:01:843 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,842 WebContainer : 1 DEBUG Building Plugin[name=properties, class=org.apache.logging.log4j.core.config.PropertiesPlugin].
[10/1/20 14:39:01:843 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,843 WebContainer : 1 DEBUG configureSubstitutor(={filead=/Was/sgk/logs/MyWebAppX/MyWebAppX, env=test, app=muhtasar, module=gib, appPassword=123, kafkaVisioAdres=kafka1.intra:9092,kafka2.intra:9092,kafka3.intra:9092, visologVersion=2, locationInfoEnabled=true, stackTraceEnabled=true, syncSend=true, acks=all, retention1=2688, timeZoneId=Asia/Istanbul}, Configuration(/Was/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/MYSERVER019Cell01/MyWebAppX.ear/MyWebAppX.war/WEB-INF/classes/log4j2.xml))
[10/1/20 14:39:01:844 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,844 WebContainer : 1 DEBUG PluginManager 'Lookup' found 16 plugins
[10/1/20 14:39:01:847 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,847 WebContainer : 1 DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
[10/1/20 14:39:01:847 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,847 WebContainer : 1 DEBUG KeyValuePair$Builder(key="retention1", value="2688")
[10/1/20 14:39:01:848 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,848 WebContainer : 1 DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
[10/1/20 14:39:01:849 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,849 WebContainer : 1 DEBUG KeyValuePair$Builder(key="app", value="muhtasar")
[10/1/20 14:39:01:849 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,849 WebContainer : 1 DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
[10/1/20 14:39:01:850 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,850 WebContainer : 1 DEBUG KeyValuePair$Builder(key="module", value="gib")
[10/1/20 14:39:01:850 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,850 WebContainer : 1 DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
[10/1/20 14:39:01:851 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,850 WebContainer : 1 DEBUG KeyValuePair$Builder(key="visologVersion", value="2")
[10/1/20 14:39:01:851 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,851 WebContainer : 1 DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
[10/1/20 14:39:01:852 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,852 WebContainer : 1 DEBUG KeyValuePair$Builder(key="env", value="test")
[10/1/20 14:39:01:852 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,852 WebContainer : 1 DEBUG Building Plugin[name=EventTemplateAdditionalFields, class=com.vlkan.log4j2.logstash.layout.LogstashLayout$EventTemplateAdditionalFields].
[10/1/20 14:39:01:852 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,852 WebContainer : 1 DEBUG LogstashLayout$EventTemplateAdditionalFields$Builder(={retention1=2688, app=muhtasar, module=gib, visologVersion=2, env=test})
[10/1/20 14:39:01:853 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,853 WebContainer : 1 DEBUG Building Plugin[name=layout, class=com.vlkan.log4j2.logstash.layout.LogstashLayout].
[10/1/20 14:39:01:854 TRT] 000000c5 SystemOut     O 2020-10-01 14:39:01,854 WebContainer : 1 DEBUG LogstashLayout$Builder(Configuration(/Was/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/MYSERVER019Cell01/MyWebAppX.ear/MyWebAppX.war/WEB-INF/classes/log4j2.xml), prettyPrintEnabled="false", locationInfoEnabled="true", stackTraceEnabled="true", emptyPropertyExclusionEnabled="true", dateTimeFormatPattern="yyyy-MM-dd'T'HH:mm:ssZZZ", timeZoneId="Asia/Istanbul", locale="null", eventTemplate="null", eventTemplateUri="classpath:visologEventLayout.json", EventTemplateAdditionalFields(com.vlkan.log4j2.logstash.layout.LogstashLayout$EventTemplateAdditionalFields@8607a1f9), stackTraceElementTemplate="null", stackTraceElementTemplateUri="null", mdcKeyPattern="null", ndcPattern="null", lineSeparator="null", maxByteCount="32768", maxStringLength="null", objectMapperFactoryMethod="null", mapMessageFormatterIgnored="null")
[10/1/20 14:39:01:865 TRT] 000000c5 AxisEngine    E org.apache.axis2.engine.AxisEngine receive null
                                 org.apache.axis2.AxisFault
	at org.apache.axis2.jaxws.server.dispatcher.JavaBeanDispatcher.createFaultResponse(JavaBeanDispatcher.java:407)
	at org.apache.axis2.jaxws.server.dispatcher.JavaBeanDispatcher.invoke(JavaBeanDispatcher.java:138)
	at org.apache.axis2.jaxws.server.EndpointController.invoke(EndpointController.java:111)
	at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:161)
	at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:212)
	at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
	at com.ibm.ws.websvcs.transport.http.WASAxis2Servlet.doPost(WASAxis2Servlet.java:1633)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1235)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:779)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:478)
	at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:179)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1124)
	at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:82)
	at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:963)
	at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1817)
	at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:382)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:465)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:532)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:318)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:289)
	at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
	at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
	at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
	at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
	at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
	at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
	at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
	at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
	at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1909)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
	at java.lang.reflect.Method.invoke(Method.java:508)
	at org.apache.axis2.jaxws.server.dispatcher.JavaDispatcher.invokeTargetOperation(JavaDispatcher.java:120)
	at org.apache.axis2.jaxws.server.dispatcher.JavaBeanDispatcher.invoke(JavaBeanDispatcher.java:118)
	... 30 more
Caused by: java.lang.NoClassDefFoundError: com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers (initialization failure)
	at java.lang.J9VMInternals.initializationAlreadyFailed(J9VMInternals.java:96)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.createStackTraceElementResolver(LogstashLayout.java:121)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.<init>(LogstashLayout.java:83)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.<init>(LogstashLayout.java:61)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout$Builder.build(LogstashLayout.java:547)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout$Builder.build(LogstashLayout.java:297)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1002)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:942)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:552)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:241)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:288)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:618)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:691)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:708)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:263)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:602)
	at tr.gov.sgk.bildirge.webservice.business.PaketIslem.paketIptalSGK(PaketIslem.java:251)
	at tr.gov.sgk.bildirge.webservice.BildirgeWS.paketIptal(BildirgeWS.java:316)
	... 36 more
Caused by: java.lang.BootstrapMethodError: java.lang.LinkageError: loading constraint violation when overriding method "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolver.resolve(Ljava/lang/Object;Lcom/fasterxml/jackson/core/JsonGenerator;)V" during creation of class "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolvers$$Lambda$262/0000000008AB1080": loader "java/lang/InternalAnonymousClassLoader@e3c90ee7" of class "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolvers$$Lambda$262/0000000008AB1080" and loader "com/ibm/ws/classloader/CompoundClassLoader@90ee7c7b" of class "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolver" have different types for the method signature
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.<clinit>(TemplateResolvers.java:34)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.createStackTraceElementResolver(LogstashLayout.java:121)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.<init>(LogstashLayout.java:83)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.<init>(LogstashLayout.java:61)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout$Builder.build(LogstashLayout.java:547)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout$Builder.build(LogstashLayout.java:297)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1002)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:942)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:552)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:241)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:288)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:618)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:691)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:708)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:263)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:243)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:174)
	at org.apache.logging.log4j.core.LoggerContext.getContext(LoggerContext.java:224)
	at tr.gov.sgk.util.sistem.SistemSabitDegerler.log4j2Islemleri(SistemSabitDegerler.java:94)
	at tr.gov.sgk.util.sistem.SistemSabitDegerler.<init>(SistemSabitDegerler.java:69)
	at tr.gov.sgk.bildirge.webservice.util.StartServlet.init(StartServlet.java:44)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:342)
	at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.init(ServletWrapperImpl.java:169)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1376)
	at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:673)
	at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:639)
	at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:454)
	at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
	at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:171)
	at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:904)
	at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:789)
	at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:427)
	at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:719)
	at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1249)
	at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1590)
	at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:707)
	at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:1161)
	at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:801)
	at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplicationDynamically(ApplicationMgrImpl.java:1451)
	at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2319)
	at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:436)
	at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
	at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:379)
	at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:127)
	at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$1.run(CompositionUnitMgrImpl.java:654)
	at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5536)
	at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5662)
	at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
	at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:668)
	at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:612)
	at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:1341)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
	at java.lang.reflect.Method.invoke(Method.java:508)
	at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:83)
	at sun.reflect.GeneratedMethodAccessor114.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
	at java.lang.reflect.Method.invoke(Method.java:508)
	at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:287)
	at javax.management.modelmbean.RequiredModelMBean$4.run(RequiredModelMBean.java:1263)
	at java.security.AccessController.doPrivileged(AccessController.java:664)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:91)
	at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1257)
	at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:1096)
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:831)
	at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:813)
	at com.ibm.ws.management.AdminServiceImpl$1.run(AdminServiceImpl.java:1350)
	at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
	at com.ibm.ws.management.AdminServiceImpl.invoke(AdminServiceImpl.java:1243)
	at com.ibm.ws.management.connector.AdminServiceDelegator.invoke(AdminServiceDelegator.java:181)
	at com.ibm.ws.management.connector.ipc.CallRouter.route(CallRouter.java:247)
	at com.ibm.ws.management.connector.ipc.IPCConnectorInboundLink.doWork(IPCConnectorInboundLink.java:360)
	at com.ibm.ws.management.connector.ipc.IPCConnectorInboundLink$IPCConnectorReadCallback.complete(IPCConnectorInboundLink.java:602)
	at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1833)
	... 8 more
Caused by: java.lang.LinkageError: loading constraint violation when overriding method "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolver.resolve(Ljava/lang/Object;Lcom/fasterxml/jackson/core/JsonGenerator;)V" during creation of class "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolvers$$Lambda$262/0000000008AB1080": loader "java/lang/InternalAnonymousClassLoader@e3c90ee7" of class "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolvers$$Lambda$262/0000000008AB1080" and loader "com/ibm/ws/classloader/CompoundClassLoader@90ee7c7b" of class "com/vlkan/log4j2/logstash/layout/resolver/TemplateResolver" have different types for the method signature
	at sun.misc.Unsafe.defineAnonymousClass(Native Method)
	at java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass(InnerClassLambdaMetafactory.java:339)
	at java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:206)
	at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:315)
	at java.lang.invoke.DirectHandle.invokeExact_thunkArchetype_L(DirectHandle.java:302)
	at java.lang.invoke.AsTypeHandle.invokeExact_thunkArchetype_X(AsTypeHandle.java:49)
	at java.lang.invoke.MethodHandle.resolveInvokeDynamic(MethodHandle.java:833)
	... 87 more

[10/1/20 14:39:01:892 TRT] 000000c5 FfdcProvider  W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on /Was/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/ffdc/uyg108_3_a5b084b7_20.10.01_14.39.01.8863351636182199464237.txt com.ibm.ws.websvcs.transport.http.WASAxis2Servlet.doPost 516

Remove max byte count cap?

I'm not sure if this is an issue or not, so just seeking clarification.

Is there a way to not cap the log size length? For our use case, we'd rather keep all the log messages instead of setting an arbitrary limit. Would it be an issue if we set the maxByte to something really high like 100k (our concern was whether these buffers were allocated for every log message)?

Failed serializing JSON: BufferOverflowException

Getting the exception below with GCP (using template from #54), version 1.0.2:

Log4j2-TF-1-AsyncLoggerConfig-1 ERROR An exception occurred processing Appender mainFile java.lang.RuntimeException: failed serializing JSON
 at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:230)
 at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:57)
 at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
[...]
 Caused by: java.nio.BufferOverflowException
 at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:194)
 at com.vlkan.log4j2.logstash.layout.util.ByteBufferOutputStream.write(ByteBufferOutputStream.java:48)
 at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2137)
 at com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1150)
 at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:263)
 at com.vlkan.log4j2.logstash.layout.LogstashLayout.encode(LogstashLayout.java:221)
 ... 19 more

Take types into account while serializing MDC values

Hi man !

The lib is helping me a lot. However, it would be awesome if the layout could infer numeric values from MDC. This is something that would help on metrics and aggregations on ES.
Currently, we can only publish String MDC values.

If you're too busy, I could open a PR for that. However I dont know where to start

Multiple template variables in single property lead to an exception

I wanted to use multiple template variables in a single property:

{
  // snip
  "caller": "${json:source:className}.${json:source:methodName}",
  "file": "${json:source:fileName}#${json:source:lineNumber}"
}

The problem is that I'm presented with an exception upon startup:

2020-07-29 18:55:18,959 main ERROR Could not create plugin of type class com.vlkan.log4j2.logstash.layout.LogstashLayout for element LogstashLayout: java.lang.IllegalArgumentException: unknown key: className}.${json:source:methodName java.lang.IllegalArgumentException: unknown key: className}.${json:source:methodName
	at com.vlkan.log4j2.logstash.layout.resolver.SourceResolver.createInternalResolver(SourceResolver.java:45)
	at com.vlkan.log4j2.logstash.layout.resolver.SourceResolver.<init>(SourceResolver.java:32)
	at com.vlkan.log4j2.logstash.layout.resolver.SourceResolverFactory.create(SourceResolverFactory.java:36)
	at com.vlkan.log4j2.logstash.layout.resolver.SourceResolverFactory.create(SourceResolverFactory.java:19)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.ofStringNode(TemplateResolvers.java:168)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.ofNode(TemplateResolvers.java:80)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.ofObjectNode(TemplateResolvers.java:127)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.ofNode(TemplateResolvers.java:79)
	at com.vlkan.log4j2.logstash.layout.resolver.TemplateResolvers.ofTemplate(TemplateResolvers.java:69)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.createEventResolver(LogstashLayout.java:153)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.<init>(LogstashLayout.java:85)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout.<init>(LogstashLayout.java:61)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout$Builder.build(LogstashLayout.java:547)
	at com.vlkan.log4j2.logstash.layout.LogstashLayout$Builder.build(LogstashLayout.java:297)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1002)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:942)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:552)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:241)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:288)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:618)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:691)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:708)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:263)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:138)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:45)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:48)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:30)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:363)
	at com.fleshgrinder.logging.LoggingKt.main(Logging.kt:6)
	at com.fleshgrinder.logging.LoggingKt.main(Logging.kt)

2020-07-29 18:55:18,960 main ERROR Unable to invoke factory method in class com.vlkan.log4j2.logstash.layout.LogstashLayout for element LogstashLayout: java.lang.IllegalStateException: No factory method found for class com.vlkan.log4j2.logstash.layout.LogstashLayout java.lang.IllegalStateException: No factory method found for class com.vlkan.log4j2.logstash.layout.LogstashLayout
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.findFactoryMethod(PluginBuilder.java:234)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:134)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1002)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:942)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:552)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:241)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:288)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:618)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:691)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:708)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:263)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:138)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:45)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:48)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:30)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:363)
	at com.fleshgrinder.logging.LoggingKt.main(Logging.kt:6)
	at com.fleshgrinder.logging.LoggingKt.main(Logging.kt)

test message

The moment I reduce the line to a single template variables things work as usual, however, I would expect this to work. 😊

PS: Thanks for the great library and your efforts to get it into core. ❤️

Messages as json for Logger.log(Level, Object) support

I am using Logger.log(Level, Object) and configured message as json:message:json in LogstashLayout. It only supports MultiformatMessage as json currently. Could you please provide support for any object as Json message as supported in JsonLayout of apache's log4j2 if we mention it as objectMessageAsJsonObject.

Also could you add support for the direct message should populated under messages instead of
message : { message: { JsonObject }}

Should be like: message: {JsonObject}

Replace ByteBufferOutputStream with a dynamically growing one

When byteCount is big and not used at all (which is the case most of the time), ByteBufferOutputStream causes frequent cache misses. Use an alternative implementation with a dynamically growing byte[] alternative. (Maybe even chaining byte[]s via List<byte[]>?)

How to output ThreadContext (ex -MDC fields)

Hello
Thanks for you work, I'am using your plugin since one year or so, but without using ex-MDC fields because I could not understand quickly how to....
After reading the doc, it is not clear for me how to output some prefefined ThreadContext (ex MDC) fields. In my case these fields are simple strings or integers...
Is it fully in the log4j2 xml file or do I have to create a custom json template file?
If so how I instruct the appender to use this custom file?
Do you have an example please

Improve LogstashJsonEventLayoutV1

Some ideas I wish log4j2-logstash-layout had:

  • Rename source_host as host to be on par with Logstash Input File
  • Be able to use environment variables, Java system properties in a layout template:
  • Filter MDC content: include only a subset of MDC fields
  • Make field names shorter "exception.class" instead of "exception.exception_class", "thread" instead of "thread_name"

This could be done with a different "enhanced" layout template

Replace Jackson with custom JSON emitter

While Jackson is the de facto JSON serialization library in the Java world and log4j2-logstash-layout enjoys its great performance, flexibility, and customization features, it is currently the slowest chain in the entire serialization pipeline. Given log4j2-logstash-layout only serializes LogEvents into JSON, a custom JSON emitter can very well be implemented in a pretty straightforward way.

Pros

  • No external (required) dependency
  • Faster serialization

Cons

  • A byte[] recycler will need to be implemented to avoid GC
  • Jackson is still needed as an optional dependency while serializing Messages that are not SimpleMessage
  • null entry elimination might need to be dropped (difficult to get right)

@mkedwards Would you (or your company) be interested in sponsoring such an effort?

Fallback for json:map: fields for libraries

Currently we're looking into adopting MapMessages for most of our logging needs, mapping the message fieldin the layout as, say json:map:message. This works fine for our code, but when dealing with library code that logs SimpleMessages we end up with empty message fields. Is there a workaround for this, some way to fallback a field from json:map: mapping to message if the mapping is empty?

Improving the rendering performance

We think we're going to be able to open-source our message class fairly soon, at which point it might be interesting to explore alternate layout/message interfaces that reduce serialization overhead. Maybe something along the lines of a visitor pattern, where the Layout passes a visitor to the Message and the Message does the tree-walk? Some people refer to that as a SAX-style API, and Jackson's "Streaming API" (JsonGenerator, https://fasterxml.github.io/jackson-core/javadoc/2.9/com/fasterxml/jackson/core/JsonGenerator.html) works that way.

Have you worked at all with log4j2 upstream? It seems like this system would benefit from some hard-core perfomance work, which generally involves some API refactoring. If we could get a team together, it would be satisfying to build a "fish tagging" system for Java distributed architectures, comparable to what I've helped build previously in a Javascript/Python/C++ world. (That system resembled log4j2's ContextDataInjector scheme, with the local context transferred as metadata on RESTful API requests and auto-captured by task closures for delegation across thread boundaries.) Netty-based services really need such a thing.

Originally posted by @mkedwards in #15 (comment)

Review request for Log4j JsonTemplateLayout

Dear past issue and pull request authors!

I am sorry to spam you in this way, though I need your help on something. I have been working extensively in the last one year to merge LogstashLayout into the Apache Log4j core. 💪 The new layout is rebranded as JsonTemplateLayout (which also communicates the intent more clearly) and gone through a massive set of changes. 🚀 I have uploaded the most recent version of the manual here. Your experience with the LogstashLayout makes you the perfect candidate for reviewing this new layout. I will really appreciate if you can spare some time to go through the manual and share your feedback. 🥺 🙏 You can either write your comments here, e-mail me directly, or use the Log4j mailing lists.

Thanks so much for your support. Both LogstashLayout and JsonTemplateLayout wouldn't be possible without you all.

/cc @a1046149428 @Achaaab @bakomchik @billcchung @emschwar @ercpe @gjevardat @gopalkakularam @ilgrosso @J0nathan-S @justinsaliba @Marx2 @MikaelStrand @mkedwards @mzeijen @ov7a @pmackles @rgomezcasas @sabareeshkkanan @vtrbtf @waldeinburg @wangzhuo0978 @yskopets

Custom user fields support

In the original logstash layout there is a possibility to use custom user fields:
https://github.com/logstash/log4j-jsonevent-layout#custom-user-fields
This feature is quite handy to provide, for example, a service name through log4j config.

I suppose one can do it with this lib, but It would require to use custom layout for each service which adds extra field with different value for each service. (Or maybe I didn't understand the docs). This way is not very convenient.

Ability to truncate individual fields

I think this is more of a feature request than a bug, but I am looking for a way to configure log4j2-logstash-layout so that it truncates certain fields if they are too long. It would be more granular than maxByteCount while also still allowing the message to go through. Something similar to the format modifiers in PatternLayout that allow you to truncate specific fields like message if it exceeds 10K characters. You can accomplish this through other means using logback but I can't find a way to do it in log4j2 short of a custom plugin.

If others agree with this, I can attempt a PR

extract certain MDC fields

instead of having { "mdc" : { "customThreadContextField" : "someValue1", "secondCustomThreadContextField" : "someValue2", }, "@version" : 1, "source_host" : "raspberrypi", "message" : "some msg", }

I would like to have the mdc flat to the rest of the fields { "customThreadContextField" : "someValue1", "secondCustomThreadContextField" : "someValue2", "@version" : 1, "source_host" : "raspberrypi", "message" : "some msg", }

Is that somehow possible? I tried adding "customThreadContextField": "${mdc:customThreadContextField}", to a custom layout template, but the syntax is obviously wrong.

Pretty printing in Logstash

I got parse issues with your extension, but stock log4j2 works with this config:

<JsonLayout compact="true" eventEol="true"/>

It inserts new line, I think you insert just a bunch of JSON nodes in the log file and he thinks it is an array, but there is no "," character.

My logstash config looks like this:
input {
file {
codec => json
type => "log4j-json"
path => "/logs/log4j2.log"
}
}

add Marker support

The LogEvent template variables which can be used inside custom templates do not support Marker (LogEvent.getMarker()). Would be nice if this would be added.

Layout should be done as in the Log4j2-JSONLayout:

  "marker" : {
    "name" : "child",
    "parents" : [ {
      "name" : "parent",
      "parents" : [ {
        "name" : "grandparent"
      } ]
    } ]
  },

Backporting to an earlier version of Log4j2

Hi,

Thanks for taking the time to create this project. I'm currently looking at this library to add more verbose logging throughout my applications and this seems to be exactly what I'm looking for.

I've successfully demo'd this to my peers and it was very well received. The only snag which we encountered whilst testing this with our framework is that we are stuck on v0.14 of this library. This is because the library started using ByteBufferDestinationHelper in v0.15 and in later versions. This class was only introduced to Log4j2 in v2.9.

Would you be willing to consider downgrading this library to support Log4j2 2.8.2? I'm willing to do the work myself and submit a PR in the near future to support this, but before doing so I would like to understand whether you would be willing to provide sporadic feedback, or whether you would even consider this at all.

Thanks in advance,

Justin

Pretty print when log level is error

Well getting used to json log but it is really hard to read logs when there is error. Even though we are shipping it elastic search but it will be nice to have pretty print when the log level is error.

License

Hi there,

This project looks very useful but since it's licensed as GPL we can't use it. Would you be willing to relicense it as LGPL or some other license that does not require open sourcing?

How exactly is MapMessage supposed to be handled?

Hi

I saw your bug report (and fix) for Log4J2's MapMessage handling. However, I've tried with a few different logging approaches and none seem to give me the output I was hoping for (where the MapMessage is output as a JSON Object).

Is there a little bit better instruction somewhere of how a MapMessage can be handled, or is it a limitation that the MapMessage class can't be serialized to an object?

Ultimately what I'm trying to do is log all headers into separate fields in my JSON log for an incoming request (to make each field searchable as well as run aggregates on different header values).

Support GELF layout

GELF layout can easily be supported by LogtashLayout. There are only two shortcomings:

  1. Rendering of epoch seconds with fraction. Such a feature can be introduced by means of a new timestamp:divisor=<divisor> template, which will emit epochNanos / <divisor> as a floating point number.
  2. Rendering of ordinal number of Levels. This requires a new level:severityCode code directive.

Once this is done, incorporating the LogstashLayout-powered GELF layout vs. Log4j 2 GelfLayout into benchmarks would be handy.

Use ByteArrayOutputStream instead of ByteBufferOutputStream to avoid message loss

I haven't researched this in depth but I suggest that the OutputStream in LogstashLayoutSerializationContexts is instantiated as a ByteArrayOutputStream (with an initial size of maxByteCount) instead of ByteBufferOutputStream to avoid message loss on large messages.

Setting maxStringLength is not a completely satisfying solution because we would have to make predictions of how many non-ASCII characters we expect as byte length is potentially larger than string length.

sleuth logging pattern: pid and defaultvalues

Thank you very much for this outstanding plugin. As spring-sleuth is becomming more popular two minor issues with your logging-plugin are present.

first: provide pid
second: if one value is absent, then the plugin generates 'null' inside json whereas sleuth generates an empty string.

I hope you consider implementing these two minor enhancements

attacement: sleuth-pattern

https://github.com/spring-cloud-samples/sleuth-documentation-apps/blob/master/service1/src/main/resources/logback-spring.xml

Add entire map content as a field in the LogstashLayout

We're logging our messages via MapMessage through a LogstashLayout to ELK.

I'm trying to add the entire map content of the MapMessage to the layout but can't figure out how. I know that i can look up individual keys via

"event": "${map:event}",

but I haven't found a way to add the entire map.
I want to do something like:

{
    "vars": "${map}"
}

and get sth. like

{
"vars": {
  "key1": "value1",
  "key2": "value2"
}

The message keys are more or less dynamic so i can't add them all as individual lookups.

From what I can see it's not possible to register a custom Resolver, isn't it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.