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]; } }