中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

log4j如何控制日志輸出文件名稱

發布時間:2021-12-27 12:31:26 來源:億速云 閱讀:292 作者:小新 欄目:開發技術

小編給大家分享一下log4j如何控制日志輸出文件名稱,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

    log4j控制日志輸出文件名稱

    1. 第一種方式

    在類對象中用如下方式定義logger變量

    private static Logger logger = Logger.getLogger("lemmaXml");

    這樣通過名稱的方式獲取logger,需要在log4j.properties文件中定義一個名稱為lemmaXml的appender,配置如下:

    log4j.logger.lemmaXml=INFO,lemmaXml
    log4j.appender.lemmaXml=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.lemmaXml.Threshold=DEBUG
    log4j.appender.lemmaXml.File=${catalina.home}/logs/lemmaXml.log
    log4j.appender.lemmaXml.layout=org.apache.log4j.PatternLayout
    log4j.appender.lemmaXml.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss} %m %n

    上述配置說明,名稱為lemmaXml的appender,是每天形成一個日志文件,日志文件的名稱為

    ${catalina.home}/logs/lemmaXml.log

    日志的格式為

    %5p %d{yyyy-MM-dd HH:mm:ss} %m %n

    2. 第二種方式(這種方式親測正確)

    在類對象中用如下方式定義logger變量

    import org.apache.log4j.Logger;
    private static Logger logger = Logger.getLogger(ExportLemmaManagerService.class);

    即,通過類的參數來獲取logger變量,此時必然也需要在log4j.properties文件有關于該對象日志文件的輸出配置,當然這里的配置不是針對每個類專門配置,而是針對一個路徑整體配置,即,你可以配置某個目錄下的所有類方式的輸出文件的文件名稱,如下

    log4j.rootLogger=info,stdout 
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Threshold=DEBUG
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n
      
    log4j.logger.com.soso.baike.service=DEBUG,ServiceLog
    log4j.appender.ServiceLog=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.ServiceLog.Threshold=DEBUG
    log4j.appender.ServiceLog.File=${catalina.home}/logs/service.log
    log4j.appender.ServiceLog.MaxBackupIndex=10
    log4j.appender.ServiceLog.layout=org.apache.log4j.PatternLayout
    log4j.appender.ServiceLog.layout.ConversionPattern=%5p %d{yyyy-MM-dd HH:mm:ss} %c %m %n

    上述配置了目錄com.soso.baike.service下的輸出文件方式,上述ExportLemmaManagerService類就是在該包下,所以用該包下的類方式來定義logger的話,輸出的文件就都在service.log文件中,每天生成一個新的日志文件。

    如何隨心所欲地自定義log4j輸出格式

    在某種情況下,我們需要在不影響原有代碼的基礎上自定義log4j的輸出格式。

    例如這樣的需求,硬性規定了項目的日志格式為:

    日期 日志等級 ClassName:line - [版本號] [請求ip地址] [項目應用名稱] [服務接口模塊] [模塊方法] [業務參數1] [業務參數2] [業務參數3] 日志詳細內容(必須為json格式)

    示例:

    2018-05-10 14:04:50,972 INFO ViolationService:51 - [v1.0.0] [192.168.137.47] [merchant-service.cx580.com] [OrderController] [messageList] [null] [] [] {"body":"訂單狀態消息列表resp:{\"code\":1000,\"msg\":\"成功\"}"}

    其中:

    • 版本號是指當前服務接口實際的版本信息,例如V1.0.1;

    • 請求ip地址為用戶真實的請求ip;

    • 項目應用名稱為項目的名稱或者標識,例如支付服務定義應用名稱為payService;

    • 服務接口模塊是指請求接口對應的模塊代碼,例如請求訂單接口,則接口模塊為OrderControlller;

    • 模塊方法是指接口對應的請求方法,例如下單接口對應模塊方法為createOrder;

    • 業務參數1可根據實際情況寫入相應的業務數據,錄入訂單號orderId,該參數可為空;

    • 業務參數2同上;

    • 業務參數3同上;

    • 日志詳細內容是指請求接口時需打印出來的描述信息,例如創建訂單異常時,在異常捕捉方法體中描述異常詳細信息,日志內容需定義到一個json結構中。

    以上是我遇到的場景,這時在不影響原有項目代碼的基礎上,我們做出日志格式的調整,使用如下方案:

    1.通過log4j的占位替換符%X{}配合MDC格式化日志,使用AOP切面在請求線程開始處填充替換符變量

    2.繼承log4j的具體appender類,重寫subAppend方法,修改日志輸出的內容格式。

    此時log4j文件如下

    log4j.rootCategory=INFO, stdout, file, errorfile
    #log4j.category.com.cx=DEBUG
    log4j.logger.error=errorfile
     
    log4j.appender.stdout=com.test.common.GrayLogConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L%X{log_version}%X{log_ip}%X{log_item}%X{log_module}%X{log_method}%X{log_req_params} %m%n
     
    log4j.appender.file=com.test.common.GrayLogDailyRollingFileAppender
    log4j.appender.file.file=${log.dir}/${spring.application.name}.log
    log4j.appender.file.DatePattern='.'yyyy-MM-dd
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L%X{log_version}%X{log_ip}%X{log_item}%X{log_module}%X{log_method}%X{log_req_params} %m%n
     
    log4j.appender.errorfile=com.test.common.GrayLogDailyRollingFileAppender
    log4j.appender.errorfile.file=${log.dir}/${spring.application.name}_error.log
    log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd
    log4j.appender.errorfile.Threshold = ERROR
    log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout
    log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L%X{log_version}%X{log_ip}%X{log_item}%X{log_module}%X{log_method}%X{log_req_params} %m%n

    在log4j.properties文件,我們做了兩個變動,一個是添加了%X{value}的變量,另一個則是將原本的DailyRollingFileAppender修改成了com.test.common.GrayLogConsoleAppender。

    處理log4j的變量,對代碼進行controller切面,在一個http請求java的入口中放入線程變量,該線程變量在當次http請求生命周期內生效。

    切面代碼如下:

    @Around("execution(public * com.test.controller..*.*(..))")
        public Object aroundController(ProceedingJoinPoint joinPoint) {
            ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request =attributes.getRequest();
            String execIp = request.getHeader("X-Real-IP");
            if(StringUtils.isBlank(execIp)){
                execIp=request.getRemoteAddr();
            }
            String execClass= joinPoint.getTarget().getClass().getSimpleName();
            String execMethod = joinPoint.getSignature().getName();
            Map<String,String[]> map = request.getParameterMap();
            List<String> paramsList = new ArrayList<>();
            for(Map.Entry<String,String []> m : map.entrySet()){
                String [] value = m.getValue();
                paramsList.add( m.getKey() + "=" + StringUtils.join(value,","));
            }
     
            String execParams = "[" + StringUtils.join(paramsList,"&") + "] [] []";
            MDC.put("log_version"," - [V1.0.0]");
            MDC.put("log_item"," [violation-mini]");
            MDC.put("log_module"," [" + execClass + "]");
            MDC.put("log_method"," [" + execMethod+ "]");
            MDC.put("log_req_params"," " + execParams);
            MDC.put("log_ip"," [" + execIp+ "]");
            Object result= null;
            try {
                result = joinPoint.proceed();
            } catch (Throwable throwable) {
                LOGGER.error("方法異常:",throwable);
            }
            return result;
        }

    至此,格式中的MDC變量都已被放入成功。

    下一步,將原本的日志內容套上json外套。

    新建GrayLogConsoleAppender類繼承具體的appender類

    代碼如下:

    package com.test.common; 
    import net.sf.json.JSONObject;
    import org.apache.commons.lang.StringUtils;
    import org.apache.log4j.ConsoleAppender;
    import org.apache.log4j.spi.LoggingEvent;
    import org.apache.log4j.spi.ThrowableInformation; 
    import java.lang.reflect.Field;
     
    /**
     * @Author: Lxx
     * @Description:
     * @Date: Created in 17:29 2018/5/30
     */
    public class GrayLogConsoleAppender extends ConsoleAppender {
        @Override
        protected void subAppend(LoggingEvent event) {
            try {
                Class<LoggingEvent> clazz = LoggingEvent.class;
                Field filed = clazz.getDeclaredField("throwableInfo");
                filed.setAccessible(true);
                Object exception = filed.get(event);
                JSONObject json = new JSONObject();
                if(exception != null){
                    if(exception instanceof ThrowableInformation){
                        ThrowableInformation throwableInformation = (ThrowableInformation) exception;
                        String [] details = throwableInformation.getThrowableStrRep();
                        String error_msg = StringUtils.join(details,"\r\n");
                        json.put("exception",error_msg);
                    }
                }
                filed.set(event,null);
                boolean flag = false;
                Field filed1 = clazz.getDeclaredField("message");
                filed1.setAccessible(true);
                Object message = filed1.get(event);
                if (message instanceof String) {
                    String msg = (String) message;
                    if (message != null) {
                        flag = true;
                    }
                    json.put("body", msg);
                    filed1.set(event, json.toString());
                }
                if(!flag){
                    Field filed2 = clazz.getDeclaredField("renderedMessage");
                    filed2.setAccessible(true);
                    Object message2 = filed2.get(event);
                    if (message2 instanceof String) {
                        String msg = (String) message2;
                        json.put("body", msg);
                        filed2.set(event, json.toString());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            super.subAppend(event);
        }
    }

    至此,已為日志內容套上json外套,并且當有異常日志時,將異常的堆棧信息放入json的exception中輸出出來,不打印堆棧信息。

    最終結果:

    2018-06-09 00:48:31,849 INFO LogAspect:65 - [V1.0.0] [223.88.53.135] [violation-mini] [TestController] [queryList] [appName=abc&authType=test&avatar=&nickName=&token=asdfasdfadsfasdf&userId=asdfasdfasdfasdf&userType=aaaaa] [] [] {"body":"結果為:ResponseResult{code='0', msg='null', errormsg='查詢成功', data={}, successFlag=false}"}

    以上是“log4j如何控制日志輸出文件名稱”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    华池县| 乳山市| 南岸区| 岑巩县| 军事| 江永县| 柳河县| 海兴县| 车致| 茂名市| 中西区| 东乌| 大洼县| 日照市| 华容县| 鄱阳县| 建平县| 丹东市| 绵竹市| 尖扎县| 惠安县| 湘阴县| 枣阳市| 旌德县| 东宁县| 满城县| 博客| 星座| 阜康市| 盐池县| 昌黎县| 台北市| 宁远县| 夏津县| 浑源县| 温州市| 观塘区| 商水县| 张家川| 宁蒗| 和政县|