Giter VIP home page Giter VIP logo

logback-gelf's Introduction

Logback GELF

build Codacy Badge codecov javadoc Maven Central

Logback appender for sending GELF (Graylog Extended Log Format) messages with zero additional dependencies.

Features

  • UDP (with chunking)
  • TCP (with or without TLS encryption)
  • HTTP(s)
  • GZIP and ZLIB compression (in UDP and HTTP mode)
  • Client side load balancing (round-robin)
  • Forwarding of MDC (Mapped Diagnostic Context)
  • Forwarding of caller data
  • Forwarding of static fields
  • Forwarding of exception root cause
  • No runtime dependencies beside Logback

Requirements

  • Java 11
  • Logback 1.5.3

Examples

Simple UDP configuration:

<configuration>

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfUdpAppender">
        <graylogHost>localhost</graylogHost>
        <graylogPort>12201</graylogPort>
    </appender>

    <root level="debug">
        <appender-ref ref="GELF" />
    </root>

</configuration>

Simple TCP configuration:

<configuration>

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfTcpAppender">
        <graylogHost>localhost</graylogHost>
        <graylogPort>12201</graylogPort>
    </appender>

    <!-- Use AsyncAppender to prevent slowdowns -->
    <appender name="ASYNC GELF" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="GELF" />
        <neverBlock>true</neverBlock>
    </appender>

    <root level="debug">
        <appender-ref ref="ASYNC GELF" />
    </root>

</configuration>

Simple TCP with TLS configuration:

<configuration>

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfTcpTlsAppender">
        <graylogHost>localhost</graylogHost>
        <graylogPort>12201</graylogPort>
    </appender>

    <!-- Use AsyncAppender to prevent slowdowns -->
    <appender name="ASYNC GELF" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="GELF" />
        <neverBlock>true</neverBlock>
    </appender>

    <root level="debug">
        <appender-ref ref="ASYNC GELF" />
    </root>

</configuration>

Simple HTTP configuration:

<configuration>

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfHttpAppender">
        <uri>https://my.server:12201/gelf</uri>
    </appender>

    <!-- Use AsyncAppender to prevent slowdowns -->
    <appender name="ASYNC GELF" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="GELF" />
        <neverBlock>true</neverBlock>
    </appender>

    <root level="debug">
        <appender-ref ref="ASYNC GELF" />
    </root>

</configuration>

Find more advanced examples in the examples directory.

Configuration

Appender

de.siegmar.logbackgelf.GelfUdpAppender

  • graylogHost: IP or hostname of graylog server. If the hostname resolves to multiple ip addresses, round-robin will be used.
  • graylogPort: Port of graylog server. Default: 12201.
  • maxChunkSize: Maximum size of GELF chunks in bytes. Default chunk size is 508 - this prevents IP packet fragmentation. This is also the recommended minimum. Maximum supported chunk size is 65,467 bytes.
  • compressionMethod: Compression method to use (NONE, GZIP or ZLIB). Default: GZIP.
  • messageIdSupplier: The mechanism that supplies unique message ids that are required by the GELF UDP protocol. Default: de.siegmar.logbackgelf.MessageIdSupplier.
  • encoder: See Encoder configuration below.

de.siegmar.logbackgelf.GelfTcpAppender

  • graylogHost: IP or hostname of graylog server. If the hostname resolves to multiple ip addresses, round-robin will be used.
  • graylogPort: Port of graylog server. Default: 12201.
  • connectTimeout: Maximum time (in milliseconds) to wait for establishing a connection. A value of 0 disables the connect timeout. Default: 15,000 milliseconds.
  • socketTimeout: Maximum time (in milliseconds) to block when reading a socket. A value of 0 disables the socket timeout. Default: 5,000 milliseconds.
  • reconnectInterval: Time interval (in seconds) after an existing connection is closed and re-opened. A value of -1 disables automatic reconnects. Default: 60 seconds.
  • maxRetries: Number of retries. A value of 0 disables retry attempts. Default: 2.
  • retryDelay: Time (in milliseconds) between retry attempts. Ignored if maxRetries is 0. Default: 3,000 milliseconds.
  • poolSize: Number of concurrent tcp connections (minimum 1). Default: 2.
  • poolMaxWaitTime: Maximum amount of time (in milliseconds) to wait for a connection to become available from the pool. A value of -1 disables the timeout. Default: 5,000 milliseconds.
  • poolMaxIdleTime: Maximum amount of time (in seconds) that a pooled connection can be idle before it is considered 'stale' and will not be reused. A value of -1 disables the max idle time feature. Default: -1 (disabled).
  • encoder: See Encoder configuration below.

de.siegmar.logbackgelf.GelfTcpTlsAppender

  • Everything from GelfTcpAppender
  • insecure: If true, skip the TLS certificate validation. You should not use this in production! Default: false.

