springboot中logback只輸出指定log(一種攔截自動輸出每個request的log,一種只輸出class中手動加入的log【模仿log4j】)

上次寫了一個通用logback(下面的鏈接),log信息是全面,但有很多運行log對開發運營人員是無用,這些冗餘log影響開發人員閱讀。

https://blog.csdn.net/thankna/article/details/105936016

這次按照項目需求,springboot中logback只輸出指定log

一種攔截自動輸出每個request的log,通俗講就是一個controller一個

一種只輸出class中手動加入的log【模仿log4j】)

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
	<property name="logs" value="./logs" />
	<property name="ROOT_LEVEL" value="INFO" />
	<statusListener
		class="ch.qos.logback.core.status.NopStatusListener" />
	<appender name="CONSOLE_OUT"
		class="ch.qos.logback.core.ConsoleAppender">
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern>
				%-15(%d{HH:mm:ss.SSS}) [%thread]%-5level%logger{80}[%line] - %msg%n
			</pattern>
		</layout>
	</appender>
	<appender name="ACCESS_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<append>true</append>
		<file>${logs}/access.log</file>
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>INFO</level>
		</filter>
		<file>${logs}/access.log</file>
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${logs}/access_%d{yyyy-MM-dd}.log</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<encoder
			class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>
				%d{yyyy-MM-dd HH:mm:ss.SSS} %logger - %msg%n
			</pattern>
		</encoder>
	</appender>
	<appender name="JSON_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<append>true</append>
		<file>${logs}/josn.log</file>
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>WARN</level>
		</filter>
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>
				${logs}/json_%d{yyyy-MM-dd}.log
			</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
			<layout class="jp.co.pia.ticket.sports.hawks.seasonseat.common.util.common.JsonLogLayout" />
		</encoder>
	</appender>
	<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<append>true</append>
		<file>${logs}/error.log</file>
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>WARN</level>
		</filter>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>
				${logs}/error_%d{yyyy-MM-dd}.log
			</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<encoder>
			<!-- <pattern>%d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%t] [%X{client}] [%X{sessionId}] %msg%n</pattern> -->
			<pattern>%d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%t] %logger - %msg%n</pattern>
		</encoder>
	</appender>
	<appender name="OPERATE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<append>true</append>
		<file>${logs}/operate.log</file>
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>INFO</level>
		</filter>
		<file>${logs}/operate.log</file>
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${logs}/operate_%d{yyyy-MM-dd}.log</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<encoder
			class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>
				%d{yyyy-MM-dd HH:mm:ss.SSS} %logger - %msg%n
			</pattern>
		</encoder>
	</appender>
	<root level="info">
		<appender-ref ref="CONSOLE_OUT" />
		<appender-ref ref="ERROR" />
		<appender-ref ref="JSON_LOG" />
	</root>
	<logger name="ACCESS" level="INFO" additivity="false">
		<appender-ref ref="ACCESS_LOG" />
	</logger>
	<logger name="OPERATE" level="INFO" additivity="false">
		<appender-ref ref="OPERATE_LOG" />
	</logger>
</configuration>

其中CONSOLE_OUT、ERROR、JSON_LOG是常規log。配置如下

    <root level="info">
        <appender-ref ref="CONSOLE_OUT" />
        <appender-ref ref="ERROR" />
        <appender-ref ref="JSON_LOG" />
    </root>

第一種ACCESS_LOG是request級別log。配置如下

    <logger name="ACCESS" level="INFO" additivity="false">
        <appender-ref ref="ACCESS_LOG" />
    </logger>

log攔截器配置如下

import java.security.Principal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import xxx.LogConfig;

public class LogInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger("ACCESS");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        JSONObject json = new JSONObject();
        // セッションID
        json.put(LogConfig.SESSION_ID, request.getSession().getId());
        // ユーザーID
        Principal auth = request.getUserPrincipal();
        String userId = null;
        if (auth != null) {
            userId = auth.getName();
        }
        if (StringUtils.isEmpty(userId)) {
            json.put(LogConfig.AUTH_NAME, LogConfig.NONE_STR);
        } else {
            json.put(LogConfig.AUTH_NAME, userId);
        }
        // クライアントIP
        json.put(LogConfig.IP, request.getRemoteAddr());
        // httpメソッド
        json.put(LogConfig.HTTP_METHOD, request.getMethod());
        // URL
        json.put(LogConfig.URL, request.getRequestURI());
        // ステータスコード
        json.put(LogConfig.HTTP_STATUS_CODE, response.getStatus());
        // ログ種類(開始)
        json.put(LogConfig.LOG_TYPE, LogConfig.START);
        // // 出力メッセージ
        // Map<String, String[]> map = request.getParameterMap();
        // map.forEach((key, value) -> {
        // json.put(key, request.getParameter(key));
        // });

        logger.info(json.toString());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView)
        throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        JSONObject json = new JSONObject();
        // セッションID
        json.put(LogConfig.SESSION_ID, request.getSession().getId());
        // ユーザーID
        Principal auth = request.getUserPrincipal();
        String userId = null;
        if (auth != null) {
            userId = auth.getName();
        }
        if (StringUtils.isEmpty(userId)) {
            json.put(LogConfig.AUTH_NAME, LogConfig.NONE_STR);
        } else {
            json.put(LogConfig.AUTH_NAME, userId);
        }
        // クライアントIP
        json.put(LogConfig.IP, request.getRemoteAddr());
        // httpメソッド
        json.put(LogConfig.HTTP_METHOD, request.getMethod());
        // URL
        json.put(LogConfig.URL, request.getRequestURI());
        // ステータスコード
        json.put(LogConfig.HTTP_STATUS_CODE, response.getStatus());
        // ログ種類(終了)
        json.put(LogConfig.LOG_TYPE, LogConfig.END);

        logger.info(json.toString());
    }
}
import java.util.HashMap;
import java.util.Map;

public interface LogConfig {
    /** セッションID */
    String SESSION_ID = "sessionId"; // jsessionidに設定された値
    /** IPアドレス */
    String IP = "ip"; // ユーザのIPアドレス
    /** URL */
    String URL = "url"; // アクセス先のURL
    /** ユーザID */
    String AUTH_NAME = "userId"; // ログインユーザのユーザID
    /** httpメソッド */
    String HTTP_METHOD = "httpMethod";
    /** ステータスコード */
    String HTTP_STATUS_CODE = "httpStatusCode";
    /** 固定文言 */
    String NONE_STR = "未設定";
    String LOG_TYPE = "logType";
    String START = "START";
    String END = "END  ";
    String TRACE_ID = "traceId";
    /** 畫面名  */
    Map<String,String> GAMEN_NAME_MAP = new HashMap<String, String>() {
        private static final long serialVersionUID = 1L;
        {
            put("HSP01002", "xxx");
        }
    };
}

TraceId攔截器配置如下

import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.MDC;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import jp.co.pia.ticket.sports.hawks.seasonseat.common.util.component.LogConfig;

public class TraceIdInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String traceId = UUID.randomUUID().toString().replace("-", "");
        MDC.put(LogConfig.TRACE_ID, traceId);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView)
        throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}

攔截器追加註冊

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class ControllerConfiger implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new TraceIdInterceptor()).addPathPatterns("/**");

        registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
    }
}

第二種OPERATE_LOG類似log4j只打印手動輸出。配置如下

    <logger name="OPERATE" level="INFO" additivity="false">
        <appender-ref ref="OPERATE_LOG" />
    </logger>

個別部打印畫面項目

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

import jit.wxs.demo.component.LogConfig;

@Component
public class OperateLog {
    /**
     * 機能概要:toJsonLog
     * @param HttpServletRequest request
     * @param HashMap<String, String> parmap
     * @return String logmsg
     */
    public  String toJsonLog(HttpServletRequest request, HashMap<String, String> parmap) throws IOException {
        String logmsg = CommonConst.STRING_BLANK;
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        // 共通部
        String[] arr = request.getRequestURI().split(CommonConst.SLASH);
        String gamenId = arr[1];
        map.put(CommonConst.OPERATELOG_GAMENID, gamenId);
        String name = LogConfig.GAMEN_NAME_MAP.get(gamenId);
        map.put(CommonConst.OPERATELOG_GAMENNAME, name);
        map.put(CommonConst.OPERATELOG_UPDDATETIME, parmap.get(CommonConst.OPERATELOG_UPDDATETIME));
        map.put(CommonConst.OPERATELOG_USERID, SecurityUtils.getUserId());
        map.put(CommonConst.OPERATELOG_USERNAME, SecurityUtils.getUsername());
        map.put(CommonConst.OPERATELOG_OPERATION, parmap.get(CommonConst.OPERATELOG_OPERATION));
        // 個別部
        Map<String, String[]> entmap = request.getParameterMap();
        entmap.forEach((key, value) -> {
            map.put(key, request.getParameter(key));
        });
        ObjectMapper mapper = new ObjectMapper();
        logmsg = mapper.writeValueAsString(map);
        return logmsg;
    }
}
@Service
@Slf4j
@Scope("session")
public class HSP01002Service {

    @Autowired
    private DocumentRequestMapper documentRequestMapper;
    /** 操作履歴 */
    @Autowired
    private OperateLog opLog;
    /** log名 */
    private Logger logger = LoggerFactory.getLogger(CommonConst.OPERATELOG_LOGNAME);

    public int insertDocumentRequest(HSP01002InputEntity tHSP01002InputEntity, HttpServletRequest request) throws Exception {
            int num = documentRequestMapper.insertDocumentRequest(documentRequestEntity);
            HashMap<String, String>parmap = new HashMap<String, String>();
            // 更新日時
            parmap.put(CommonConst.OPERATELOG_UPDDATETIME, DateUtil.toDateStringMilliSecByDate(documentRequestEntity.getUpdate_tim()));
            // 操作
            parmap.put(CommonConst.OPERATELOG_OPERATION, CommonConst.OPERATELOG_INSERT);
            // 操作履歴
            logger.info(opLog.toJsonLog(request, parmap));
            log.debug(this.getClass().getName() + "■insertDocumentRequest end:");
}

logger輸出的是在operate log文件中。沒有任何系統自己出的log。

log輸出在通用的log中,混在一堆log裏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章