1

I want to maintain a log of only WARN, ERROR and FATAL in my logfile.log whereas want all above INFO to be written to console in my spring boot application. I see that when I do log.level.root=WARN, in application.properties file it sets a log level of WARN for the whole application. What can I do for displaying all log messages in console but writing only ones above WARN in the file?

Also!!!! Is there a way to set level to INFO and write only certain specified logs in the file. For eg. I want to trace each and every logins/logouts/filechanges (say business logic related) in log with INFO level but don't want to see the default INFO messages that pop up during the start of the application like

2018-07-11 10:19:00.554 INFO 11190 --- [ main] c.v.guruji.GurujiApplication : Started GurujiApplication in 10.307 seconds (JVM running for 11.029) .

Kush
  • 644
  • 1
  • 12
  • 30

2 Answers2

1

Well , I went through some logback documentations and pretty much figured out what to do.

I'm posting this code for others who'll be having such problems as me for quick reference.

But I'll suggest to go through a proper documentation at first to understand it clearly.

logback.xml(for logging each level log in a separate file and to show all at console)

<?xml version="1.0" encoding="UTF-8"?>

<property name="DEV_HOME" value="logs" />

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



<appender name="FILE-ERROR"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/error.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </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">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/error.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

</appender>



<appender name="FILE-INFO"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/info.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>INFO</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </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">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/info.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

</appender>



<appender name="FILE-FATAL"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/fatal.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>FATAL</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </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">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/fatal.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

</appender>


<appender name="FILE-WARN"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${DEV_HOME}/warn.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>WARN</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </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">
        <!-- rollover daily -->
        <fileNamePattern>${DEV_HOME}/archived/warn.%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

</appender>


<!-- Send logs to both console and file audit -->

<logger name="com.vaidiksanatansewa.guruji" level="fatal"
        additivity="false">

    <appender-ref ref="FILE-FATAL" />
</logger>


<logger name="com.vaidiksanatansewa.guruji" level="error"
        additivity="false">

    <appender-ref ref="FILE-ERROR" />
</logger>


<logger name="com.vaidiksanatansewa.guruji" level="warn"
        additivity="false">

    <appender-ref ref="FILE-WARN" />
</logger>


<logger name="com.vaidiksanatansewa.guruji" level="info"
        additivity="false">

    <appender-ref ref="FILE-INFO" />
</logger>

<root level="INFO">
    <appender-ref ref="STDOUT" />
</root>

Kush
  • 644
  • 1
  • 12
  • 30
0

The answer depends on which actual logging framework are you planning to use, spring boot has integrations with most of them.

In general, if you opt for "zero configuration", specify the level of events in spring boot configuration files (application.properties / yaml) with the following line:

logging.level.com.myorg=DEBUG
logging.level.root=INFO

If you want to write to files, or in general provide more flexible configurations, you'll need to configure something called appender, but it's not a spring boot notion, but a logging framework term.

So the actual configuration will depend on a specific logging framework, usually, people put an XML configuration file (like logback.xml if you use logback) into src/main/resources folder and it works. Another modern option is log4j2 framework.

From the question it seems like you better first understand how to use these frameworks and then try to integrate them into spring boot, each of them is really flexible and will provide a solution you're looking for

  • Here is a link to the tutorial on how to use each of those frameworks with spring boot

  • Here is a logging chapter of official documentation of spring boot

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97