de.siegmar.logbackgelf.GelfHttpAppender

  • uri: HTTP(s) URI of graylog server (e.g. https://my.server:12201/gelf).
  • insecure: If true, skip the TLS certificate validation. You should not use this in production! Default: false.
  • connectTimeout: Maximum time (in milliseconds) to wait for establishing a connection. A value of 0 disables the connect timeout. Default: 15,000 milliseconds.
  • requestTimeout: Maximum time (in milliseconds) to wait for a response. A value of 0 disables the timeout. Default: 5,000 milliseconds.
  • maxRetries: Number of retries. A value of 0 disables retry attempts. Default: 2.
  • retryDelay: Time (in milliseconds) between retry attempts. Ignored if maxRetries is 0. Default: 3,000 milliseconds.
  • compressionMethod: Compression method to use (NONE, GZIP or ZLIB). Default: GZIP.
  • encoder: See Encoder configuration below.

Encoder

de.siegmar.logbackgelf.GelfEncoder

  • originHost: Origin hostname - will be auto-detected if not specified.
  • includeRawMessage: If true, the raw message (with argument placeholders) will be sent, too. Default: false.
  • includeKeyValues: If true, key value pairs will be sent, too. Default: true.
  • includeMarker: If true, logback markers will be sent, too. Default: false.
  • includeMdcData: If true, MDC keys/values will be sent, too. Default: true.
  • includeCallerData: If true, caller data (source file-, method-, class name and line) will be sent, too. Default: false.
  • includeRootCauseData: If true, root cause exception of the exception passed with the log message will be exposed in the root_cause_class_name and root_cause_message fields. Default: false.
  • includeLevelName: If true, the log level name (e.g. DEBUG) will be sent, too. Default: false.
  • levelNameKey: The key (i.e. the field name) that should be used for the log level name. This is only relevant when includeLevelName is true. Default: level_name.
  • loggerNameKey: The key (i.e. the field name) that should be used for the logger name. Default: logger_name.
  • threadNameKey: The key (i.e. the field name) that should be used for the thread name. Default: thread_name.
  • appendNewline: If true, a system-dependent newline separator will be added at the end of each message. Don't use this in conjunction with TCP/UDP/HTTP appender, as this is only reasonable for console logging!
  • shortMessageLayout: Short message format. Default: "%m%nopex".
  • fullMessageLayout: Full message format (Stacktrace). Default: "%m%n".
  • numbersAsString: Log numbers as String. Default: false.
  • staticFields: Additional, static fields to send to graylog. Defaults: none.

Troubleshooting

If you have any problems, enable the debug mode and check the logs.

<configuration debug="true">
    ...
</configuration>

logback-gelf's People

Contributors

andrebrait avatar dneunkirch avatar fabiojb avatar fupgang avatar gerrri avatar joelittlejohn avatar kimbsy avatar marbon87 avatar osiegmar avatar shurkantwo avatar stratehm avatar ushkinaz 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

logback-gelf's Issues

Avoid logging InterruptedException when exiting

When shutting down GelfTcpAppender, I would like to avoid an error being logged.
Sample log:

16:12:39,427 |-INFO in ch.qos.logback.core.hook.DelayingShutdownHook@91259c3 - Logback context being closed via shutdown hook
16:12:39,563 |-INFO in ch.qos.logback.classic.AsyncAppender[GELF TCP ASYNC] - Worker thread will flush remaining events before exiting. 
16:12:39,565 |-ERROR in de.siegmar.logbackgelf.GelfTcpAppender[GELF TCP] - Error sending message via tcp://graylog:12201 java.lang.InterruptedException
	at java.lang.InterruptedException
	at 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220)
	at 	at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
	at 	at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:462)
	at 	at de.siegmar.logbackgelf.pool.SimpleObjectPool.borrowObject(SimpleObjectPool.java:83)
	at 	at de.siegmar.logbackgelf.pool.SimpleObjectPool.execute(SimpleObjectPool.java:62)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.sendMessage(GelfTcpAppender.java:173)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.appendMessage(GelfTcpAppender.java:147)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:104)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:27)
	at 	at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
	at 	at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
	at 	at ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:299)
16:12:42,612 |-INFO in ch.qos.logback.classic.AsyncAppender[GELF TCP ASYNC] - Queue flush finished successfully within timeout.

java.nio.channels.ClosedByInterruptException

My project is used 1.1.0 version, however, I found my log can not be sent to graylog server, the exception is java.nio.channels.ClosedByInterruptException.

I do not know why this is so I put the relevant screenshots up.

This is an exception,de.siegmar.logbackgelf.AbstractGelfAppender#append

image

This is current channel
image

My kafka dependency

   <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka_2.10</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

milliseconds accuracy

I'm get messages on screen rounded to seconds:

image

So, it drive me to misread log messages.

I'm sending them using this maven package (logback-gelf):

<dependency>
    <groupId>de.siegmar</groupId>
    <artifactId>logback-gelf</artifactId>
    <version>2.2.0</version>
</dependency>

logback configuration is:

<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

    <!-- LOG "com.baeldung*" at TRACE level -->
    <logger name="net.gencat.transversal.espaidoc.common.dao.RedisDao" level="WARN" additivity="false" />

    <springProperty scope="context" name="ACTIVE_PROFILE" source="spring.profiles.active"/>

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfTcpAppender">
        <graylogHost>localhost</graylogHost>
        <graylogPort>12201</graylogPort>
        <connectTimeout>15000</connectTimeout>
        <reconnectInterval>300</reconnectInterval>
        <maxRetries>2</maxRetries>
        <retryDelay>3000</retryDelay>
        <poolSize>2</poolSize>
        <poolMaxWaitTime>5000</poolMaxWaitTime>
        <encoder class="de.siegmar.logbackgelf.GelfEncoder">
            <originHost>localhost</originHost>
            <includeRawMessage>true</includeRawMessage>
            <includeMarker>true</includeMarker>
            <includeMdcData>true</includeMdcData>
            <includeCallerData>true</includeCallerData>
            <includeRootCauseData>false</includeRootCauseData>
            <includeLevelName>true</includeLevelName>
            <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%m%nopex</pattern>
            </shortPatternLayout>
            <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%m%n</pattern>
            </fullPatternLayout>
            <numbersAsString>false</numbersAsString>
            <staticField>service_name:api-${ACTIVE_PROFILE}</staticField>
        </encoder>
    </appender>

    <!-- Use AsyncAppender to prevent slowdowns -->
    <appender name="ASYNC GELF" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="GELF" />
    </appender>

    <logger name="net.gencat.transversal.espaidoc" level="debug" additivity="false">
        <appender-ref ref="ASYNC GELF" />
        <appender-ref ref="CONSOLE" />
    </logger>

    <logger name="net.gencat.transversal.espaidoc.api.service.RepositoryService" level="debug" additivity="false">
        <appender-ref ref="CONSOLE" />
    </logger>

    <logger name="net.gencat.transversal.espaidoc.api.dao.RepositoryDocumentDao)" level="debug" additivity="false">
        <appender-ref ref="CONSOLE" />
    </logger>
