简体   繁体   中英

How to use custom logger to log access log in spring boot

Currently in spring boot 1.3, we could only log access log to a file in the filesystem. Is there any way to actually use the custom logger (like log4j2) to log the access log?

I am currently using undertow with spring boot, but after checking the spring boot source code, the undertow logger is initialized with DefaultAccessLogReceiver which is writing to file. I would like to use the AccessLogHandler if possible, and avoid writing a web filter which logs the access.

Is there any easy way around this? (except writing a pull request)

A trick for this kind of hard-coded-thus-not-customizeable problem is to hide the class to kick out with a new one with the same package and name. All you have to do is to provide a log4j based DefaultAccessLogReceiver and make sure it can be search by the classloader before the one in the undertow library.

package io.undertow.server.handlers.accesslog;

public class DefaultAccessLogReceiver implements AccessLogReceiver {

    public void logMessage(final String message) {
        // TODO: log with log4j
    }
}

Spring Boot has no mandatory logging dependency, except for the commons-logging API, of which there are many implementations to choose from. To use Logback you need to include it, and some bindings for commons-logging on the classpath. The simplest way to do that is through the starter poms which all depend on spring-boot-starter-logging. For a web application you only need spring-boot-starter-web since it depends transitively on the logging starter. For example, using Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Boot has a LoggingSystem abstraction that attempts to configure logging based on the content of the classpath. If Logback is available it is the first choice.

Spring Boot also supports either Log4j or Log4j 2 for logging configuration, but only if one of them is on the classpath. If you are using the starter poms for assembling dependencies that means you have to exclude Logback and then include your chosen version of Log4j instead. If you aren't using the starter poms then you need to provide commons-logging (at least) in addition to your chosen version of Log4j.

The simplest path is probably through the starter poms, even though it requires some jiggling with excludes, .eg in Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

To use Log4j 2, simply depend on spring-boot-starter-log4j2 rather than spring-boot-starter-log4j.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM