I'm developing an application with springboot which has an microservice architecture.
There is Service A (Port 8080) and spring cloud's config-server (Port 8888), which provides the properties-file for Service A from a Git-Repo (located locally under the ~/git//config).
This works well so far and Service A receive the properties-file from config-server.
For logging i use the logback logging framework and created a XML-Configuration file named logback-spring.xml with following content:
<?xml version="1.0" encoding="utf-8"?>
<property name="LOGS" value="./logs" />
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%highlight(%-5level) %black(%d{ISO8601}) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
</Pattern>
</layout>
</appender>
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
<logger name="com.example" level="trace" additivity="false">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</logger>
I want to distribute this configuration file to Service A by the config-server to have a central point to manage this for all future services.
Inside of the git-repo for config i created a directory named logging with that file inside. So the local path to that file is: ~/git//config/logging/logback-spring.xml.
Related to the docs(documentation of config server) in my case i can retrieve this file with curl localhost:8888/config/spring/main/logging/logback.xml and when i curl this i get the content from this file.
But now the problem:
I specified this logging.config - location to this endpoint to let springboot load this XML file as a config client. The application-properties in Service A has following content:
When i start Service A while hoping to get this configuration appended to the logs, i am getting following error:
How can i properly include the configuration to Service A?
Appreciate any help.
Related
I followed this tutorial to setup spring boot logging in my app and it work correctly in my development environment but not after I deploy the app.
The spring app log files should go to ${CATALINA_BASE}/logs/spring-boot-logger.log when app is deployed. How do I configure that?
My logback-spring.xml:
<property name="LOGS" value="./logs" />
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
</Pattern>
</layout>
</appender>
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
<!-- LOG "com.baeldung*" at TRACE level -->
<logger name="xxx.app" level="trace" additivity="false">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</logger>
When I start the app on the deployment server using this configuration I get:
java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[RollingFile] - Failed to create parent directories for [/./logs/spring-boot-logger.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[RollingFile] - openFile(./logs/spring-boot-logger.log,true) call failed. java.io.FileNotFoundException: ./logs/spring-
boot-logger.log (No such file or directory)
I also tried configuring logging.file.name = ${catalina.base}/logs/${service.name}.log in application.properties like suggested here but then I receive an error when running mvn clean install locally
[ERROR] contextLoads Time elapsed: 0.004 s <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'catalina.base' in value "${catalina.base}/logs/${service.name}.log"
You want to write your log file to the ${CATALINA_BASE}/logs directory, but you used ./logs in your configuration file. This would of course work if the working directory of your Tomcat server were ${CATALINA_BASE}, but it is unsafe to assume anything about the working directory of the Tomcat server (and in your case it's not ${CATALINA_BASE}).
Use variable substitution in your logback-spring.xml file:
<property name="LOGS" value="${catalina.base:-.}/logs" />
The default value . will be used when there is no catalina.base property (i.e. when you use the embedded Tomcat).
My logback.xml content is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_TEMP" value="${user.home}/logs/cloudcanal/console"/>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="PROJECT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<Key>module</Key>
<DefaultValue>console</DefaultValue>
</discriminator>
<sift>
<appender name="FILE-${module}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${user.home}/logs/cloudcanal/console/${module}.log</File>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${user.home}/logs/cloudcanal/console/%d{yyyy-MM-dd}/${module}-%d{yyyy-MM-dd}-%i.log.gz
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>512MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{56} - %msg%n
</pattern>
</encoder>
</appender>
</sift>
</appender>
<root level="info">
<appender-ref ref="PROJECT"/>
</root>
</configuration>
When I start springboot I find there exist two log file called console.log and spring.log whose content is the same. I check some document and know that spring.log is generated by springboot's file appender(file-appender.xml). Can I only use my own PROJECT appender?
New edited at 2020/11/30
What I really want to achieve is to rename the default spring.log
Can you try adding -
logging.config=logback.xml
on the property file (application.properties)
and see
I find the answer myself. Just using the following config in spring config properties or yaml file.
logging.file.name=console.log
I have a java package with specialized operations. Specialized in the sense that they are rarely used and i don't want to have them be mixed with normal logging.
I know that adding logging.file=myapplication.log will redirect the logging to this file but is there a way to specify only logging from specific packages to another file? Like logging.file.my.package=special.log ?
It's not possible with the logging configuration Spring Boot provides. However, you can fall back upon the configuration that the logging framework provides. By default, this is Logback, which can be configured to log to multiple logging files.
To do that, you need to add a logback.xml file to your classpath and configure multiple appenders. For example:
<appender name="FILE1" class="ch.qos.logback.core.FileAppender">
<file>log1.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE2" class="ch.qos.logback.core.FileAppender">
<file>log2.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
And now you can define a separate logger in case you want to log to a different file. Make sure to add the additivity="false" otherwise, the log message will still be printed in both log files:
<logger name="com.example.apps.special-package" level="INFO" additivity="false">
<appender-ref ref="FILE2" />
</logger>
<root level="INFO">
<appender-ref ref="FILE1" />
</root>
In this case, all logs will be written to log1.log (FILE1 appender), while logs from the package com.example.apps.special-package will be written to log2.log (FILE2 appender).
Spring uses Logback as default logger. According to the official doc you can setup logback.xml yourself to add to the default logging mechanism your 'special' behavior:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<property name="SPECIAL_FILE_NAME" value="special"/>
<appender name="SPECIAL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%-10.10thread] %-5level %30.30logger{29}:%-4line %msg%n</pattern>
<charset>utf8</charset>
</encoder>
<file>logs/${SPECIAL_FILE_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/${SPECIAL_FILE_NAME}-%i.log</fileNamePattern>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<logger name="logging.file.my.package" level="debug" additivity="false">
<appender-ref ref="SPECIAL_FILE"/>
</logger>
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
Here we use Spring default FILE and CONSOLE appenders to log app info as usual (except logging.file.my.package), and use SPECIAL_FILE appender to log info from this package to file log/special.log.
Overview:
I am using Sentry appender in my logback.xml file and I want to pass plenty of tags as parameters from application.properties file to logback config file.
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/file-appender.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<appender name="SENTRY" class="com.getsentry.raven.logback.SentryAppender">
<dsn>
https://e0a61232c92f42ffa34c22914d676a8e:e64f7edc60de490eb004556d2b3fce45#sentry.io/112817
</dsn>
<springProfile name="dev">
<tags>env:dev,app:${app.name},platform:aws</tags>
</springProfile>
<springProfile name="stage">
<tags>env:dev</tags>
</springProfile>
<springProfile name="test">
<tags>env:test</tags>
</springProfile>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<root level="ERROR">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="SENTRY"/>
</root>
</configuration>
application.properties:
security.ignored=/**
logging.level.root = DEBUG
spring.profiles.active=dev
app.name=retailServices
Note:
the spring.profiles.active property in application.properties is mapped to springProfile tag in logback config file.
But the issue is the fact that the "app.name" property cannot be found in logback.xml file. If I use this property as system properties it works but I want to pass it to config file from application.properties.
So any solution, feedback and idea would be highly appreciated.
In logback.xml include:
<property resource="application.properties" />
And then you can refer properties in a standard way, for example ${app.name}.
I found that Spring has support of next tag <springProperty/> described here . It means that you can easily add variable from property files even this variable value spring resolves from environment/system variable.
you can do it now directly via a logback context, or via a third party encoder.
LoggerContext context = (LoggerContext)LoggerFactory.getILoggerFactory();
context.putProperty("global", "value");
https://github.com/getsentry/sentry-java/pull/794
I know this is an old question but this is still a valid question.
Here is my solution, let's say you have a different spring profile and base on it want to change the configuration like log pattern, path of log file create, size of log file ...etc.
It can do it in like below,
let's say, We have two profile called dev and prod those config files look like below,
application-dev.properties
spring.application.name=Admin Module
logback.log.pattern=%-5level [%thread] %logger{36} : %X{correlationId} : %m%n
logback.app.log.root=C:\logs\adminModule\
logback.max.file.size=50MB
logback.max.file.history=2
application-prod.properties
spring.application.name=Admin Module
logback.log.pattern=%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} %-5level [%thread] %logger{36} : ${spring.application.name} : %X{correlationId} : %m%n
logback.app.log.root=\logs\adminModule\
logback.max.file.size=50MB
logback.max.file.history=30
application.properties
# (active profile can get dynamically)
spring.profiles.active=dev
This is my logback.xml file
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- get active profile-->
<springProperty scope="context" name="profile" source="spring.profiles.active"/>
<!-- get properties from active profile-->
<property resource="application-${profile}.properties" />
<property name="LOG_PATTERN" value="${logback.log.pattern}"/>
<property name="APP_LOG_ROOT" value="${logback.app.log.root}"/>
<property name="MAX_FILE_SIZE" value="${logback.max.file.size}"/>
<property name="MAX_FILE_HISTORY" value="${logback.max.file.history}"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="infoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${APP_LOG_ROOT}/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${APP_LOG_ROOT}/info.%d{yyyy-MM-dd_HH}-%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>${MAX_FILE_HISTORY}</maxHistory>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="infoLog"/>
<appender-ref ref="console"/>
</root>
</configuration>
This solution will reduce multiple logback.xml files maintain over head.
Is is possible to configure a daily file appender within the application.yml of a Spring Boot application?
i.e. filenamePattern: myfile.%d{yyyy-MM-dd-HH-mm-ss}.log
I have configuration such as the following in my application.yml file.
logging:
file: /mypath/myfile.log
level:
mypackage: INFO
Thanks
The default file appender is size based (10MB).
In your logback.xml just configure a TimeBasedRollingPolicy as described here
I.e. something like:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="ROLLIN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="ROLLIN" />
</root>
<logger name="org.springframework.web" level="INFO"/>
</configuration>
To override the default file appender and change it to daily rollover, you could use a logback-spring.xml looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<appender name="ROLLING-FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING-FILE"/>
</root>
</configuration>
logging.file.name=MyApp.log
logging.pattern.rolling-file-name=MyApp-%d{yyyy-MM-dd-HH-mm-ss}.%i.log
Working with Spring Boot 2.3.4 and 2.2.10
Not working with Spring Boot 2.1.17
application.yml
logging:
logback:
rollingpolicy:
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz # by date
max-file-size: 10MB # by size
Works on springboot v.2.5.10
You can also configure rolling policy based on file size in your
logback-spring.xml. In the below, we are specifying max file size as 10MB for SizeBasedTriggeringPolicy:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<appender name="ACTUAL_LOG_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!-- gz extension to enable file deletion by logrotator -->
<fileNamePattern>${LOG_FILE}.%i.gz</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<root level="INFO">
<appender-ref ref="ACTUAL_LOG_FILE" />
</root>
</configuration>
A little late to the party... but I was able to get my log file to roll (by size) with the following configuration in application.yaml and no logback.xml configuration whatsoever:
logging:
file: /var/log/webapps/app/app.log
# Roll the log file when it reaches max size
file.max-size: 1024KB
# Limit the number of log files retained
file.max-history: 50
pattern:
console: "%d %-5level %logger : %msg%n"
file: "%d %-5level [%thread] %logger : %msg%n"
level:
root: info
my.package.of.app: debug
org.springframework: error
# etc. etc.
In the application.properties file add these lines of code, use any these according to your requirement
logging.file.name=myinfo.log
#daily rolling logs
logging.pattern.rolling-file-name=myinfo-%d{yyyy-MM-dd}.%i.log
#per hour rolling logs
logging.pattern.rolling-file-name=myinfo-%d{yyyy-MM-dd-HH}.%i.log
#per minute rolling logs
logging.pattern.rolling-file-name=myinfo-%d{yyyy-MM-dd-HH-mm}.%i.log
#per secs rolling logs
logging.pattern.rolling-file-name=myinfo-%d{yyyy-MM-dd-HH-mm-ss}.%i.log
From this link :-
logging:
file: logs/application-debug.log
pattern:
console: "%d %-5level %logger : %msg%n"
file: "%d %-5level [%thread] %logger : %msg%n"
level:
org.springframework.web: ERROR
com.howtodoinjava: INFO
org.hibernate: ERROR