</configuration>

Any ideas?

Usage as code

Is there any example to setup this as code (i.e. tweak the loggers / appenders ...) in Java / Kotlin ? I intend to use it for several projects, it's more practical and maintainable than doing some XML tweaks.

Thanks !

GraylogHost can support multiple addresses?

Graylog master-slave mode, when a service a large number of anomalies for a short time, then crazy hit a node, here want to do load balancing, then you can configure multiple addresses on the client?

StaticField add fail

add a staticField in logback.xml "order_id:{orderId}".

My interface

/**
* vin logger
*
* @param orderId
* @param content
* @Date 2019/9/12_14:06
*/
@PutMapping("/vin")
public void vin(@RequestParam("orderId") String orderId,
@RequestParam("content") String content) {
MDC.put("orderId", orderId);
log.info(content);
}

when orderId was number,It was ok,garylog console sout this message
but orderId like "2e22a1e1a68a4dde94c73ea56e04d914",no error,garylog was't this message.
I need your help!

Enable adding multiple static fields via environment variable and/or logback.properties

Is your feature request related to a problem? Please describe.
It would be nice to be able to declare multiple static fields in a comma-delimited list. I'm creating a base Docker image with a default Logback configuration for my coworkers to use for their projects. Currently, I've been able to be flexible enough using variables so that everything can be configured by either setting environment variables when the Docker image is started or by using a logback.properties file in their project. However, there's no easy way for them to customize the static fields they'd like to include in the GELF logging...only by overriding the entire GELF appender configuration.

Describe the solution you'd like
Instead of declaring each <staticField> individually, I'd like to be able to add multiple fields in a single element:

...
    <staticFields>field1:my value,field2:second value,field_3:value</staticFields>
...

I'd then be able to declare a variable (either in the environment or in the logback.properties file) containing a comma-delimited list of name:value pairs...

GELF_STATIC_FIELDS=field1:my value,field2:second value,field_3:value

...and use the variable in my default configuration:

...
    <staticFields>${GELF_STATIC_FIELDS}</staticFields>
...

Describe alternatives you've considered
I considered using logback.groovy, but the goal is to make it as easy and user-friendly as possible. I could also take each request and hard-code a new <staticField> everytime and rebuild the Docker image, but not every project wants/needs the same static fields.

Raise Manifest version to 2

In some contexts the library can't be used as the following error message is thrown:

Unsupported 'Bundle-ManifestVersion' value: 1

The error message comes from Karaf which does not seem to support the old Manifest version. - Is there a way to raise the version?

Thank you and best regards!

Error to Add staticField

thanks for making good library osiegmar!!

i have issue to use staticField.
when i use staticField then

Logging system failed to initialize using configuration from 'classpath:logback.xml'
java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.joran.action.NestedBasicPropertyIA - Unexpected aggregationType AS_BASIC_PROPERTY_COLLECTION
ERROR in ch.qos.logback.core.joran.action.NestedBasicPropertyIA - Unexpected aggregationType AS_BASIC_PROPERTY_COLLECTION

but when i remove staticfiled or there is no value in staticfield , then execute normally...
please give me a advise

localhost 12201 woojuin
  <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
    <pattern>%m%nopex</pattern>
  </shortPatternLayout>
  <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">
    <pattern>%m</pattern>
  </fullPatternLayout>
  <staticField>os_name:win</staticField>
</layout>

Feature Request: Masking pattern layout

