qos-ch / logback Goto Github PK
View Code? Open in Web Editor NEWThe reliable, generic, fast and flexible logging framework for Java.
Home Page: http://logback.qos.ch
License: Other
The reliable, generic, fast and flexible logging framework for Java.
Home Page: http://logback.qos.ch
License: Other
Invoking log.info("Destroyed {} gracefully in {} ms.", process, duration)
doesn't interpolate the values in the message
field when using JsonEncoder
.
The arguments are there in the arguments
array so technically interpolation can be done downstream (e.g. the consumer of the ndjson-formatted output) but this is a bit surprising and makes integration with log sinks harder.
Any plans to have some form of interpolation supported here? I'd be happy to provide a PR.
I checked that, the logic about contextSelectorBinder had been abandoned by @ceki almost 7 years ago.
The commit is 6660751
seems like logback do not support customize my owner contextSelector any more. can I get the reason? and if logback still support the customization, can anyone tell me the new way?
This bug(?) appears in later versions of ch.qos.logback: classic > 1.2.12
I am using the below code in a unit test class with the following imports and declarations
`
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.slf4j.LoggerFactory;
private final Logger logger = (Logger) LoggerFactory.getLogger(MyClass.class);
private final ListAppender listAppender = new ListAppender<>();
@BeforeEach
public void setUp() {
listAppender.start();
logger.addAppender(listAppender);
}
`
I am using org.slf4j:api version 2.0.9 and logback-classic version 1.2.12 as that's the last version that doesn't break the casting.
Hoping I can get an answer or a guide to this issue.
version:1.2.2
blocking position:ch.qos.logback.core.AppenderBase#doAppend:63
Appender:RollingFileAppender
On Windows, when I use logback 1.4.14
with Jansi 2.4.0
in the old CMD.EXE console, the logback fails to produce color-coded output. The same code executed in Windows Terminal works as expected.
Interestingly, substituting the current Jansi 2.4.0
with an older Jansi 1.18
, seems to fix the issue. This suggests that there might be some differences in the newer versions of Jansi that Logback doesn't handle very well.
The following ZIP contains a simple example (requires Java 11+) that produces colored output using standalone Jansi 1.18
and 2.4.0
, and Logback with Jansi 1.18
and 2.4.0
. To execute: extract and run jansi-examples.bat
Here's the output produced on the same machine in CMD.EXE console:
and in Windows Terminal:
Hello,
checkIncrement was added in 1.3.12, but it is not configurable via SizeAndTimeBasedRollingPolicy
which constructs SizeAndTimeBasedFNATP
automatically.
Can checkIncrement
get added as an option to SizeAndTimeBasedRollingPolicy
?
Attempting Logback receiver feature I get this error:
ERROR in ch.qos.logback.core.model.processor.DefaultProcessor@76b10754 - Can't handle model of type class ch.qos.logback.classic.model.ReceiverModel with tag: receiver at line 11
My setup:
To reproduce:
Structure:
./
├── pom.xml
└── src/
└── main/
├── java/
│ └── logbackreceiver/
│ └── server/
│ └── Main.java
└── resources/
└── logback.xml
Main.java:
package logbackreceiver.server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
static public void main(String[] args) {
logger.info("Starting");
}
}
logback.xml:
(I also tried the canonical style with same result)
<configuration debug="true">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%date]-%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
<receiver class="ch.qos.logback.classic.net.server.ServerSocketReceiver">
<port>3331</port>
</receiver>
</configuration>
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>home.logbackreceiver</groupId>
<artifactId>server</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<version>1.0-SNAPSHOT</version>
<name>logbackreceiverserver</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.3.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.3.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
</project>
To build and run:
mvn clean compile && sudo mvn exec:java -Dexec.mainClass="logbackreceiver.server.Main"
Following the guide here: https://logback.qos.ch/manual/receivers.html
I also cloned code from github (various versions here too) and run the example codes. Everything give me the same problem.
I tried various versions of Logback (3.x and 4.x). I tried Java 8,11,17
I would prefer to make Logback 3.x to work since I am stuck with Java 8 in prod.
I even tried run it in a Docker-container to rule out problems in my environment.
Complete log:
12:50:25,651 |-INFO in ch.qos.logback.classic.LoggerContext[default] - This is logback-classic version 1.3.11
12:50:25,652 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - No custom configurators were discovered as a service.
12:50:25,652 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - Trying to configure with ch.qos.logback.classic.joran.SerializedModelConfigurator
12:50:25,652 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - Constructed configurator of type class ch.qos.logback.classic.joran.SerializedModelConfigurator
12:50:25,664 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.scmo]
12:50:25,664 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.scmo]
12:50:25,664 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - ch.qos.logback.classic.joran.SerializedModelConfigurator.configure() call lasted 12 milliseconds. ExecutionStatus=INVOKE_NEXT_IF_ANY
12:50:25,664 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - Trying to configure with ch.qos.logback.classic.util.DefaultJoranConfigurator
12:50:25,665 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - Constructed configurator of type class ch.qos.logback.classic.util.DefaultJoranConfigurator
12:50:25,665 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
12:50:25,665 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/home/x/Projects/logbackreceiver/server/target/classes/logback.xml]
12:50:25,722 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [CONSOLE]
12:50:25,722 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
12:50:25,725 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
12:50:25,729 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to DEBUG
12:50:25,729 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONSOLE] to Logger[ROOT]
12:50:25,730 |-ERROR in ch.qos.logback.core.model.processor.DefaultProcessor@270251cf - Can't handle model of type class ch.qos.logback.classic.model.ReceiverModel with tag: receiver at line
10
12:50:25,730 |-WARN in ch.qos.logback.core.model.processor.ImplicitModelHandler - Ignoring unknown property [port] in [ch.qos.logback.classic.LoggerContext]
12:50:25,730 |-ERROR in ch.qos.logback.core.model.processor.DefaultProcessor@270251cf - Can't handle model of type class ch.qos.logback.classic.model.ReceiverModel with tag: receiver at line
10
12:50:25,730 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@270251cf - End of configuration.
12:50:25,730 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@49fe6dec - Registering current configuration as safe fallback point
12:50:25,730 |-INFO in ch.qos.logback.classic.util.ContextInitializer@2e8123ad - ch.qos.logback.classic.util.DefaultJoranConfigurator.configure() call lasted 65 milliseconds. ExecutionStatus=DO_NOT_INVOKE_NEXT_IF_ANY
[2023-09-29 12:50:25,731]-Starting
I have started the same JAR file on the same server using two different ports, and I'm writing logs to the same log file. The log file should be split by day and when it reaches 30MB, a new log file should be created. However, I'm facing the following issue: after midnight, one of the services is still writing logs to the file from the previous day and not creating a new one, while the other service is working correctly. What could be the reason for this?
`
<springProperty scope="context" name="logfile.home" source="server.logfile.home"/>
<springProperty scope="context" name="logLevel" source="server.loglevel"/>
<springProperty scope="context" name="profiles.active" source="spring.profiles.active"/>
<appender name="ERRORFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logfile.home}/error/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logfile.home}/error/error.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<MaxHistory>60</MaxHistory>
<totalSizeCap>2GB</totalSizeCap>
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<MaxFileSize>30MB</MaxFileSize>
</TimeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%p] [%t] [%class{35}] [%X{supplierId}-%X{userId}][%X{deviceSn}][%X{traceId}] [%m]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="DEBUGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logfile.home}/debug/debug.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logfile.home}/debug/debug.%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<MaxHistory>1095</MaxHistory>
<totalSizeCap>30GB</totalSizeCap>
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<MaxFileSize>30MB</MaxFileSize>
</TimeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%p] [%t] [%class{35}] [%X{supplierId}-%X{userId}][%X{deviceSn}][%X{traceId}] [%m]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<neverBlock>true</neverBlock>
<queueSize>512</queueSize>
<appender-ref ref="DEBUGFILE" />
</appender>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG"/>
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG"/>
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG"/>
<root level="${logLevel}">
<appender-ref ref="DEBUGFILE"/>
<appender-ref ref="ERRORFILE"/>
</root>
`
环镜是 java 17 ,启动正常,运行正常。。。就是没打印日志。
In LOGBACK-1673 it was mentioned that
One notable change is that, <if>/<then> elements cannot be embedded within "second phase" elements such as <appender>/<root>/<logger>. The<if>/<then> elements must be located under <configuration> or other "first phase elements", i.e. all elements other than <appender>/<root>/<logger>.
In my case, I have a conditional configuration for an appender. There's a chunk of attributes that I don't include when some property is not set. For example,
<appender name="..." class="...">
<log>...</log>
<flushLevel>...</flushLevel>
<if condition='...'>
<then>
<partialSuccess>true</partialSuccess>
<logbackBatchingSettings>
<elementCountThreshold>...</elementCountThreshold>
...
</logbackBatchingSettings>
</then>
</if>
</appender>
With the sanity check in place, I don't see any way to configure this properly without duplicating appenders: one with these settings and the same one but without, then introducing a logic to include only one of them later. That looks like a lot of duplication and exposing properties/logic that I'd rather have in the <include>
d xml.
What's the best way to express a conditional configuration for an appender in 1.3/1.4?
Hi , someone know why my logback settings stopped working , I didn't even change them
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
<scope>compile</scope>
src\main\resources\logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %blue(LogBack) %magenta(Logger) [%thread] %highlight(%-5level){TRACE=blue, DEBUG=green, INFO=white, WARN=yellow, ERROR=red} %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Intergacja z discord za pomocą JDA-->
<!-- <logger name="net.dv8tion.jda" level="OFF"/>-->
<logger name="net.dv8tion.jda" level="ERROR,WARN"/>
<!-- Strona -->
<logger name="org.eclipse.jetty" level="ERROR,WARN"/>
<logger name="io.javalin" level="ERROR,WARN"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
xz is more efficient than gzip and are widely used now, and xz -0
produces smaller files than gzip -9
.
Hi,
There are files that are licensed only under the LGPL v2.1 only. This may cause users to use the software under only the LGPL v2.1 only license. The following are the files:
Can you please correct the license text in the files to reflect the dual license that applies to the rest of the source code files?
The AsyncAppender-Worker-ASYNC_STDOUT worker stack is as follows:
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122)
then the arrayBlockingQueue soon be full, and all business threads stand awaiting.
It happened once, and is difficult to repeat in the production environment.
Could you tell me how can I find the cause of what happened in the invocation of write?
The Java application runs in the containerd runtime on linux os orchestrated by Kubernetes. thanks!
I'm using slf4j with logback 1.2.x and have the following code to reset logback to default configuration:
ch.qos.logback.classic.LoggerContext loggerContext = (ch.qos.logback.classic.LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory();
ch.qos.logback.classic.util.ContextInitializer ci = new ch.qos.logback.classic.util.ContextInitializer(loggerContext);
java.net.URL confUrl = ci.findURLOfDefaultConfigurationFile(true);
loggerContext.reset();
ch.qos.logback.classic.joran.JoranConfigurator joranConfigurator = new ch.qos.logback.classic.joran.JoranConfigurator();
joranConfigurator.setContext(loggerContext);
joranConfigurator.doConfigure(confUrl);
Upgrading logback to 1.3.x or 1.4.x I get compilation error:
The method findURLOfDefaultConfigurationFile(boolean) is undefined for the type ContextInitializer
How to implement this in the newer versions?
Feature request:
pls make possible to write conditions without janino.
it should allow to use conditions with native image for example.
I suggest something like a predicate-like interface that user would implement and use like so:
<if predicateClass="org.example.MyCondition">
or it could be a static method
SpringBoot 3.1.5
<============ 🚀 JAVA版本:21 CPU核心数:4 🚀 ============>
18:43:09.194 [main] INFO hxy.dream.app.Application -- 当前CPU核心=4,main是否为守护线程=false
Logging system failed to initialize using configuration from 'classpath:logback-spring.xml'
java.lang.IllegalStateException: Could not initialize Logback logging from classpath:logback-spring.xml
at org.springframework.boot.logging.logback.LogbackLoggingSystem.lambda$loadConfiguration$1(LogbackLoggingSystem.java:250)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.withLoggingSuppressed(LogbackLoggingSystem.java:460)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:242)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:66)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:57)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:189)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:335)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
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:174)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at hxy.dream.app.Application.main(Application.java:30)
Caused by: ch.qos.logback.core.joran.spi.JoranException: Error during parser creation or parser configuration
at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:99)
at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:62)
at ch.qos.logback.core.joran.GenericXMLConfigurator.populateSaxEventRecorder(GenericXMLConfigurator.java:184)
at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:158)
at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:122)
at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:65)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.configureByResourceUrl(LogbackLoggingSystem.java:285)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.lambda$loadConfiguration$1(LogbackLoggingSystem.java:247)
... 25 more
Caused by: org.xml.sax.SAXNotRecognizedException: unrecognized feature http://xml.org/sax/features/external-general-entities
at org.gjt.xpp.sax2.Driver.setFeature(Driver.java:178)
at org.gjt.xpp.jaxp11.SAXParserImpl.setFeatures(SAXParserImpl.java:149)
at org.gjt.xpp.jaxp11.SAXParserImpl.<init>(SAXParserImpl.java:132)
at org.gjt.xpp.jaxp11.SAXParserFactoryImpl.newSAXParserImpl(SAXParserFactoryImpl.java:114)
at org.gjt.xpp.jaxp11.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:142)
at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:88)
... 32 more
Disconnected from the target VM, address: '127.0.0.1:51293', transport: 'socket'
Process finished with exit code 1
When file compression is enabled and triggered (gz or zip) and the program exits before Logback can complete the compression, the .tmp files created.
Logback file:
<configuration scan="true">
<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${BW_LOG_DIR}/test.log</file>
<!-- <fileNamePattern>${BW_LOG_DIR}/test.log</fileNamePattern> -->
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${BW_LOG_DIR}/test.log.%d{yyyy-MM-dd}.log%i.zip</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days' worth of history, but at most 1GB -->
<maxFileSize>1KB</maxFileSize>
<maxHistory>0</maxHistory>
<totalSizeCap>1KB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] <%X{operationID}> %logger{36} - %msg%n</pattern>
</encoder>
</appender>
I tried of using shutdownhook as you can see in the above snippet but still .tmp files are generated. I am using logback-core version 1.2.10.
Please help me out with the above issue.
In our Maven-based Java-Lambdas we get no application logs if we upgrade from logback-core & logback-classic v1.4.8 to 1.4.9 and above (even with everything else staying the same).
I couldn't find anything in the Release Notes or elsewhere that could explain this.
The applications use:
As of SLF4j 2.0.10, the internal org.slf4j.helpers.Util.report
method is commented out: https://github.com/qos-ch/slf4j/blob/v_2.0.10/slf4j-api/src/main/java/org/slf4j/helpers/Util.java#L120-L124
Unfortunately, this method is being used in Logback to report errors initializing the LoggerContext: https://github.com/qos-ch/logback/blob/v_1.4.14/logback-classic/src/main/java/ch/qos/logback/classic/spi/LogbackServiceProvider.java#L49-L65
The result is that if the LoggerContext initialization fails for whatever reason (e.g. an exception thrown in some component's start
method), a NoSuchMethodError
is thrown and bubbles up to the caller, most likely causing the application using it to exit. In contrast, with SLF4j 2.0.9, an error message is printed including the stack trace of the root cause exception, and no exception is thrown to the caller, so the rest of the program can work as usual (except without logs).
A short snippet
<appender name="STDOUT" class="${APPENDER_CLASS:-ch.qos.logback.core.ConsoleAppender}">
<layout class="${LAYOUT_CLASS:-some.custom.Layout}">
<hostName>${HOSTNAME}</hostName>
</layout>
In this example, the layout class may be specified via env variable, which is useful to switch between different receivers.
However, the APPENDER_CLASS
will not be substituted, throwing an error:
Caused by: java.lang.ClassNotFoundException: ${APPENDER_CLASS:-ch.qos.logback.core.ConsoleAppender}
Is there any particular reason for this behaviour?
It is tempting to "fix" it by changing line #23 to
appenderModel.setClassName(interpretationContext(attributes.getValue(CLASS_ATTRIBUTE)));
However, it doesn't seem to be a correct fix, as SaxEventInterpretationContext interpretationContext
seems to not be used at all
Pull request #671 allows the system environment or a JNDI variable to choose an alternate ContextSelector. This allows the use of JEE deployment descriptors to choose an alternative selector. Consider two JEE applications deployed in the same container that want to use different selectors. This very trivial code update enables this capability
Why is in this class action only created, but addRule is commented in version 1.4.11 ch.qos.logback.core.joran.spi.SimpleRuleStore#addRule(ch.qos.logback.core.joran.spi.ElementSelector, java.lang.String)
we are not able to use censoring from com.tersesystems.logback:logback-censor because line below in our logback is basicaly useless
<newRule pattern="*/censor" actionClass="com.tersesystems.logback.censor.CensorAction"/>
the problem is that ch.qos.logback.core.joran.action.NewRuleAction#begin
on line 51 is calling old ec.getSaxEventInterpreter().getRuleStore().addRule(new ElementSelector(pattern), actionClass);
addRule method which have commented line on addRule() after initialization of new action
To upgrade logback to 1.4.11 in the Micronaut Framework, we had to add the following GraalVM Configuration Metadata via reflect-config.json
file:
[
{
"name": "ch.qos.logback.classic.joran.SerializedModelConfigurator",
"methods": [
{
"name": "<init>",
"parameterTypes": [
]
}
]
},
{
"name": "ch.qos.logback.classic.util.DefaultJoranConfigurator",
"methods": [
{
"name": "<init>",
"parameterTypes": [
]
}
]
}
]
It would be best if Logback could include this reflect-config.json directly so that everyone using logback could have a smooth GraalVM experience. Would you be interested in such a contribution?
Hi,
Starting with logback-classic version 1.4.9, I have the following error:
java.lang.NullPointerException: Cannot invoke "java.lang.ClassLoader.loadClass(String)" because "classLoader" is null
at ch.qos.logback.classic.util.ContextInitializer.instantiateConfiguratorByClassName(ContextInitializer.java:104)
at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:94)
at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:65)
at ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:52)
at ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:41)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:195)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:182)
at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:490)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:476)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:425)
This error happens because the jdk specifies that getClassLoader() may return null when the class is loaded from the bootstrap classloader. See here.
Unfortunately, since the commit LOGABCK-1717, autoConfig() will throw a NullPointerException when getClassLoader() returns null. The same code is working fine with version 1.4.8 and below.
Jetty 12 has been released July 20, 2023 and it is the latest stable release of Jetty: https://projects.eclipse.org/projects/rt.jetty/releases/12.0 . There has been quite many changes in Jetty 12 compared to earlier versions. One of the biggest change is probably "The Servlet-Api has been removed from the internals of Jetty allowing for non-servlet-based application creation."
These changes in Jetty 12 seems to make logback access logging not to work at all when using Jetty 12. At least I don't get any errors or stacktraces in logs but it just silently does not work. I am assuming that the problem might be in the log method of logback's RequestLogImpl:
public void log(Request jettyRequest, Response jettyResponse) {
JettyServerAdapter adapter = makeJettyServerAdapter(jettyRequest, jettyResponse);
IAccessEvent accessEvent = new AccessEvent(this, jettyRequest, jettyResponse, adapter);
if (getFilterChainDecision(accessEvent) == FilterReply.DENY) {
return;
}
aai.appendLoopOnAppenders(accessEvent);
}
So in the log method parameters it takes org.eclipse.jetty.server.Request
and passes that to the constructor of AccessEvent
which assumes that the request should implement jakarta.servlet.http.HttpServletRequest
. This has worked just fine with Jetty 10 and 11. But the case in Jetty 12 is that due to the big change mentioned above, org.eclipse.jetty.server.Request
no longer implements jakarta.servlet.http.HttpServletRequest
.
In Jetty 10 and 11, Request class is defined as public class Request implements HttpServletRequest
: https://github.com/jetty/jetty.project/blob/jetty-10.0.x/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java#L145
In Jetty 12, Request class is defined as public interface Request extends Attributes, Content.Source
: https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java#L122
So my guess is that the access logging most likely silently breaks due to this problem and should somehow be able to change org.eclipse.jetty.server.Request
-> jakarta.servlet.http.HttpServletRequest
or make AccessEvent
to accept org.eclipse.jetty.server.Request
or some other better solution. Same problem is of course with the jettyResponse
object.
Also package structure has changed in Jetty 12 a bit: https://webtide.com/new-jetty-12-maven-coordinates/ but not sure if this package structure change has any impact on logback since logback does not seem to reference classes in org.eclipse.jetty.eeX
packages but only org.eclipse.jetty.server.*
.
There is org.eclipse.jetty.ee9.nested.Request
in Jetty 12 which implements HttpServletRequest
but using that is probably not an option to use since it seems to be Jetty internal class and would then depend on the org.eclipse.jetty.eeX
packages.
There has been some plans that Jetty 10 and 11 will probably reach end of life in couple of years, possibly in 2025, so would be good time to start preparing logback to also work with Jetty 12.
You can see my reactor thread is waiting for the logger.error method.
The full thread stack is in the added file.
stack1.txt
the jcmd thread dump info(jcmd Thread.dump_to_file ):
thread_jcmdaa.txt
thread_jcmdab.txt
"ts-reactor-0" #47 [693] prio=5 os_prio=0 cpu=195123.31ms elapsed=69926.73s tid=0x00007fbc7a0daf10 nid=693 waiting on condition [0x00007fbc4cebf000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21/Native Method)
- parking to wait for <0x0000000759b899e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@21/LockSupport.java:371)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21/AbstractQueuedSynchronizer.java:519)
at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21/ForkJoinPool.java:3780)
at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21/ForkJoinPool.java:3725)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21/AbstractQueuedSynchronizer.java:1707)
at java.util.concurrent.ArrayBlockingQueue.put(java.base@21/ArrayBlockingQueue.java:370)
at ch.qos.logback.core.AsyncAppenderBase.putUninterruptibly(AsyncAppenderBase.java:186)
at ch.qos.logback.core.AsyncAppenderBase.put(AsyncAppenderBase.java:177)
at ch.qos.logback.core.AsyncAppenderBase.append(AsyncAppenderBase.java:166)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:85)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:426)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:386)
at ch.qos.logback.classic.Logger.error(Logger.java:539)
at com.huya.taf.net.core.nio.TCPSession.handleVtServer(TCPSession.java:218)
at com.huya.taf.net.core.nio.TCPSession.readRequest(TCPSession.java:177)
at com.huya.taf.net.core.nio.TCPSession.read(TCPSession.java:140)
at com.huya.taf.net.core.nio.TCPAcceptor.handleReadEvent(TCPAcceptor.java:111)
at com.huya.taf.net.core.nio.Reactor.dispatchEvent(Reactor.java:197)
at com.huya.taf.net.core.nio.Reactor.run(Reactor.java:114)
"ts-reactor-1" #48 [694] prio=5 os_prio=0 cpu=223469.95ms elapsed=69926.73s tid=0x00007fbc7a0eda90 nid=694 waiting on condition [0x00007fbc4ce7e000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21/Native Method)
- parking to wait for <0x0000000759b899e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@21/LockSupport.java:371)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21/AbstractQueuedSynchronizer.java:519)
at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21/ForkJoinPool.java:3780)
at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21/ForkJoinPool.java:3725)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21/AbstractQueuedSynchronizer.java:1707)
at java.util.concurrent.ArrayBlockingQueue.put(java.base@21/ArrayBlockingQueue.java:370)
at ch.qos.logback.core.AsyncAppenderBase.putUninterruptibly(AsyncAppenderBase.java:186)
at ch.qos.logback.core.AsyncAppenderBase.put(AsyncAppenderBase.java:177)
at ch.qos.logback.core.AsyncAppenderBase.append(AsyncAppenderBase.java:166)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:85)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:426)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:386)
at ch.qos.logback.classic.Logger.error(Logger.java:539)
at com.huya.taf.net.core.nio.Reactor.disConnectWithException(Reactor.java:144)
at com.huya.taf.net.core.nio.Reactor.run(Reactor.java:117)
"ts-reactor-2" #49 [695] prio=5 os_prio=0 cpu=196075.69ms elapsed=69926.73s tid=0x00007fbc7a0eec00 nid=695 waiting on condition [0x00007fbc4ce3d000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21/Native Method)
- parking to wait for <0x0000000759b895b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@21/LockSupport.java:221)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21/AbstractQueuedSynchronizer.java:754)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21/AbstractQueuedSynchronizer.java:990)
at java.util.concurrent.locks.ReentrantLock$Sync.lock(java.base@21/ReentrantLock.java:153)
at java.util.concurrent.locks.ReentrantLock.lock(java.base@21/ReentrantLock.java:322)
at java.util.concurrent.ArrayBlockingQueue.remainingCapacity(java.base@21/ArrayBlockingQueue.java:485)
at ch.qos.logback.core.AsyncAppenderBase.isQueueBelowDiscardingThreshold(AsyncAppenderBase.java:170)
at ch.qos.logback.core.AsyncAppenderBase.append(AsyncAppenderBase.java:162)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:85)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:426)
at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:419)
at ch.qos.logback.classic.Logger.info(Logger.java:592)
at com.huya.taf.net.core.nio.TCPSession.handleVtServer(TCPSession.java:208)
at com.huya.taf.net.core.nio.TCPSession.readRequest(TCPSession.java:177)
at com.huya.taf.net.core.nio.TCPSession.read(TCPSession.java:140)
at com.huya.taf.net.core.nio.TCPAcceptor.handleReadEvent(TCPAcceptor.java:111)
at com.huya.taf.net.core.nio.Reactor.dispatchEvent(Reactor.java:197)
at com.huya.taf.net.core.nio.Reactor.run(Reactor.java:114)
"ts-reactor-3" #50 [696] prio=5 os_prio=0 cpu=194924.27ms elapsed=69926.73s tid=0x00007fbc7a0f0020 nid=696 waiting on condition [0x00007fbc4cdfc000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21/Native Method)
- parking to wait for <0x0000000759b899e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@21/LockSupport.java:371)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21/AbstractQueuedSynchronizer.java:519)
at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21/ForkJoinPool.java:3780)
at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21/ForkJoinPool.java:3725)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21/AbstractQueuedSynchronizer.java:1707)
at java.util.concurrent.ArrayBlockingQueue.put(java.base@21/ArrayBlockingQueue.java:370)
at ch.qos.logback.core.AsyncAppenderBase.putUninterruptibly(AsyncAppenderBase.java:186)
at ch.qos.logback.core.AsyncAppenderBase.put(AsyncAppenderBase.java:177)
at ch.qos.logback.core.AsyncAppenderBase.append(AsyncAppenderBase.java:166)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:85)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:426)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:386)
at ch.qos.logback.classic.Logger.error(Logger.java:539)
at com.huya.taf.net.core.nio.TCPSession.handleVtServer(TCPSession.java:218)
at com.huya.taf.net.core.nio.TCPSession.readRequest(TCPSession.java:177)
at com.huya.taf.net.core.nio.TCPSession.read(TCPSession.java:140)
at com.huya.taf.net.core.nio.TCPAcceptor.handleReadEvent(TCPAcceptor.java:111)
at com.huya.taf.net.core.nio.Reactor.dispatchEvent(Reactor.java:197)
at com.huya.taf.net.core.nio.Reactor.run(Reactor.java:114)
"ts-reactor-4" #51 [697] prio=5 os_prio=0 cpu=194829.49ms elapsed=69926.73s tid=0x00007fbc7a0f15b0 nid=697 waiting on condition [0x00007fbc4cdbb000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21/Native Method)
- parking to wait for <0x0000000759b899e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base@21/LockSupport.java:371)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21/AbstractQueuedSynchronizer.java:519)
at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21/ForkJoinPool.java:3780)
at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21/ForkJoinPool.java:3725)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21/AbstractQueuedSynchronizer.java:1707)
at java.util.concurrent.ArrayBlockingQueue.put(java.base@21/ArrayBlockingQueue.java:370)
at ch.qos.logback.core.AsyncAppenderBase.putUninterruptibly(AsyncAppenderBase.java:186)
at ch.qos.logback.core.AsyncAppenderBase.put(AsyncAppenderBase.java:177)
at ch.qos.logback.core.AsyncAppenderBase.append(AsyncAppenderBase.java:166)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:85)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:272)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:259)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:426)
at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:419)
at ch.qos.logback.classic.Logger.info(Logger.java:592)
at com.huya.taf.net.core.nio.TCPSession.handleVtServer(TCPSession.java:208)
at com.huya.taf.net.core.nio.TCPSession.readRequest(TCPSession.java:177)
at com.huya.taf.net.core.nio.TCPSession.read(TCPSession.java:140)
at com.huya.taf.net.core.nio.TCPAcceptor.handleReadEvent(TCPAcceptor.java:111)
at com.huya.taf.net.core.nio.Reactor.dispatchEvent(Reactor.java:197)
at com.huya.taf.net.core.nio.Reactor.run(Reactor.java:114)
Denial of service vulnerability in logback-core was discovered by CIFuzz. Method new CyclicBuffer(int) and CyclicBuffer.resize(int) can receive a too big number which can lead to OOM.
pom
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>
code1
CyclicBuffer cyc = new CyclicBuffer(1611270666);
code2
CyclicBuffer cyc = new CyclicBuffer(123);
cyc.resize(1611270666);
Hello,
I have used scan="true" and scanPeriod =1 minute in logback configuration file. Still it is not taking up the changes done in configuration file at runtime.Always need to restart application.
logback-classic version : 1.2.6
logback-core version : 1.2.6
how can i use SyslogAppender by tcp protocol?
Hi all,
I had the below logback xml in old 1.2 version and it works fine.
But when I upgrade to logback 1.4 , it starts to not working.
I guess it is related to nested Appender which is not allowed anymore.
However I cannot move out some Appender as the name is base on the category id.
Is it intended to not support below anymore? any workaround .
Very thanks you for any suggestion
the below have warning
As of logback version 1.3, nested appenders are not allowed.
<appender class="ch.qos.logback.classic.sift.SiftingAppender" name="SwiftGH">
<discriminator>
<defaultValue>unknown</defaultValue>
<key>category</key>
</discriminator>
<sift>
<appender class="ch.qos.logback.classic.AsyncAppender" name="async-${category}">
<appender class="ch.qos.logback.core.FileAppender" name="logss-${category}">
<append>true</append>
<file>chat-${category}.log</file>
</appender>
</appender>
</sift>
</appender>
In My Spring 6 example, when upgrading to 1.4.13, it failed the tests run on Github actions.
0.040 s <<< ERROR!
java.lang.NoSuchMethodError: 'java.lang.ClassLoader ch.qos.logback.core.util.Loader.systemClassloaderIfNull(java.lang.ClassLoader)'
at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:73)
at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:66)
at ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:52)
at ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:41)
Originally published in the Logback-Dev Mailing list:
I refer to commit dd2b9fe that enabled
the Context interface to handle a ConfigurationEvent.
Currently, there is only a method to register a
ConfigurationEventListener. It would be useful to have another method to
deregister such a listener. What's more, the current source describes
the registration method as follows:
"The propagation of {@link ConfigurationEvent configuration events} is
intended for internal testing as well as some coordination between
configurators."
I believe a ConfigurationEvent is generally useful. The documentation
should acknowledge that.
BACKGROUND
I use Logback in a Spring web application and need to register
LoggingEvent filter beans programmatically. This requires to hook into
Spring's lifecycle and to perform registration / deregistration on bean
initialization and destruction. Special attention needs to be taken to
Logback's configuration reload. In this case I need to hook into
ReconfigureOnChangeTask to realize when reload has ended since all
filter beans need to be registered again. This can be performed with the
help of listeners, all of which have some drawbacks:
Pull request #634 simply adds a try-catch block around the selector initialization so that if a custom selector throws an exception, logback will continue with the default selector instead of throwing an exception back to the container and failing
Hello, we are facing the same issue mentioned in https://jira.qos.ch/browse/LOGBACK-1731 and we hoped, it will be fixed in 1.4.12 (as it is listed in fix-versions)
It seems that there was a change in when we migrated from 1.2 to 1.4
Using scope="system"
seems to work in spring.
It seems that there is some logical order problem
As far as I could debug the issue, logback builds a "Model" which represents the complete config (with all included files)
and then, the properties are evolved. So due this order problem, it is not possible to use parameters in include
tags. (Note: I'm not very familiar with the architecture in logback, so this is just a guess, what I've ssen in debugger)
When you apply scope="system"
- logback puts the value in the system-properties. As spring reloads the logback config at least once, the next run can access the value from the previous run.
Note: we do not really rely on this issue if our use cases could be solved in an other way
Preferred solution:
<property file="config/application-local.properties" optional="true"/>
This does not work, because there is no optional
support for property
and the produced error will prevent spring to run the application
Current solution:
<!-- We define a property, that evaluates to "true", if the file exists -->
<define name="APPLICATION_LOCAL_EXISTS" class="ch.qos.logback.core.property.FileExistsPropertyDefiner" scope="system">
<path>config/application-local.properties</path>
</define>
<!-- if file exists, we include application-local.properties-true.inc.xml.
If the property file does not exist, no XML is found.
This works, because 'include' supports 'optional=true' -->
<include resource="logback/application-local.properties-${APPLICATION_LOCAL_EXISTS}.inc.xml" optional="true"/>
<!-- content of application-local.properties-true.inc.xml -->
<included>
<property file="config/application-local.properties"/>
</included>
Yes this is a workaround, and I'm sure it was not intended to use it this way, but it did work with 1.2
possible fix
Add 'optional' to 'property'
<property name="consoleAppender" value="${de.foconis.log.console.appender:-CONSOLE}" scope="system"/>
<root>
<appender-ref ref="${consoleAppender}"/>
</root>
By default we want to use the CONSOLE
appender, we have also other appenders like CONSOLE_ANSI
, CONSOLE_JSON
which formats the output to console in a different way.
If we put all appenders "ready for use" in the logback.xml we get warnings like Appender named [CONSOLE_ANSI] not referenced. Skipping further processing.
- so we split them up into a CONSOLE.appender.inc.xml, CONSOLE_ANSI.appender.inc.xml, CONSOLE_JSON.inc.xml and include the dedicated file with
<include optional="true" resource="logback/${consoleAppender}.appender.inc.xml"/>
possible fix
Add 'optionalUse' to 'appender'. If this is set, no warnings are printed, if appender is not in use.
Logback 1.4.12 has a small issue. It prints “default THREAD FACTORY” to System.out
. When looking at the diff between 1.4.11 and 1.4.12 it's immediately showing up as a simple System.out.println
.
Here's the diff between 1.4.11 and 1.4.12:
Problem is in the file logback-core/src/main/java/ch/qos/logback/core/util/ExecutorServiceUtil.java
.
In fact it prints to System.out in 2 places inside the makeThreadFactory
method:
if(EnvUtil.isJDK21OrHigher()) {
// ...
System.out.println("virtual THREAD FACTORY");
// ...
} else {
System.out.println("default THREAD FACTORY");
// ...
}
Starting from version 1.4.8 of Logback, an issue has been observed where MDC properties are no longer associated with log statements when a custom MDCAdapter
, for instance com.twitter.inject.logging.FinagleMDCAdapter
, is set in the application.
The likely root cause is that, beginning with version 1.4.8, Logback obtains the MDCAdapter
from ch.qos.logback.classic.LoggerContext
instead of directly getting it from MDC. Consequently, the application ends up using two separate and independent MDCAdapters concurrently.
You can find a simplified application created to reproduce this issue in the following repository:
https://github.com/naser-ayat/logback-bug-reproducer
Hi Team,
In our recent rollout, we had a bug in code, which started generating a very high volume of logs and we are expecting logback to remove old logs and keep the storage space in control.
However this was not the case, log files were not removed and storage was filling and bringing the entire appliance to a halt.
log back config:
maxHistory: 2
maxFileSize: 25MB
totalSizeCap: 75MB
Logs generated per sec: 25MB(1.5 GB per minute/ 1 million lines per minute)
Max file size: 25MB, so every second one log file is generated.
Max CAP size: 75MB
within 3 sec the MAX cap is met.
Storage available is 24 GB.
The time taken to fill up the storage is 16Min(1.5 GB per minute generation rate)
I can see logs are successfully written into files but old files are not deleted.
The expectation here is that logback has to clean up old files every 3 seconds to keep up with config and maintain storage. I am not sure this functionality working.
and I need below info if some can help me:
Below are config we used
`
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_PATTERN}</pattern>
</encoder>
</appender>
<appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>10000</queueSize>
<appender-ref ref="STDOUT"/>
<includeCallerData>true</includeCallerData>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/spring.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_DIR}/spring-%d{yyyyMMdd}.%i.log</FileNamePattern>
<maxHistory>2</maxHistory>
<maxFileSize>25MB</maxFileSize>
<totalSizeCap>75MB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_PATTERN}</pattern>
</encoder>
</appender>
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>10000</queueSize>
<appender-ref ref="FILE"/>
<includeCallerData>true</includeCallerData>
</appender>
<logger name="org.springframework.scheduling.support.TaskUtils" level="OFF"/>
<logger name="io.jaegertracing.internal" level="OFF"/>
<logger name="org.apache.ignite.internal" level="OFF"/>
<logger name="org.springframework.web.client" level="OFF"/>
<root level="${SERVICE_LOG_LEVEL}">
<appender-ref ref="ASYNC_STDOUT"/>
<appender-ref ref="ASYNC_FILE"/>
</root>
`
appender can't be added to AsyncAppender after being detached.
add following test in AsyncAppenderBaseTest
@Test
@Timeout(value=2, unit = TimeUnit.SECONDS)
public void appenderShouldBeAddedSuccessfullyAfterDetachedByReference() {
asyncAppenderBase.addAppender(listAppender);
asyncAppenderBase.start();
asyncAppenderBase.doAppend(0);
asyncAppenderBase.detachAppender(listAppender);
asyncAppenderBase.addAppender(listAppender);
asyncAppenderBase.doAppend(0);
asyncAppenderBase.stop();
verify(listAppender, 2);
}
the value of property "appenderCount" does't decrease in method "detachAppender", the value is 1 after first addAppender, and still 1 after detachAppender, so when addAppender again, it goes into "else".
public void addAppender(Appender<E> newAppender) {
if (appenderCount == 0) {
appenderCount++;
addInfo("Attaching appender named [" + newAppender.getName() + "] to AsyncAppender.");
aai.addAppender(newAppender);
} else {
addWarn("One and only one appender may be attached to AsyncAppender.");
addWarn("Ignoring additional appender named [" + newAppender.getName() + "]");
}
}
Given the project already supports printing the current thread name, it should also be able to retrieve the threadId
.
This would be useful when dealing with virtual threads, I noticed that ones created via Executors.newVirtualThreadPerTaskExecutor()
don't have a name and they would be shown as an empty string:
Unless I'm missing something obvious, there's no easy way to serialize the Logback model to scmo
file.
One way to do that is to include <serializeModel file="...">
into XML config. When Logback runs such a configuration, it'll serialize itself into the given file. Two problems here. First, it's not very convenient to get a serialized model only when the app starts, especially when maintaining shared configuration, meaning there's no app to start to begin with. Second, the serialized model contains a model to serialize itself, so every time the app starts, it creates a new scmo file.
It would be so much better if there was a CLI tool that users could point to XML files and get SCMO files as an output.
Add ability to delete logs based of last modified date instead of looping up-to a capped time window, such as 14 days for hourly date specifier.
Investigate and implement support for virtual threads introduced in JDK 21.
Java documentation states:
Virtual threads are lightweight threads that reduce the effort of writing, maintaining, and debugging high-throughput concurrent applications.
Two difficulties were encountered while adding virtual threads in logback.
First, while Multi-Release Jar files make it easy to support JDK version dependent code in projects, support for support for Multi-Release jar files in IDEs when combined with build tools is lacking (as of 2023-11-25). When the Multi-Release path seemed blocked, the project reverted to the old practice of adding support via reflection.
Second, virtual threads are meant to be used for tasks which spend most of their time waiting for blocking I/O operations. Thus virtual threads are meant to reduce resource consumption which is not easy to measure and requires good judgement.
Hello everyone,
we just realized that logback behaves differently when handling the inclusion of files that use properties.
This different behavior was introduced with version 1.3.0 and its changes to the configuration implementation.
I'm not sure whether this is actually a bug. Perhaps we relied on something that was never intended to work.
We want to include a configuration snippet multiple times and use properties to slightly change the snippet every time.
A very simple example is an appender definition with a name derived from a property:
<included>
<appender name="${name}" class="ch.qos.logback.core.ConsoleAppender">
<!-- ... -->
</appender>
</included>
Now we want to include this snippet to create appenders with different names:
<property name="name" value="A" />
<include resource="snippet.xml"/>
<property name="name" value="B" />
<include resource="snippet.xml"/>
Thus, we want to pass parameters to the snippet.
This works fine with version 1.2.12.
Here's the status log:
09:45:03,179 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@566776ad - Adding [file://snippet.xml] to configuration watch list.
09:45:03,180 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
09:45:03,182 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [A]
09:45:03,203 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@566776ad - Adding [file://snippet.xml] to configuration watch list.
09:45:03,205 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
09:45:03,205 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [B]
This doesn't work anymore since version 1.3.0. It doesn't work with 1.4.11 neither.
The properties value is always B (as seen by the included snippets).
10:12:35,409 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@7b49cea0 - Adding [file:///snippet.xml] to configuration watch list.
10:12:35,413 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@7b49cea0 - Adding [file:///snippet.xml] to configuration watch list.
10:12:35,458 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [B]
10:12:35,458 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
10:12:35,476 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [B]
10:12:35,477 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
In our real world use case the application does not start anymore, since logback detects the same file name pattern to be used multiple times.
Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.
The file name pattern is defined by a property. The file appenders are included with a snippet.
There is an open feature request to support passing of parameters to included snippets in a different way: https://jira.qos.ch/browse/LOGBACK-1104
If this is not considered a bug, I vote for this feature request.
https://jira.qos.ch/browse/LOGBACK-1760 might be related, even though the variable is used in the <include>
tag not in the included snippet.
Since this ticket states 1.4.12 as fix version, I tried our use case with the 1.4.12-SNAPSHOT but it doesn't work.
Thank you for your support!
Pull request #635 allow subclasses to do post-create operations on new Logger instances by providing a no-op method that can be overridden for apps that want to further customize the logger instances
Hello. Is there any way to gather metrics on the internal queue used by async logger? Things like current capacity, nb of info logs dropped, nb of logs dropped when full, etc.
If not available would that be an interesting contribution?
Thanks.
Hi Logback team / @ceki ! 👋
We still work with Dropwizard 2.1 which still relies on Logback 1.2. Do you have any plans to backport your fix to prevent the DOS attack that is already applied to the 1.3 and 1.4 branches? That would be greatly appreciated! 🌻
Cheers,
Christopher
Denial of service vulnerability in logback-core was discovered by CIFuzz. Method new CyclicBuffer(int) and CyclicBuffer.resize(int) can receive a too big number which can lead to OOM.
pom
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>
code1
CyclicBuffer cyc = new CyclicBuffer(1611270666);
code2
CyclicBuffer cyc = new CyclicBuffer(123);
cyc.resize(1611270666);
While updating from Logback 1.4.8 to 1.4.11, he hit the removal of this deprecated method ContextInitializer::configureByResource
.
Does logback follow semantic versioning? Are breaking changes expected in patch releases?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.