封裝log4j支持記錄到testng

1、初始方案java

自動化中須要把日誌經過testng的Reporter.log來記錄日誌在報告中展現。開始是新增了一個日誌類:apache

ReporterLog.class測試

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Reporter;

public class ReporterLogger {
    private Logger LOGGER;

    public ReporterLogger(Class<?> clazz){
        LOGGER= LoggerFactory.getLogger(clazz);
    }

    public void  info(String message){
        //使用slf4j打印到控制檯或者文件
        LOGGER.info(message);
        //記錄到Reporter
        Reporter.log(message);
    }

}

 

這樣會有2個問題:spa

一、LOGGER.info(message);這句話打印出來的類名、方法名、行號等不是調用ReporterLogger方法info的類,二是ReporterLogger類。日誌

二、Reporter.log記錄的日誌,沒有時間、類名、方法名、行號。code

 

第一個問題測試:orm

import com.sqe.sas.test.service.ReporterLogger;

public class LogTest {
    private static final ReporterLogger LOGGER = new ReporterLogger(LogTest.class);

    public static void main(String[] args) {
        LOGGER.info("processing。。。。");
    }

}

打印結果:blog

[main][2019-01-29 18:28:14] [INFO] [LogTest.info:25] processing。。。。字符串

類名打印的是對的,可是方法名和行號打印的都是ReporterLogger中的get

 

 

2、改進方案:

第一個問題:

使用log4j的log方法

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.testng.Reporter;

public class ReporterLogger {
    private Logger LOGGER; //使用org.apache.log4j.Logger 而不是org.slf4j.Logger;
    static final String FQCN = ReporterLogger.class.getName();  // log4j把傳遞進來的callerFQCN在堆棧中一一比較,相等後,再往上一層即認爲是用戶的調用類

    public ReporterLogger(Class<?> clazz){
        LOGGER= Logger.getLogger(clazz); // 這裏也要改
    }


    public void  info(String message){
        //使用slf4j打印到控制檯或者文件
        LOGGER.log(FQCN, Level.INFO,message,null);
        //記錄到Reporter
        Reporter.log(message);
    }

}

 

再次測試,打印結果以下:

 [main][2019-01-30 10:44:23] [INFO] [LogTest.main:7] processing。。。。

已經能夠了打印正確的方法名和行號了

 

第二個問題:

在打印的字符串前加上時間、類名、方法名、行號

 

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.testng.Reporter;

import java.text.SimpleDateFormat;
import java.util.Date;

public class ReporterLogger {
    private Logger LOGGER; //使用org.apache.log4j.Logger 而不是org.slf4j.Logger;
    static final String FQCN = ReporterLogger.class.getName();  // og4j把傳遞進來的callerFQCN在堆棧中一一比較,相等後,再往上一層即認爲是用戶的調用類

    public ReporterLogger(Class<?> clazz){
        LOGGER= Logger.getLogger(clazz); // 這裏也要改
    }


    public void  info(String message){
        //使用slf4j打印到控制檯或者文件
        LOGGER.log(FQCN, Level.INFO,message,null);
        message = getLogTag()+message;
        //記錄到Reporter
        Reporter.log(message);
    }
    //根據堆棧信息,拿到調用類的名稱、方法名、行號
    public String getLogTag(){
        String logTag = "";
        Long timeStamp = System.currentTimeMillis();
        String dateString = timestampToDate(timeStamp);
        StackTraceElement stack[] = (new Throwable()).getStackTrace();
        for(int i=0;i<stack.length;i++) {
            StackTraceElement s = stack[i];
            if(s.getClassName().equals(LOGGER.getName())){
                logTag= "["+dateString+"]"+"["+classNameDeal(s.getClassName())+":"+s.getMethodName()+":"+s.getLineNumber()+"]";
            }
        }
        return logTag;
    }

    //時間戳轉date字符串
    public static String timestampToDate(Long timestamp){
        if(timestamp.toString().length() <13){
            timestamp = Long.valueOf(timestamp.toString().substring(0,10)+"000");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date date = new Date(timestamp);
        String dateStr = sdf.format(date);
        return dateStr;
    }

    //去掉包名,只保留類名
    private String classNameDeal(String allName){
        String[] className = allName.split("\\.");
        return className[className.length-1];
    }
}
相關文章
相關標籤/搜索