mmo
mmo

Reputation: 4246

SpringBoot with LogBack creating LOG_FILE_IS_UNDEFINED folder

I am using SpringBoot with LogBack and I am trying to direct all log-statements of one specific package (here shown as "com.example.somepackagename") to a file. All other log statements should go to stdout.

At first ran into the issue that during startup a file "LOG_FILE_IS_UNDEFINED" was created. I then googled on that issue (found e.g. this on github or this on StackOverflow and a few others), but none of the appends really solved the issue.

Based on the misc. descriptions I came up with the below configuration using a logback-spring.xml-file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_PATH" value="${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}" />
    <property name="LOG_FILE" value="${LOG_FILE:-ts-msgs.log}" />

    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
    </appender>

    <appender name="MSG_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${LOG_FILE}</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n%wex</Pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- rollover daily -->
            <fileNamePattern>${LOG_PATH}/archived/debug.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <logger name="com.example.somepackagename" additivity="false" level="debug">
         <appender-ref ref="MSG_LOG_FILE" />
    </logger>

    <logger name="org.springframework" additivity="false" level="info">
        <appender-ref ref="STDOUT" />
    </logger>

    <root level="warn">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

With that I don't get a file called "LOG_FILE_IS_UNDEFINED" anymore but LogBack now always first creates an empty file "ts-msgs.log" in the working directory of the application before it creates a file with the same name in the temp-directory (where that file should go). So, somehow during initialization it already creates a file with the correct name but the correct path not being set, yet. In other words, the initialization order of Logback within SpringBoot seems broken (or at least not intuitive) and it seems impossible to avoid a first log-file being created before the correct path for the file-appender is being defined and applied.

How can one prevent that first, initial and empty log file from being created? This is necessary, since the working directory is in general write-protected and the attempt to create a file there will lead to an exception (and typically the program being terminated).

Any hints or suggestions?

BTW: I already tried to rename that file to logback.xml (which seems to be processed earlier during SpringBoot startup) but that didn't solve the issue, so I kept the suggested filename.

Upvotes: 13

Views: 11154

Answers (2)

Hey StackExchange
Hey StackExchange

Reputation: 2125

Removing :

<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml"/>

from logback.xml fixed the problem for me.

Upvotes: -2

Eric
Eric

Reputation: 24890

I get similar issue, on application start following empty file might be generated:

  • LOG_PATH_IS_UNDEFINED
  • LOG_FILE_IS_UNDEFINED

Reason

Logging related config in application.yml, is read after logback-spring.xml is parsed, thus can't read it.


Possible solutions

I found 3 possible solutions, choose one that best fit your case:

  1. Move logging config from application.yml to bootstrap.yml, this will need spring-cloud dependency to make it work.

    • This works because bootstrap.yml is read before logback-spring.xml.
    • If you are not using spring-cloud, this probably won't be your best choice, since the extra dependencies is unnecessary.
  2. Define path & file in logback-spring.xml directly.
    e.g

     <configuration>
         <springProperty name="LOG_PATH" source="logging.path" defaultValue="logs/" />
         <springProperty name="LOG_FILE" source="logging.file" defaultValue="app.log" />
    

    In this case, might need to add "logback-spring.xml" to each sub project, if the log file names need to be different, and can't simply put the config file in a shared common dependency.

  3. Just keep the config in application.yml, and ignore the generated empty files by setting .gitinore.
    e.g

     LOG_*_IS_UNDEFINED
    

    In this case, the logs are still written to the file specified by application.yml, though the empty file is generate.


Tips

  • The logback-spring.xml file mentioned above, might be logback.xml or some other name in your case.

Upvotes: 3

Related Questions