This question already has answers here:
Logback logger logging twice
(3 answers)
Closed 6 years ago.
In my application, I would like to log some messages coming from my own code in a specific manner compared to all other messages being logged. However I am not sure how can I avoid them also being automatically logged to the logack root logger.
Using this configuration below, I would like to use code like follows (scala) so that I can log certain messages only to that logger.
val logger: Logger = LoggerFactory.getLogger("data-logger")
However in the configuration below, these messages get logged twice, i.e. they are logged also by the root logger. How can I avoid that? must I quite artificially use a different logging level to accomplish something like that with logback?
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/activity.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>activity.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- use discarding threshold of zero to avoid ignoring INFO level messages see docs -->
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="FILE" />
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="ASYNC" />
</root>
<logger name="data-logger" level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="ASYNC" />
</logger>
</configuration>
Loggers are hierarchical, and any message sent to a logger will be sent to all its ancestors by default. You can disable this behavior by setting additivity=false. E.g.:
<logger name="data-logger" level="info" additivity="false">
Related
Here is the log config for reference. I have set the log level to be ERROR but I see TRACE, INFO, DEBUG logs as well in the log file.
<configuration>
<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
<Marker>TraceMarker</Marker>
<OnMatch>ACCEPT</OnMatch>
</turboFilter>
<appender name="NAME" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/file/path</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{HH:mm:ss} [%thread] %highlight(%-5level) %cyan(%logger{35}) - [%marker] %msg %n</pattern>
</layout>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>/Some/Pattern</FileNamePattern>
<MaxHistory>240</MaxHistory>
<maxFileSize>500MB</maxFileSize>
</rollingPolicy>
</appender>
<root level="ERROR">
<appender-ref ref="NAME" />
</root>
<logger name="com.sample.service" level="ERROR" additivity="false">
<appender-ref ref="NAME" />
</logger>
Try setting the root log level to 'info', then clean build your application and then run. Sometimes, it happens old log file is getting used during application run.
This table might be helpful to you-
Log Level- Going down the first column, you will see how the log works in each level. i.e for WARN, (FATAL, ERROR and WARN) will be visible. For OFF, nothing will be visible.
I'm trying to get separate log file based on log levels, for eg. separate file for debug, info, error
My current configuration in application.properties file only keeps in single file, per date
logging.file=myservice-%d{yyyyMMdd}.log
logging.level.org.springframework.boot=DEBUG
logging.level.org.springframework.web=DEBUG
I want separate log files created as
myservice-info-20190516.log
myservice-debug-20190516.log
myservice-error-20190516.log
You can easily do that with Logback. You can create different appenders for each log level and you're done.
Using the recommended and default implementation Logback of the SLF4J façade, you need to configure appender for each level of the log.
<appender name="debugAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>debug-%d{yyyy-MM-dd_HH}.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>info-%d{yyyy-MM-dd_HH}.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>error-%d{yyyy-MM-dd_HH}.log</fileNamePattern>
</rollingPolicy>
</appender>
And attach them to the logger distinguished by the level:
<logger name="com.bla" level="DEBUG" additivity="true">
<appender-ref ref="debugAppender"/>
</logger>
<logger name="com.bla" level="INFO" additivity="true">
<appender-ref ref="infoAppender"/>
</logger>
<logger name="com.bla" level="ERROR" additivity="true">
<appender-ref ref="errorAppender"/>
</logger>
I am using the logback as implementation with SL4j interface. Here is the configuration
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/prod.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>logs/prod.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>700MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="com.ecom" additivity="false" level="ERROR">
<appender-ref ref="FILE" />
</logger>
I want to change the level to Info or debug at runtime through configuration or external property change in production without restarting the server. Is it possible ?
FYI ,I am using Weblogic as application server and also Spring frameworks for other purposes >
What you can try is to include another file (outside your webapp) that overrides the config in your logback.xml.
<configuration scan="true" scanPeriod="30 seconds">
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/prod.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>logs/prod.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>700MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="com.ecom" additivity="false" level="ERROR">
<appender-ref ref="FILE" />
</logger>
<include optional="true" file="/tmp/logbackDynamic.xml"/>
</configuration>
Then your /tmp/logbackDynamic.xml could look like this if you want DEBUG loggings for com.ecom.SomeClass
<included>
<logger name="com.ecom.SomeClass" level="DEBUG">
<appender-ref ref="FILE" />
</logger>
</included>
Now Logback will check every 30 seconds if you changed your config in /tmp/logbackDynamic.xml, and reload it. If you want to return the original log level, just remove the line between the tags and Logback will ignore the DEBUG level. You could even delete the file because of optional="true".
There are two ways to externalize the logger level
One at with system level property i.e. java -Dlogback.configurationFile=/pathToconfig.xml. See How to externalize the log level
<root level="${log.level:-Error}">. Then set the system level property -Dlog.level=DEBUG
Variable substitution is your friend here. Default values for variables should be helpful as well.
See also variable scoping.
I've been using Logback Groovy configuration, and now I found out that it's the cause of very slow startup. A HelloWorld "application" needs about one second. I didn't notice the slowdown earlier in the context of web server, but now when I often need to run some rather simple tools, it's unacceptable.
Q1: I still can't believe it, as my configuration file is small and one second is huge, so can someone confirm it?
I can imagine to easily rewrite everything but one part back to XML. The problematic part is my own filter and its two methods like
public class MyLogbackFilter extends Filter<ILoggingEvent> {
public MyLogbackFilter accept(String prefix, Level level) {...}
public MyLogbackFilter accept(String prefix, Level level) {...}
...
}
configured via something like
filter = new MyLogbackFilter()
.accept("com.example.pck1.Class1", TRACE)
.accept("com.example.pck1.Class2", TRACE)
.deny("com.example.pck1", TRACE)
.accept("", WARNING)
.deny("", INFO);
The rules get evaluated top-down, e.g., everything from com.example.pck1.Class1 at level TRACE or higher gets accepted, no matter what's specified later.
Q2: Can I somehow make logback read a configuration file like
A com.example.pck1.Class1 TRACE
A com.example.pck1.Class2 TRACE
D com.example.pck1 TRACE
A * WARNING
D * INFO
and feed it to my class? The interpretation is then peanuts.
Sincerely, i never know you can make appenders by class, BUT You can just add an xml config file to your project, and the logback libraries tries to locate the xml in the classpath (usually, in maven you put the xml in the resources file).
The file can be like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/usr/java/logs/floresTrace.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>/path/to/file/myfile.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss} %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- you can, however add loggers by package here-->
<logger name="your.package.one" level="DEBUG">
<appender-ref ref="STDOUT" />
</logger>
<logger name="your.package.two" level="INFO">
<appender-ref ref="STDOUT" />
</logger>
<logger name="your.package.two" level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</logger>
<root level="debug">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
So, as the comment says, you can add loggers by package. hope this helps.
In Log4j it is easy to have different packages in your application being logged at different levels (this is especially useful for debugging). Is there an easy way of doing this other than creating your own filter?
I tried creating an tag within the root tag or after whose name is the package (ie reminiscent of Log4J) and then placed the appenders for it within but, but it didn't work.
So, is there a built in to LogBack way of defining loggers and/or logging levels for certain packages that does not require a custom filter implementation?
I'm using a Play! web app and have different log levels for different packages. You can specify the package in the name of the <logger> element.
My config is:
<configuration>
<conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${application.home}/logs/application.log</file>
<encoder>
<pattern>%date - [%level] - from %logger in %thread %n%message%n%xException%n</pattern>
</encoder>
</appender>
<appender name="TIMESTAMP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${application.home}/logs/batches/current.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" maxHistory="720">
<fileNamePattern>${application.home}/logs/batches/archived/%d{yyyy/MM/dd}.gz</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>{mpoplib} %date - [%level] in %thread %n%message%n%xException%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%coloredLevel %logger{15} - %message%n%xException{5}</pattern>
</encoder>
</appender>
<logger name="play" level="INFO">
<appender-ref ref="FILE"/>
</logger>
<logger name="application" level="INFO">
<appender-ref ref="FILE"/>
</logger>
<logger name="ru.kupikupon.mpoplib" level="DEBUG">
<appender-ref ref="TIMESTAMP_FILE"/>
</logger>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>