In an effort to mask sensitive data (passwords, CCID`s etc.) we extend ch.qos.logback.classic.PatternLayout and replace sensitive data with *****
Example:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.foo.config.log.MaskingPatternLayout">
                <pattern> ${PATTERN}</pattern>
            </layout>
        </encoder>
    </appender>

I may have missed it, but it doesnt look like thats possible right now ?

Thanks

Remote Graylog

Hey there,
How are you?

I have 2 graylog servers(1 locally and another published), I can send logs in the graylog locally but when I change grayloghost to the other graylog, it doesn't receive. Do you have any ideia how to send data from differents java application in differents networks to one graylog centralized?

Add the possibility to filter included MDC keys

Using logback-gelf with spring-cloud-sleuth works just fine, and I can index sleuth fields like "traceId" and "spanId" on every log. But for some reason sleuth duplicates the values on two different MDC entries, traceId -> X-B3-TraceId and spanId -> X-B3-SpanId (and other undesired MDC entries).

Having the possibility to filter the MDC data that is included will be interesting for this and other cases I think.

Improve test coverage

As commented in #64:
My current concerns are about the networking stuff (like #62). The corner cases like timeouts or TLS handshakes needs some more testing. And those tests could identify that a different implementation (NIO) is needed. NIO usually comes with higher complexity, hence I'd only use it with a good reason. This reason might be performance โ€“ a test has to proof it. The reason might be this socket timeout issue โ€“ a test would be needed as well.

Differences from other Gelf encoders

It seems the layout used here differs a bit from other popular solutions for other logging frameworks, such as Log4J2's own Gelf encoder).

The two main differences is that Log4J2's sends thread instead of thread_name and logger instead of logger_name.

Unfortunately, this makes filtering logs by such fields a bit of a hassle when there are different systems with different logging frameworks sending logs to the same logstash server.

Would you mind changing this? (I can send the PR, I just need the green light ๐Ÿ˜„)

[question] tcpappender with down graylog uses 5 seconds on log

I am seeing delays on log.info by about 5 seconds when our graylog server is down. Config below.

Is this the way its supposed to be? Udp appender would probably be much better.

`

<appender name="gelf" class="de.siegmar.logbackgelf.GelfTcpAppender">
    <graylogHost>jenkins.usrv.ubergenkom.no</graylogHost>
    <graylogPort>12201</graylogPort>
    <connectTimeout>15000</connectTimeout>
    <reconnectInterval>300</reconnectInterval>
    <maxRetries>2</maxRetries>
    <retryDelay>3000</retryDelay>
    <layout class="de.siegmar.logbackgelf.GelfLayout">
        <originHost>${HOSTNAME}</originHost>
        <includeRawMessage>false</includeRawMessage>
        <includeMarker>true</includeMarker>
        <includeMdcData>true</includeMdcData>
        <includeCallerData>true</includeCallerData>
        <includeRootCauseData>false</includeRootCauseData>
        <includeLevelName>true</includeLevelName>
        <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%m%nopex</pattern>
        </shortPatternLayout>
        <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%m</pattern>
        </fullPatternLayout>
        <staticField>app:${CONTEXT_NAME}</staticField>
        <staticField>constretto:${CONSTRETTO_TAGS}</staticField>
    </layout>
</appender>


<appender name="ASYNCGELF" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="gelf"/>
</appender>

<root level="INFO">
    <appender-ref ref="ASYNCGELF"/>
</root>

`

[BUG] setting reconnectInterval to 0 does not disable reconnects

In de.siegmar.logbackgelf.GelfTcpAppender, the documentation for reconnectInterval says:

Time interval (in seconds) after an existing connection is closed and re-opened.
A value of 0 disables automatic reconnects. Default: 300 seconds.

but the implementation checks for < 0, so effectively reconnects on every message:

    private void connect() throws IOException {
        closeOut();

        final Socket socket = getSocket();
        outputStream = socket.getOutputStream();

        nextReconnect = reconnectInterval < 0
            ? Long.MAX_VALUE
            : System.currentTimeMillis() + (reconnectInterval * SEC_TO_MSEC);
    }

GZIP Compression with GelfUdpAppender

Problem:
We have an application that sends logs to a Logstash instance but all special characters are badly handled. It seems that Logstash has a problem when using ZLIB compression but works well with GZIP compression (tested and approved). (logstash-plugins/logstash-input-gelf#54)

Solution
We would like to be able to use GZIP compression instead of ZLIB since this compression method is also permitted in the GELF specs: https://docs.graylog.org/docs/gelf#gelf

A solution may be to add a <compressionMethod>GZIP/ZLIB</compressionMethod> configuration to the GelfUdpAppender and taken into account only if <useCompression> is true.

Alternative solution
Remove <useCompression> configuration (breaking change) and replace it with <compressionMethod>None/GZIP/ZLIB</compressionMethod>

Multiple markers not handled correctly

Hi,

I'm having some problems with the gelf output, if I understand correctly, this line should loop over related markers and add them as properties like Mdc does.

additionalFields.put("marker", marker.getName());

With multiple markers I get a _marker="LS_APPEND_OBJECT" in my json output.

For example logstash logback adds the various markers as separate properties

Best regards,
Daniel

Reconnect load balancer

Hi,

With long lasting tcp connections to our Graylog load balancer we have trouble balancing the load across our cluster if a node is restarted.

Could you elaborate whether the reconnect functionality would help this situation? My understanding after reading the docs is that it would force a reconnect to the load balancer every N seconds, and thus should help this issue.

Thank you :)

Some log messages never delivered to Graylog server

I have 2 appenders set up, a GelfUdpAppender and a RollingFileAppender. Consistently there are messages that show up in the log file but do not show up in Graylog. Is there a way to debug the gelf appender?

In my specific case I log when connections are made, and I log when they are closed. I only ever see the "connection closed" messages make it to graylog. The "connection opened" messages never show up in graylog though both "connection opened" and "connection closed" messages show up in the log file. The messages come from the same class/logger/format but still, there is something unique about the "connection opened" messages that prevent them from appearing in graylog.

"no applicable action"

Trying out logback-gelf 2.0.0, GELF logging did not happen, and enabling logging.debug in logback made this show up:

12:45:38,253 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [/etc/logger-conf/..data/logback-graylog.xml] at [file:/etc/logger-conf/..data/logback-graylog.xml]
12:45:38,572 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
12:45:38,576 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
12:45:38,597 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
12:45:38,697 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [de.siegmar.logbackgelf.GelfTcpAppender]
12:45:38,699 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [GELF]
12:45:38,719 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@23:59 - no applicable action for [layout], current ElementPath  is [[configuration][appender][layout]]
12:45:38,719 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@24:32 - no applicable action for [includeRawMessage], current ElementPath  is [[configuration][appender][layout][includeRawMessage]]
12:45:38,726 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@25:28 - no applicable action for [includeMarker], current ElementPath  is [[configuration][appender][layout][includeMarker]]
12:45:38,726 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@26:29 - no applicable action for [includeMdcData], current ElementPath  is [[configuration][appender][layout][includeMdcData]]
12:45:38,726 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@27:32 - no applicable action for [includeCallerData], current ElementPath  is [[configuration][appender][layout][includeCallerData]]
12:45:38,727 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@28:35 - no applicable action for [includeRootCauseData], current ElementPath  is [[configuration][appender][layout][includeRootCauseData]]
12:45:38,727 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@29:31 - no applicable action for [includeLevelName], current ElementPath  is [[configuration][appender][layout][includeLevelName]]
12:45:38,727 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@30:78 - no applicable action for [shortPatternLayout], current ElementPath  is [[configuration][appender][layout][shortPatternLayout]]
12:45:38,727 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@31:26 - no applicable action for [pattern], current ElementPath  is [[configuration][appender][layout][shortPatternLayout][pattern]]
12:45:38,728 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@33:77 - no applicable action for [fullPatternLayout], current ElementPath  is [[configuration][appender][layout][fullPatternLayout]]
12:45:38,728 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@34:26 - no applicable action for [pattern], current ElementPath  is [[configuration][appender][layout][fullPatternLayout][pattern]]
12:45:38,729 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@36:26 - no applicable action for [staticField], current ElementPath  is [[configuration][appender][layout][staticField]]
12:45:38,729 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:26 - no applicable action for [staticField], current ElementPath  is [[configuration][appender][layout][staticField]]
12:45:38,772 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender]
12:45:38,774 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [ASYNC GELF]
12:45:38,774 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [GELF] to ch.qos.logback.classic.AsyncAppender[ASYNC GELF]
12:45:38,774 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC GELF] - Attaching appender named [GELF] to AsyncAppender.
12:45:38,781 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC GELF] - Setting discardingThreshold to 51
12:45:38,786 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender]
12:45:38,787 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [ASYNC STDOUT]
12:45:38,787 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to ch.qos.logback.classic.AsyncAppender[ASYNC STDOUT]
12:45:38,787 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC STDOUT] - Attaching appender named [STDOUT] to AsyncAppender.
12:45:38,787 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC STDOUT] - Setting discardingThreshold to 51
12:45:38,787 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
12:45:38,787 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [ASYNC STDOUT] to Logger[ROOT]
12:45:38,788 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [ASYNC GELF] to Logger[ROOT]
12:45:38,788 |-ERROR in ch.qos.logback.core.joran.action.ShutdownHookAction - Missing class name for shutdown hook. Near [shutdownHook] line 55
12:45:38,788 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.

logback-classic version used is 1.2.3.

My configuration:

<configuration scan="true">
<!-- Changes to this configuration will be applied automatically within one minute,
     i.e, you can reload the configmap and the changes will be applied within approximately
     a minute -->

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfTcpAppender">
        <graylogHost>graylog-node.monitoring.svc.cluster.local</graylogHost>
        <graylogPort>12300</graylogPort>
        <connectTimeout>15000</connectTimeout>
        <reconnectInterval>300</reconnectInterval>
        <maxRetries>2</maxRetries>
        <retryDelay>3000</retryDelay>
        <poolSize>2</poolSize>
        <poolMaxWaitTime>5000</poolMaxWaitTime>
        <layout class="de.siegmar.logbackgelf.GelfLayout">
            <includeRawMessage>false</includeRawMessage>
            <includeMarker>true</includeMarker>
            <includeMdcData>true</includeMdcData>
            <includeCallerData>true</includeCallerData>
            <includeRootCauseData>true</includeRootCauseData>
            <includeLevelName>true</includeLevelName>
            <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%m%nopex</pattern>
            </shortPatternLayout>
            <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%m</pattern>
            </fullPatternLayout>
            <staticField>ncs-service:grpc</staticField>
            <staticField>namespace:erfor</staticField>
        </layout>
    </appender>

    <appender name="ASYNC GELF" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="GELF" />
    </appender>

    <appender name="ASYNC STDOUT" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="STDOUT" />
    </appender>


    <root level="info">
        <appender-ref ref="ASYNC STDOUT" />
        <appender-ref ref="ASYNC GELF" />
    </root>

    <shutdownHook/>

</configuration>

Reverting to logback-gelf 1.1.0 resolves the problem.

Seems a bit similar to #6

Add ability to log thread ID in addition to thread name

Is your feature request related to a problem? Please describe.
Thread names in Java are not guaranteed unique, so it'd be useful to include thread ids as well. This would basically be analogous to logging %T instead of/in addition to %t in a Pattern Layout.

Describe the solution you'd like
I'd like my GELF message to be able to include thread ID in addition to the thread name (presumably as an additional, separate field).

An alternative, more general solution would be allowing the definition of extra fields besides ShortPatternLayout and FullPatternLayout that can use Pattern Layouts in the same manner (static fields as currently implemented can only use Logback variable substitution, which as far as I can tell can't include something like the thread id).

Describe alternatives you've considered
Since ShortPatternLayout and FullPatternLayout are, indeed, Pattern Layouts, I could just include %T in one of those, but this means I'd then have to parse the thread ID out of the message field later, which sort of feels like giving up a big benefit of using GELF.

Error sending GELF message java.nio.channels.AsynchronousCloseException

spring boot: 2.1.3.RELEASE
logback-gelf: 1.1.0
graylog: 3.1.2

23:31:04,825 |-ERROR in de.siegmar.logbackgelf.GelfUdpAppender[GELF_UDP] - Error sending GELF message java.nio.channels.AsynchronousCloseException
	at java.nio.channels.AsynchronousCloseException
	at 	at java.base/java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
	at 	at java.base/sun.nio.ch.DatagramChannelImpl.endWrite(DatagramChannelImpl.java:693)
	at 	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:533)
	at 	at de.siegmar.logbackgelf.GelfUdpAppender.appendMessage(GelfUdpAppender.java:81)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:106)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:28)
	at 	at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
	at 	at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
	at 	at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
	at 	at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
	at 	at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
	at 	at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:414)
	at 	at ch.qos.logback.classic.Logger.info(Logger.java:587)

Refactor JSON to byte array

Refactor de.siegmar.logbackgelf.GelfMessage#toJSON to return byte[] instead of String for proper performance.

[question] Performance of GelfUdpAppender

Hello @osiegmar,

I'd like to ask about following line

https://github.com/osiegmar/logback-gelf/blob/master/src/main/java/de/siegmar/logbackgelf/GelfUdpAppender.java#L73

According to InetSocketAddress javadoc

An attempt will be made to resolve the hostname into an InetAddress. If that attempt fails, the address will be flagged as unresolved.

So, I assume this line is affecting logging performance since host / port resolution happens on each log statement.

What do you think ?

inetaddress.getlocalhost().getcanonicalhostname() cause slow startup

after added de.siegmar.logbackgelf.GelfUdpAppender to logback-spring.xml the application will freeze 15s before spring logo appear,
debug the constructor of GelfUdpAppender found getcanonicalhostname() is too slow to resolve

//host = nameService.getHostByAddr(addr.getAddress());   //15s to load
getHostFromNameService:618, InetAddress (java.net)
getCanonicalHostName:589, InetAddress (java.net)
buildHostname:279, GelfEncoder (de.siegmar.logbackgelf)
start:265, GelfEncoder (de.siegmar.logbackgelf)

root cause maybe npcap in windows.
reference: https://stackoverflow.com/questions/47031687/getcanonicalhostname-is-very-slow

add that ip to host file fix one computer, but i dont want to modify every developer's hosts file.

could you use a faster way to get hostname without resolve?
https://stackoverflow.com/questions/7348711/recommended-way-to-get-hostname-in-java

tried to override buildHostname() but it was private.

os: windows 10

Formatting issue when logging exception object

When we log something like this:

try {
    throw new RuntimeException("Some exception message")
} catch(RuntimeException runtimeException) {
    slf4JLogger.error("Some message: {}", 123, runtimeException)
}

then we see in Kibana as message:

August 28th 2018, 19:23:50.184    ERROR     Some message: 123java.lang.RuntimeException: Some exception message
    at [...]
    at [...]

-> as you can see, the exception is suffixed without newline to the log message!

In our Log4j appegged like this:

2018-08-28 19:23:50.184   ERROR   [...]   Some message: 123

java.lang.RuntimeException: Some exception message
    at [...]
    at [...]

Is this a bug? Where does the difference come from?
We understand that slf4j auto-appends the exception to the message if e.g. "%noexp" is not explicitly specified. But in log4j the formatting comes out readable whereas with logback-gelf we have this problem.

Any help is highly appreciated!

GeflUdpAppender throws ClosedChannelException

Hi, when logging to Graylog with logback-gelf-1.1.0.jar it stops logging after a minute.
By debugging I see that gelf throws a ClosedChannelException. Maybe gelf needs to check the state of channel and reopen if closed?:

[Ljava.lang.StackTraceElement;@39e25fb8java.nio.channels.ClosedChannelException
	at sun.nio.ch.DatagramChannelImpl.ensureOpen(DatagramChannelImpl.java:320)
	at sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:428)
	at de.siegmar.logbackgelf.GelfUdpAppender.appendMessage(GelfUdpAppender.java:81)
	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:106)
	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:28)
	at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
	at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
	at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
	at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
	at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
	at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:414)
	at ch.qos.logback.classic.Logger.info(Logger.java:587)

Ability to add custom fields to GelfMessage, computed from ILoggingEvent

I would like to implement error grouping similar to Bugsnag. For this, I would like to add a group identifier as a custom field on each relevant GELF message (computed based on raw message, some stack frames, etc).
Currently, this is not easy, so I would like to propose some sort of extension point to make it easier. A kind of "enrichment" processors.

Basically, it would boil down to turning GelfEncoder.mapAdditionalFields(ILoggingEvent event) method into an interface. I'll make a PR to exemplify this.

If you want to explore this idea further, you could even refactor GelfEncoder and replace all include* properties with specific built-in "enrichment" processors. This would simplify that class A LOT.

Usage sample:

<configuration>
  <appender name="GELF" class="de.siegmar.logbackgelf.GelfTcpAppender">
        <graylogHost>localhost</graylogHost>
        <graylogPort>12201</graylogPort>
        <connectTimeout>15000</connectTimeout>
        <reconnectInterval>300</reconnectInterval>
        <maxRetries>2</maxRetries>
        <retryDelay>3000</retryDelay>
        <poolSize>2</poolSize>
        <poolMaxWaitTime>5000</poolMaxWaitTime>
        <poolMaxIdleTime>10</poolMaxIdleTime>
        <encoder class="de.siegmar.logbackgelf.GelfEncoder">
            <originHost>localhost</originHost>
            <additionalFieldMapper class="my.package.GelfGroupIdentifierGenerator"/>
        </encoder>
  </appender>
</configuration>

Feature Request: TLS configuration

It'd be nice if, when using the TcpTlsAppender, you could explicitly supply a Root CA to trust. It'd also be good if you could specify a client certificate and key to use for TLS Client Certificate Authentication.

Got empty hostname .

    private String buildHostname() {
        try {
            return InetAddress.getLocalHost().getCanonicalHostName();
        } catch (final UnknownHostException e) {
            return UUID.randomUUID().toString();
        }
    }

GelfUdpChunker#buildHostname

sometimes, it return empty string but uuid. cause the graylog sever missing log.

the other client works well .
Moocar

    /**
     * Retrieves the local host's hostname. If found, the fully qualified domain name (FQDN) will be returned,
     * otherwise it will fallback to the unqualified domain name. E.g prefer guerrero.moocar.me over guerrero.
     */
    public static String getLocalHostName() throws SocketException, UnknownHostException {
        try {
            final String canonicalHostName = InetAddress.getLocalHost().getCanonicalHostName();
            if (isFQDN(canonicalHostName)) {
                return canonicalHostName;
            } else {
                return InetAddress.getLocalHost().getHostName();
            }
        } catch (UnknownHostException e) {
            NetworkInterface networkInterface = NetworkInterface.getNetworkInterfaces().nextElement();
            if (networkInterface == null)
                throw e;
            InetAddress ipAddress = networkInterface.getInetAddresses().nextElement();
            if (ipAddress == null)
                throw e;
            return ipAddress.getHostAddress();
        }
    }

can use this way to get hostname, It's a pleasure.

Use property as a variable in staticField

I'm new to JAVA stack and I may seem totally lost.

I want logback to send the environment name to graylog as field. so I can create a stream based on that field (prod,stage,dev..)

To achieve this, I created a file under resources called application.properties containing:
environment=dev

into backlog.xml I added : <staticField>environment:${environment}</staticField>
After that, in gray log I'm receiving : environment environment_IS_UNDEFINED

Do you know how can I achieve this? any reference to documentation is welcome.
Thanks for your help!

Some messages are lost

I'm using the latest logback-gelf appender (3.0.0) and also tried the old one (2.2.0) with Spring Boot 2.2.2.RELEASE (web app)

Not all the messages are reaching Graylog, and when the app is under heavy load almost none of them are logged.

When enabling logback debug I see the following errors very often:

ERROR in de.siegmar.logbackgelf.GelfTcpAppender[GELF] - Error sending message via tcp://my host:12201 java.net.SocketException: Broken pipe (Write failed)
	at java.net.SocketException: Broken pipe (Write failed)
	at 	at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
	at 	at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
	at 	at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:138)
	at 	at de.siegmar.logbackgelf.TcpConnection.write(TcpConnection.java:55)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender$2.accept(GelfTcpAppender.java:176)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender$2.accept(GelfTcpAppender.java:173)
	at 	at de.siegmar.logbackgelf.pool.SimpleObjectPool.execute(SimpleObjectPool.java:63)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.sendMessage(GelfTcpAppender.java:173)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.appendMessage(GelfTcpAppender.java:147)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:104)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:27)
	at 	at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
	at 	at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
	at 	at ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:290)


Also, there are the following errors:

ERROR in de.siegmar.logbackgelf.GelfTcpAppender[GELF] - Error sending message via tcp://my host:12201 java.net.SocketException: An established connection was aborted by the software in your host machine
	at java.net.SocketException: An established connection was aborted by the software in your host machine
	at 	at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:421)
	at 	at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:441)
	at 	at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:825)
	at 	at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1007)
	at 	at java.base/java.io.OutputStream.write(OutputStream.java:122)
	at 	at de.siegmar.logbackgelf.TcpConnection.write(TcpConnection.java:55)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.lambda$sendMessage$1(GelfTcpAppender.java:161)
	at 	at de.siegmar.logbackgelf.pool.SimpleObjectPool.execute(SimpleObjectPool.java:63)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.sendMessage(GelfTcpAppender.java:161)
	at 	at de.siegmar.logbackgelf.GelfTcpAppender.appendMessage(GelfTcpAppender.java:135)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:104)
	at 	at de.siegmar.logbackgelf.AbstractGelfAppender.append(AbstractGelfAppender.java:27)
	at 	at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
	at 	at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
	at 	at ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:290)

Here is my config

<appender name="GELF" class="de.siegmar.logbackgelf.GelfTcpAppender">
        <graylogHost>${MY_GRAYLOG_HOST}</graylogHost>
        <graylogPort>12201</graylogPort>
        <connectTimeout>15000</connectTimeout>
        <reconnectInterval>300</reconnectInterval>
        <maxRetries>2</maxRetries>
        <retryDelay>3000</retryDelay>
        <poolSize>2</poolSize>
        <poolMaxWaitTime>5000</poolMaxWaitTime>
        <encoder class="de.siegmar.logbackgelf.GelfEncoder">
            <originHost>localhost</originHost>
            <includeMdcData>true</includeMdcData>
            <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%m%nopex</pattern>
            </shortPatternLayout>
            <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%m%n</pattern>
            </fullPatternLayout>
            <staticField>application:${application}</staticField>
        </encoder>
    </appender>

    <appender name="ASYNC_GELF" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="GELF" />
    </appender>

    <root level="info">
        <appender-ref ref="ASYNC_GELF" />
        <appender-ref ref="Console" />
    </root>

All statics fields are prefixed by _ if we log in the run method of thread

Hello @osiegmar ,

We noticed if we log in the run method of a thread, all statics fields are prefixed by _

Example : when we call a method from the run method of thread, statics fields are prefixed by _ ( _app_name instead of app_name for example)

if we call the same method from http endpoint, all static fields are ok (not prefixed with underscore)

Did we miss a configuration ? Any suggestions please ?

Thank you for your help.

use the config that in advanced_udp.xml cause an exception

Hi,first thank you provide the good project logback-gelf.
Unfortunately i am using the config that in advanced_udp.xml cause an exception.
I use the springboot verision is : 2.2.2.RELEASE,logback-gelf verision is :2.2.0

This is my logback.xml.
`

<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
        <pattern>
            %d - %msg%n
        </pattern>
    </layout>
</appender>
<appender name="GELF" class="de.siegmar.logbackgelf.GelfUdpAppender">
    <graylogHost>192.168.31.102</graylogHost>
    <graylogPort>12201</graylogPort>
    <maxChunkSize>508</maxChunkSize>
    <useCompression>true</useCompression>
    <messageIdSupplier class="de.siegmar.logbackgelf.MessageIdSupplier"/>
    <encoder class="de.siegmar.logbackgelf.GelfEncoder">
        <originHost>localhost</originHost>
        <includeRawMessage>false</includeRawMessage>
        <includeMarker>true</includeMarker>
        <includeMdcData>true</includeMdcData>
        <includeCallerData>false</includeCallerData>
        <includeRootCauseData>false</includeRootCauseData>
        <includeLevelName>false</includeLevelName>
        <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%m%nopex</pattern>
        </shortPatternLayout>
        <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%m%n</pattern>
        </fullPatternLayout>
        <numbersAsString>false</numbersAsString>
        <staticField>app_name:backend</staticField>
        <staticField>os_arch:${os.arch}</staticField>
        <staticField>os_name:${os.name}</staticField>
        <staticField>os_version:${os.version}</staticField>
    </encoder>
</appender>

<root level="info">
    <appender-ref ref="consoleLog"/>
    <appender-ref ref="GELF"/>
</root>

`

This is exception log.

Exception in thread "main" java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.joran.spi.Interpreter@15:78 - no applicable action for [messageIdSupplier], current ElementPath is [[configuration][appender][messageIdSupplier]]
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.reinitialize(LogbackLoggingSystem.java:222)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:73)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:313)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:288)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:206)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:117)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:74)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at com.evan.eureka.EurekaApplication.main(EurekaApplication.java:12)

when i delete this config : <messageIdSupplierclass="de.siegmar.logbackgelf.MessageIdSupplier"/>

Application can run normally.

Could you please solve this problem or give me some help, thank you very much~

Add a configurable socket timeout

We are using logback-gelf for a while and are pretty happy with it. The following rare error happened only once. It caused our application to freeze while all threads were blocked trying to send a log message.

We are using a GelfTcpTlsAppender.
When establishing the connection, the socket is read for the tls handshake. For some reason the tls handshake did never finish successfully. Since no socket timeout is configured, the appender keeps waiting forever:

"AsyncAppender-Worker-GELF_ASYNC" #29 daemon prio=5 os_prio=0 cpu=4681.06ms elapsed=47670.01s tid=0x00007febb8ea2000 nid=0x1f7a1 runnable  [0x00007febbb1fa000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0([email protected]/Native Method)
	at java.net.SocketInputStream.socketRead([email protected]/SocketInputStream.java:115)
	at java.net.SocketInputStream.read([email protected]/SocketInputStream.java:168)
	at java.net.SocketInputStream.read([email protected]/SocketInputStream.java:140)
	at sun.security.ssl.SSLSocketInputRecord.read([email protected]/SSLSocketInputRecord.java:467)
	at sun.security.ssl.SSLSocketInputRecord.readHeader([email protected]/SSLSocketInputRecord.java:461)
	at sun.security.ssl.SSLSocketInputRecord.decode([email protected]/SSLSocketInputRecord.java:160)
	at sun.security.ssl.SSLTransport.decode([email protected]/SSLTransport.java:110)
	at sun.security.ssl.SSLSocketImpl.decode([email protected]/SSLSocketImpl.java:1403)
	at sun.security.ssl.SSLSocketImpl.readHandshakeRecord([email protected]/SSLSocketImpl.java:1309)
	at sun.security.ssl.SSLSocketImpl.startHandshake([email protected]/SSLSocketImpl.java:440)
	at sun.security.ssl.SSLSocketImpl.ensureNegotiated([email protected]/SSLSocketImpl.java:814)
	at sun.security.ssl.SSLSocketImpl$AppOutputStream.write([email protected]/SSLSocketImpl.java:1184)
	at java.io.OutputStream.write([email protected]/OutputStream.java:122)
	at de.siegmar.logbackgelf.TcpConnection.write(TcpConnection.java:55)
	at de.siegmar.logbackgelf.GelfTcpAppender$2.accept(GelfTcpAppender.java:176)
	at de.siegmar.logbackgelf.GelfTcpAppender$2.accept(GelfTcpAppender.java:173)
	at de.siegmar.logbackgelf.pool.SimpleObjectPool.execute(SimpleObjectPool.java:63)
	at de.siegmar.logbackgelf.GelfTcpAppender.sendMessage(GelfTcpAppender.java:173)

Of course the network error is out of logback-gelf's scopes and fortunately it seems to be a rare edge case.
We would appreciate it, if the GelfTcpTlsAppender's socket timeout can be configured, like it is already possible for the connection timeout.

Thank you!

logback 1.1.8: "No applicable action for [graylogHost]"

I'm not sure what changed, but running logback-gelf with logback-{core,classic}-1.1.8 with the sample configuration in the readme results in:

16:36:43,214 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [de.siegmar.logbackgelf.GelfUdpAppender]
16:36:43,216 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [GELF]
16:36:43,218 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@36:22 - no applicable action for [graylogHost], current ElementPath  is [[configuration][appender][graylogHost]]
16:36:43,218 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:22 - no applicable action for [graylogPort], current ElementPath  is [[configuration][appender][graylogPort]]
16:36:43,218 |-ERROR in de.siegmar.logbackgelf.GelfUdpAppender[GELF] - No graylogHost configured

Logback 1.1.3 works fine though, so I'm running with that for now.

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.