Spring Boot and Logging with External Tomcat only outputs startup log - spring-boot

My Spring boot 2 app is not showing any log message when is running. I can only see the startup log. This app is deployed as WAR in the production server and I configured the log to output to a file:
logging.file = app.log
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} - %msg%n
In my local I can see whatever debug message I include in my code but in the server I can't. I only see the application startup trace.
My config to generate the file is the provided by official guideance. And the tomcat dependency in the app.war:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Do you have any idea of what is happening? It is strange. The log file is generating in the server ( we deploy it in a docker container ) but after the app is running, no more log is output to the file.

By default Spring Boot logs on INFO level, which should include ERROR.
As per Spring boot logging guide 79.1.1 Configure Logback for File-only Output
If you want to disable console logging and write output only to a file, you need a custom logback-spring.xml that imports file-appender.xml but not console-appender.xml, as shown in the following example:
<?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" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
You also need to add logging.file to your application.properties which you have alraedy added.

Related

Open Telemetry Logger MDC auto-instrumentation

The following Open Telemetry starters have been added to the Spring Boot project (v2.7.2) to instrument the application:
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot-starter</artifactId>
<version>1.22.1-alpha</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-jaeger-spring-boot-starter</artifactId>
<version>1.22.1-alpha</version>
</dependency>
Traces and spans are successfully exported to a Jaeger collector. The problem is those traces and spans cannot be correlated with log statements because logs don't contain the current trace_id and span_id.
By following the documentation I added the logging.pattern.level property to application.properties but it seems like information about the current span is not injected into the logging event's MDC copy.
logging.pattern.level = trace_id=%mdc{trace_id} span_id=%mdc{span_id} trace_flags=%mdc{trace_flags} %5p
For example:
log.info(
"traceId: {}, spanId: {}",
Span.current().getSpanContext().getTraceId(),
Span.current().getSpanContext().getSpanId());
2023-01-25 12:21:36.774 trace_id= span_id= trace_flags= INFO 34272 --- [nio-8080-exec-2] h.c.DemoController : traceId: 1bccb6a4fea8345026ca87a202f0091f, spanId: c59a5d44ee40cd2c
Have I missed anything?
opentelemetry-spring-boot-starter is missing this feature right now (version 1.22.1-alpha), but it can be added very easily.
Firstly, MDC Instrumentation for Logback dependency should be added to the project.
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-logback-mdc-1.0</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
Then add a custom logback.xml configuration to the classpath, which will automatically inject context information from the span context to logging events.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Default logback 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"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml"/>
<!-- -->
<appender name="OTEL" class="io.opentelemetry.instrumentation.logback.v1_0.OpenTelemetryAppender">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</appender>
<root level="INFO">
<appender-ref ref="OTEL"/>
</root>
</configuration>
Finally, add the property to application.properties (as mentioned in the question):
logging.pattern.level = trace_id=%mdc{trace_id} span_id=%mdc{span_id} trace_flags=%mdc{trace_flags} %5p

Is there a way to provide Slueth the spring application name other than specifying that in bootstrap.properties of Spring boot application?

As per this guidelines, one has to specify application name in bootstrap.properties if using custom logback.xml. I was wondering if there's any way where I can hardcode the application name in logback.xml instead of creating the bootstrap.properties file with that property ?
I have bootstrap.properties with property spring.application.name and slueth recognizes that and things are fine. But I was wondering if there's any way where I can specify any logback property and sleuth will pick the application name up!?
Please note I am using my own custom logging format. Following is how my logback.xml file looks like.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="CONSOLE_LOG_PATTERN" value="%date{ISO8601}
${LOG_LEVEL_PATTERN:-%5p} ${PID:- } [%15.15t] %-40.40logger{39} :
%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
The <springProperty> tag lets you expose properties from the Spring Environment for use within Logback.
i.e.
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host" defaultValue="localhost"/>

How to set max number of archived logs in spring boot

I tried following settings in application.properties:
logging.file=foo/bar.log
logging.file.max-history=2
logging.file.max-size=1KB
Still, its not limiting the number of archive logs to 2.
As per application properties documentation reference, only supported when you setup logback.
logging.file.max-history=0 # Maximum of archive log files to keep. Only supported with the default logback setup.
So to add support of logback please see section 79.1 Configure Logback for Logging & 79.1.1 Configure Logback for File-only Output of Spring Boot Logging Guide
If you want to disable console logging and write output only to a
file, you need a custom logback-spring.xml that imports
file-appender.xml but not console-appender.xml, as shown in the
following example:
<?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" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>

logback-spring.xml loaded before spring boot application configuration properties

I have my own logback base.xml file where i define pre-defined file appenders that are used by different applications.
I want the log directory to be configurable per application with a property in application.properties (log.path) and have a default in case none is provided (/var/log), so i have:
base.xml
<included>
<property name="logPath" value="${logPath:-/var/log}"/>
<appender name="TEST" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logPath}/test.log</file>
...
</appender>
logback-spring.xml for spring boot application:
<configuration>
<springProperty scope="context" name="logPath" source="log.path" />
<include resource="base.xml" />
<root level="INFO">
<appender-ref ref="TEST"/>
</root>
</springProfile>
For some reason i end up with two log directories, both /var/log and "log.dir", it seems base.xml is interpreted before spring boot environment is ready.
I'm running spring-boot 1.5.2 comes with logback 1.1.11.
It seems the problem was caused by adding spring-cloud.
During spring cloud's boostraping process, log.dir property is not found and logback creates an logDir_IS_UNDEFINED directory. After the bootstrap process logback is re-initialized with right configuration.
Related spring-cloud issue: issue-197
See Spring Documentation, especially the section about how properties are carried over to logback. Try using logging.path as a property in your application.properties. It should be accessible as LOG_PATH in logback than.
Also the usual way to use the base file is by adding the spring-boot-starter-logging in Maven/Gradle and include it like that:
<include resource="org/springframework/boot/logging/logback/base.xml"/>
I have a similar problem. I use defaultValue. To be honest it's just a smelly workaround.
<springProperty name="configurable.canonical.name" source="canonical.name" defaultValue="${canonical_name}" />
<file>logs/${configurable.canonical.name}.log</file>
canonical_name is defined in default.properties. Maven is going to resolve it during build.

Cannot suppress debug logging of framework classes with spring boot and logback

I am working on a spring boot microservice application that uses logback for logging.
The standard logback.xml is in the default place (main/resources) and is obviously used as I can add logger-statements and they are effective.
Its content looks like this (standard apart from removed comments and the two additional logger directives):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="org.springframework" level="INFO"/>
<logger name="my.app.package.MyClass" level="DEBUG"/>
</configuration>
However, even though I put this into the logback.xml file:
<logger name="org.springframework" level="INFO"/>
I get tons of debug log output from framework classes like this here:
2015-09-16 10:49:40.733 DEBUG 96549 --- [ main] o.s.w.s.h.BeanNameUrlHandlerMapping : Rejected bean name 'contextAttributes': no URL paths identified
What is wrong with my setup? Why are framework classes not respecting my logback config?

Resources