Skip to content

Commit 358f644

Browse files
authored
Document Thread and ThreadLocal cleanup (#1105)
Add a section to the readme on Threads and ThreadLocals and how to ensure they are cleaned up, and don't leak memory.
1 parent 0d553cf commit 358f644

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ The structure of the output, and the data it contains, is fully configurable.
3838
* [Wait Strategy](#wait-strategy)
3939
* [Appender Listeners](#appender-listeners)
4040
* [Encoders / Layouts](#encoders--layouts)
41+
* [Threads and ThreadLocals](#threads-and-threadlocals)
4142
* [LoggingEvent Fields](#loggingevent-fields)
4243
* [Standard Fields](#standard-fields)
4344
* [MDC fields](#mdc-fields)
@@ -87,7 +88,7 @@ The structure of the output, and the data it contains, is fully configurable.
8788
* [AccessEvent patterns](#accessevent-patterns)
8889
* [Custom JSON Provider](#custom-json-provider)
8990
* [Status Listeners](#status-listeners)
90-
* [Joran/XML Configuration](#joran-xml-configuration)
91+
* [Joran/XML Configuration](#joranxml-configuration)
9192
* [Duration Property](#duration-property)
9293
* [Comma separated list of values](#comma-separated-list-of-values)
9394

@@ -963,7 +964,42 @@ input {
963964
}
964965
```
965966

967+
### Threads and ThreadLocals
966968

969+
Asynchronous appenders use a separate set of threads to process logging events.
970+
971+
The encoders/layouts use ThreadLocals internally to improve performance.
972+
973+
In environments that support application reloading (e.g. web containers)
974+
and in applications with many threads logging events (e.g. virtual threads),
975+
it is recommended to:
976+
1. use an asynchronous appender (such as `LogstashTcpSocketAppender`, `LoggingEventAsyncDisruptorAppender`, or [`AsyncAppender`](https://logback.qos.ch/manual/appenders.html#AsyncAppender)), and
977+
2. [cleanly shut down logback](http://logback.qos.ch/manual/configuration.html#stopContext) when the application is stopped/reloaded.
978+
979+
980+
Using an asynchronous appender ensures that a limited number of threads use the encoder/layout,
981+
and therefore limits the number of ThreadLocal value instances
982+
and minimizes resource contention.
983+
984+
Cleanly shutting down logback stops the threads used by the asynchronous appender,
985+
and makes their ThreadLocal values eligible for garbage collection.
986+
987+
Failure to use an asynchronous appender may result in errors like the following when stopping/reloading an application in Tomcat:
988+
989+
```
990+
The web application [webapp] created a ThreadLocal with key of type [java.lang.ThreadLocal.SuppliedThreadLocal]
991+
(value [java.lang.ThreadLocal$SuppliedThreadLocal@6f75b07c]) and a value of type
992+
[net.logstash.logback.util.ThreadLocalHolder.Holder] (value [net.logstash.logback.util.ThreadLocalHolder$Holder@7d940c3e])
993+
but failed to remove it when the web application was stopped.
994+
Threads are going to be renewed over time to try and avoid a probable memory leak.
995+
```
996+
997+
Failure to cleanly shutdown logback may result in errors like the following when stopping/reloading an application in Tomcat:
998+
999+
```
1000+
The web application [webapp] appears to have started a thread named [logback-appender-ASYNC-2] but has failed to stop it.
1001+
This is very likely to create a memory leak.
1002+
```
9671003

9681004
## LoggingEvent Fields
9691005

0 commit comments

Comments
 (0)