I need to rotate my log file every day by zipping it and creating another one, the problem is that when the rotation of the log ocours, it doesn't create an new empty log file, it zips what happended in the previous day but doesn't create a new file, it keeps all the information. Here is my log4j.xml configuration:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<jmxConfigurator/>
<appender class="ch.qos.logback.core.ConsoleAppender" name="Console_Appender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</layout>
</appender>
<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="RollingFile_Appender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/opt/s4bconrmkissflow/log/console-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>200MB</maxFileSize>
<totalSizeCap>1GB</totalSizeCap>
<maxHistory>15</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger additivity="false" level="info" name="net.s4bdigital.intg.kissflow">
<appender-ref ref="Console_Appender"/>
<appender-ref ref="RollingFile_Appender"/>
</logger>
<logger additivity="false" level="error" name="org.apache.camel.processor.interceptor.Tracer">
<appender-ref ref="Console_Appender"/>
<appender-ref ref="RollingFile_Appender"/>
</logger>
<root level="error">
<appender-ref ref="Console_Appender"/>
<appender-ref ref="RollingFile_Appender"/>
</root>
</configuration>
By the way, I don't fully understand what the pattern that I'm using does, I got the %d,%t,%m and %n, but the others, no. So if you could explain me, I'd appreciate.
Related
I have tried the solution from Logback: how to log only errors to file
but it doesn't work for me:
What can be wrong with my logback.xml file?
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>ALL.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>ALL.%d{yyyy-ww}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>ERROR.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>ERROR.%d{yyyy-ww}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<root level="ERROR">
<appender-ref ref="FILE-ERROR" />
</root>
</configuration>
Then to files and console goes only ERRORs.
Is it because I log the errors with log4j?
I believe this part is what causes the issue:
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<root level="ERROR">
<appender-ref ref="FILE-ERROR" />
</root>
Here, we first set the level on root logger to INFO, attach two appenders to it, but then reassign the level to be ERROR and attach another appender.
Since you set the filter on FILE-ERROR appender, there’s no need to change the root’s level and you can attach all the appenders at once:
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
<appender-ref ref="FILE-ERROR" />
</root>
I'm setting up more complex logging then a simple console output. Logback writes logs really well via ConsoleAppender. But when I add extra RollbarAppender it does not work for it.
Here is an example of logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration >
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight([%level]) - [%date] - [%logger] %msg%n</pattern>
</encoder>
</appender>
<appender name="ROLLBAR" class="com.rollbar.logback.RollbarAppender">
<accessToken>VERY_SECRET_TOKEN</accessToken>
<encoder>
<pattern>%highlight([%level]) - [%date] - [%logger] %msg%n</pattern>
</encoder>
</appender>
<logger name="akka" level="ERROR" additivity="false">
<appender-ref ref="ROLLBAR" />
</logger>
<logger name="slick" level="ERROR"/>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
Meanwhile this configuration works fine and sends logs to the 3rd party logging service, but doesn't write to the console :(
<?xml version="1.0" encoding="UTF-8"?>
<configuration >
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight([%level]) - [%date] - [%logger] %msg%n</pattern>
</encoder>
</appender>
<appender name="ROLLBAR" class="com.rollbar.logback.RollbarAppender">
<accessToken>VERY_SECRET_TOKEN</accessToken>
<encoder>
<pattern>%highlight([%level]) - [%date] - [%logger] %msg%n</pattern>
</encoder>
</appender>
<logger name="akka" level="INFO" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="slick" level="ERROR"/>
<root level="ERROR">
<appender-ref ref="ROLLBAR" />
</root>
</configuration>
So I'm confused. How to make logback work in this way:
INFO level events write to the console
ERROR level events write to the console + ROLLBAR
The solution was pretty simple. <filter> tag solved the issue: Its logging level overrides logging level of the <root> tag
<appender name="RollBar" class="com.rollbar.logback.RollbarAppender">
<accessToken> VERY_SECRET_TOKEN </accessToken>
<environment>PROD</environment>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
...
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="RollBar" />
</root>
Say I have two Java classes: foo.ClassA and bar.ClassB. To print (root) exception stacktrace, I need to print only frames of foo package. My question is how exactly I can configure Logback to do that.
I know that the feature is already implemented in Logback, and I need to use evaluator. But I couldn't figure it out. I tried the example described here without success (no surprise).
Can anyone give the exact configuration for filtering stacktrace frames?
<configuration>
<evaluator name="FILTER">
<expression>¿what should I put here?</expression>
</evaluator>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%thread] %-5level - %msg%n%rEx{full, FILTER}</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
I contacted Tomasz Nurkiewicz (the author of the blog linked in the question) and he kindly answered my question. I'm posting the answer, just in case:
While printing stack trace, to filter lines from bar package use the following:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%thread] %-5level - %msg%n%rEx{full, bar}</pattern>
</encoder>
</appender>
...
</configuration>
I wanted to use it in my web application (Tomcat+Spring+Hibernate+etc). So I configured logback with the following not to print any stack trace line from org.something packages (e.g. org.apache, org.springframework, org.hibernate, etc):
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%thread] %-5level - %msg%n%rEx{full, org}</pattern>
</encoder>
</appender>
...
</configuration>
Thanks Tomasz!
This may help someone who is writing springboot apps like me
I am currently using
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" packagingData="true">
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProfile name="!cloud">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${APP_NAME} %green(%d{dd-MM-yyyy HH:mm:ss.SSS}) %magenta([%thread]) %highlight(%-5level) %red(%logger.%M:%L) - %magenta(%msg) %rEx{full,java.lang.reflect.Method,
org.apache.catalina,
org.apache.tomcat,
org.apache.coyote,
javax,
java.util.concurrent,
java.lang.Thread,
org.springframework.aop,
org.springframework.boot.actuate,
org.springframework.security,
org.springframework.transaction,
org.springframework.web,
sun.reflect,
net.sf.cglib,
ByCGLIB
}%n
</pattern>
</encoder>
</appender>
</springProfile>
<springProfile name="cloud">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- send cloud event in one line so kibana can log it as one event -->
<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger.%M:%L - %msg %replace(%rEx){'[\r\n]+', '\\n'}%nopex %n</pattern>
</encoder>
</appender>
</springProfile>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.aaa" level="DEBUG"/>
<logger name="org.springframework.web.filter" level="INFO"/>
<logger name="org.springframework.cloud" level="INFO"/>
<logger name="org.springframework.core.env" level="INFO"/>
<logger name="org.springframework.boot" level="INFO"/>
<logger name="org.springframework.boot.actuate" level="WARN"/>
<logger name="org.springframework.boot.context" level="INFO"/>
<logger name="org.springframework.boot.autoconfigure" level="INFO"/>
<logger name="io.lettuce.core.protocol" level="WARN"/>
I am using logback api and have a logback.xml in my classpath which looks like this
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<configuration scan="true">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<appender class="ch.qos.logback.core.ConsoleAppender" name="STDOUT">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="FILE">
<file>/${path}/logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>/${path}/logs/application.%i.log</fileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>50MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<!-- ~~~ PERFORMANCE TRACKING LOGGER CONFIGURATION (USING PERF4J) || END ||~~~
-->
<logger name="com.nucleus">
<level value="DEBUG"/>
<!-- <appender-ref ref="STDOUT" /> -->
<appender-ref ref="FILE"/>
</logger>
<logger level="DEBUG" name="org.hibernate.transaction.JDBCTransaction"/>
<logger level="DEBUG" name="org.hibernate.jdbc.ConnectionManager"/>
<logger level="DEBUG" name="org.springframework.orm.jpa.JpaTransactionManager"/>
<!-- <root level="info">
<appender-ref ref="FILE" />
</root> -->
</configuration>
Now the rollback that i have implemented is not working in the production environment only. I wish to debug the same and hence want to put a trace for this logback api. Can anyone suggest what i might be doing wrong or what should i do to resolve this issue?
From Logback 1.0.4 you can use system property -Dlogback.debug=true to enable debugging of your Logback setup which will allow you to debug your configuration.
I am using logback/slf4j to do my logging. I want to parse my log file to analyze some data, so instead of parsing a great big file (mostly consisting of debug statements) I want to have two logger instances which each log to a separate file; one for analytics and one for all purpose logging. Does anyone know if this is possible with Logback, or any other logger for that matter?
It's very possible to do something like this in logback. Here's an example configuration:
<?xml version="1.0"?>
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logfile.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<appender name="ANALYTICS-FILE" class="ch.qos.logback.core.FileAppender">
<file>analytics.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<!-- additivity=false ensures analytics data only goes to the analytics log -->
<logger name="analytics" level="DEBUG" additivity="false">
<appender-ref ref="ANALYTICS-FILE"/>
</logger>
<root>
<appender-ref ref="FILE"/>
</root>
</configuration>
Then you'd setup two separate loggers, one for everything and one to log analytics data like so:
Logger analytics = LoggerFactory.getLogger("analytics");
You can have as many loggers as you wish. But, it's better you have one for each package that you need to log differently. Then all the classes in that package and its sub-packages will get the that specific logger. They all can share the root logger and send their log data to root logger appender using additivity="true". Here's an example:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="pattern" value="%date{HH:mm:ss.SSS} %-5p %logger{36}
%X{akkaSource} [%file:%line] - %m%n" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{HH:mm:ss.SSS} %-5p %logger{36} %X{akkaSource} [%file:%line] - %m%n</pattern>
</encoder>
</appender>
<appender name="abc" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.base}/logs/worker.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.base}/logs/worker-%d{yyyy-MM-dd_HH}.log</fileNamePattern>
<maxHistory>360</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${pattern}</pattern>
</encoder>
</appender>
<appender name="xyz" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.base}/logs/transformer.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.base}/logs/transformer-%d{yyyy-MM-dd_HH}.log</fileNamePattern>
<maxHistory>360</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${pattern}</pattern>
</encoder>
</appender>
<logger name="com.xxx.yyy.zzz" level="INFO" additivity="true">
<appender-ref ref="xyz"/>
</logger>
<logger name="com.aaa.bbb.ccc" level="INFO" additivity="true">
<appender-ref ref="abc"/>
</logger>
<root>
<level value="INFO" />
<appender-ref ref="STDOUT" />
</root>
in my case I wanted to leave class names as log name
private static final Logger log = LoggerFactory.getLogger(ScheduledPost.class);
and as I had few such classes, so my logback.xml
<!--additivity=false ensures this log data only goes to the this log, and no one more -->
<logger name="xxx.xxx.xxx.ScheduledPost" level="DEBUG" additivity="false">
<appender-ref ref="ASYNC_SCHEDULE_LOG_FILE"/>
</logger>
<logger name="xxx.xxx.xxx.GcmPost" level="DEBUG" additivity="false">
<appender-ref ref="ASYNC_SCHEDULE_LOG_FILE"/>
</logger>
<logger name="xxx.xxx.xxx.PushUtils" level="DEBUG" additivity="false">
<appender-ref ref="ASYNC_SCHEDULE_LOG_FILE"/>
</logger>