How can I log HTTP @GET
and @POST
to separate files. Basically we just want to have separate log files for read ( GET) and write( PUT, POST , DELETE). I and using Slf4j
with logback
with embedded jetty.
one solution is to have two loggers in class and use them accordingly . i.e.
private final static Logger log = LoggerFactory.getLogger(Controller.class);
private final static Logger writeLog = LoggerFactory.getLogger("WRITE");
Now as per the requirement use the above logger, Define Appender
and Logger
.
<appender name="APPENDER_READ"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${HOME}/logs/read.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>read.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%date{YYYY-MM-dd HH:mm:ss} %level [%thread] %X{TaskKey} %msg%n</pattern>
</encoder>
</appender>
<appender name="APPENDER_WRITE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${HOME}/logs/write.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/write.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%date{YYYY-MM-dd HH:mm:ss} %level [%thread] %X{TaskKey} %msg%n</pattern>
</encoder>
</appender>
<logger name="WRITE" level="warn" additivity="false">
<appender-ref ref="APPENDER_WRITE" />
</logger>
<root level="WARN">
<appender-ref ref="APPENDER_READ" />
</root>
But I am looking for some better solution that can start logging not from controller but from the Handler level ( as soon as request enters).
You should put the request method (GET, POST, etc...) into Logback's MDC (mapped diagnostic context). Indeed, you should do this as early as possible, for example in a Filter, like this:
import javax.servlet.Filter;
import org.slf4j.MDC;
public class MDCFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
MDC.put("METHOD", ((HttpServletRequest)req).getMethod());
try {
chain.doFilter(req, resp);
} finally {
MDC.remove("METHOD");
}
}
}
Then you can direct logging into different files based on the value of the MDC key 'METHOD' with Logback's SiftingAppender.
Very good example for that: https://www.mkyong.com/logging/logback-different-log-file-for-each-thread/ (just use 'METHOD' instead of 'logFileName')