1、log4j日志參數說明
log4j.appender.ERROR.layout.ConversionPattern=[%p][%l] %d{yyyy-MM-dd HH:mm:ss} %m%n
格式輸出修改成:
log4j.appender.INFO.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - [%p] - [%l] - [ %m ]%n
時間-事件級別-打印日志的詳細信息-消息內容
p log事件的級別。
l log發生位置的詳細描述,包括方法名、文件名及行號。
d 時間和日期的輸出格式,例如:%d{yyyy MM dd HH:mm:ss,SS},可不帶后面的日期格式字符。
m log事件的消息內容
n 根據所運行的平台輸出相應的行分隔字符。
2、在一個對象中通常只使用一個Logger對象,Logger應該是static final的,只有在少數需要在構造函數中傳遞logger的情況下才使用private final。
private static final org.slf4j.Logger logger =
LoggerFactory.getLogger(TemperatureDetectionController.class);
如果使用com.leelen.esafe.utils.Logger,則日志輸出的具體類將不能體現。
之前寫法:Logger.info(TAG + ":" + JSON.toJSONString(cmds));
調用LoggerUtil的類,並且要手動獲取類名,拼接字符串才能顯示具體的類名
3.輸出Exceptions的全部Throwable信息,因為logger.error(msg)和logger.error(msg,e.getMessage())這樣的日志輸出方法會丟失掉最重要的StackTrace信息。
try {
throw new Exception("測試日志");
}catch (Exception e){
logger.info(e.getMessage());//錯誤
logger.info("輸入日志1",e.getMessage());//錯誤
logger.info("輸入日志2",e);//正確
}
4、不允許記錄日志后又拋出異常,因為這樣會多次記錄日志,只允許記錄一次日志。
try {
}catch (Exception e){
logger.info("輸入日志",e);
throw new BusinessException(1,e.getMessage());
}
5、不允許出現System print(包括System.out.println和System.error.println)語句。
System.out.println(e.getMessage());//錯誤
System.err.println(e.getMessage());//錯誤
logger.info("輸入日志",e);//正確
System.out日志打印不可控制、打印時間無法確定、不能添加過濾器、日志沒有級別區分4、不允許出現printStackTrace。
try {
throw new Exception("222");
}catch (Exception e){
e.printStackTrace();//錯誤
logger.info("輸入日志",e);//正確
}
為什么盡量不用e.printStackTrace
主要原因有以下幾點:
1、占用太多內存,造成鎖死
要打印字符串輸出到控制台上,需要字符串常量池所在的內存塊有足夠的空間。然而,因為e.printStackTrace() 語句要產生的字符串記錄的是堆棧信息,太長太多,內存被填滿了!大量線程產出字符串產出到一半,等待有內存被釋放,鎖死了,導致整個應用掛掉了。
代碼本身有問題,很多情況下拋異常 -> e.printStackTrace() 來打印異常到控制台 -> 產生錯誤堆棧字符串到字符串池內存空間 -> 此內存空間一下子被占滿了 -> 開始在此內存空間產出字符串的線程還沒完全生產完整,就沒空間了 -> 大量線程產出字符串產出到一半,等在這兒(等有內存了繼續搞啊)-> 相互等待,等內存,鎖死了,整個應用掛掉了。
2、日志交錯混合,不易讀
printStackTrace()默認使用了System.err輸出流進行輸出,與System.out是兩個不同的輸出流,那么在打印時自然就形成了交叉。再就是輸出流是有緩沖區的,所以對於什么時候具體輸出也形成了隨機。
6、日志正確的寫法
logger.error("測試日志{}{}",”參數1”, "參數2");//正確
logger.error("測試日志{}",”參數1”, e);//正確
logger.error("測試日志"+”參數1”);//錯誤
Logger.info("讀取字節數組成文件失敗:" + e);//錯誤
//錯誤,重復輸出日志
//錯誤,不用+號拼接字符串的方式 改用占位符{}
可以減少參數構造的開銷。
調試階段的日志可用DEBUG級別的日志輸出或者去掉無意義的日志輸出:
7、log4j日志級別說明
log4j定義了8個級別的log(除去OFF和ALL,可以說分為6個級別),優先級從高到低依次為:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
ALL 最低等級的,用於打開所有日志記錄。
TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志級別,一般不會使用。
DEBUG 指出細粒度信息事件對調試應用程序是非常有幫助的,主要用於開發過程中打印一些運行信息。
INFO 消息在粗粒度級別上突出強調應用程序的運行過程。打印一些你感興趣的或者重要的信息,這個可以用於生產環境中輸出程序運行的一些重要信息,但是不能濫用,避免打印過多的日志。
WARN 表明會出現潛在錯誤的情形,有些信息不是錯誤信息,但是也要給程序員的一些提示。
ERROR 指出雖然發生錯誤事件,但仍然不影響系統的繼續運行。打印錯誤和異常信息,如果不想輸出太多的日志,可以使用這個級別。
FATAL 指出每個嚴重的錯誤事件將會導致應用程序的退出。這個級別比較高了。重大錯誤,這種級別你可以直接停止程序了。
OFF 最高等級的,用於關閉所有日志記錄。
1、log4j日志參數說明log4j.appender.ERROR.layout.ConversionPattern=[%p][%l] %d{yyyy-MM-dd HH:mm:ss} %m%n
格式輸出修改成:log4j.appender.INFO.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - [%p] - [%l] - [ %m ]%n
時間-事件級別-打印日志的詳細信息-消息內容
p log事件的級別。l log發生位置的詳細描述,包括方法名、文件名及行號。d 時間和日期的輸出格式,例如:%d{yyyy MM dd HH:mm:ss,SS},可不帶后面的日期格式字符。m log事件的消息內容n 根據所運行的平台輸出相應的行分隔字符。
在一個對象中通常只使用一個Logger對象,Logger應該是static final的,只有在少數需要在構造函數中傳遞logger的情況下才使用private final。
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(TemperatureDetectionController.class);
如果使用com.leelen.esafe.utils.Logger,則日志輸出的具體類將不能體現。
之前寫法:Logger.info(TAG + ":" + JSON.toJSONString(cmds));調用LoggerUtil的類,並且要手動獲取類名,拼接字符串才能顯示具體的類名
3.輸出Exceptions的全部Throwable信息,因為logger.error(msg)和logger.error(msg,e.getMessage())這樣的日志輸出方法會丟失掉最重要的StackTrace信息。
try { throw new Exception("測試日志");}catch (Exception e){ logger.info(e.getMessage());//錯誤 logger.info("輸入日志1",e.getMessage());//錯誤 logger.info("輸入日志2",e);//正確}
4、不允許記錄日志后又拋出異常,因為這樣會多次記錄日志,只允許記錄一次日志。try { }catch (Exception e){ logger.info("輸入日志",e); throw new BusinessException(1,e.getMessage());}
5、不允許出現System print(包括System.out.println和System.error.println)語句。System.out.println(e.getMessage());//錯誤System.err.println(e.getMessage());//錯誤logger.info("輸入日志",e);//正確
System.out日志打印不可控制、打印時間無法確定、不能添加過濾器、日志沒有級別區分4、不允許出現printStackTrace。try { throw new Exception("222");}catch (Exception e){ e.printStackTrace();//錯誤 logger.info("輸入日志",e);//正確}
為什么盡量不用e.printStackTrace主要原因有以下幾點:1、占用太多內存,造成鎖死要打印字符串輸出到控制台上,需要字符串常量池所在的內存塊有足夠的空間。然而,因為e.printStackTrace() 語句要產生的字符串記錄的是堆棧信息,太長太多,內存被填滿了!大量線程產出字符串產出到一半,等待有內存被釋放,鎖死了,導致整個應用掛掉了。
代碼本身有問題,很多情況下拋異常 -> e.printStackTrace() 來打印異常到控制台 -> 產生錯誤堆棧字符串到字符串池內存空間 -> 此內存空間一下子被占滿了 -> 開始在此內存空間產出字符串的線程還沒完全生產完整,就沒空間了 -> 大量線程產出字符串產出到一半,等在這兒(等有內存了繼續搞啊)-> 相互等待,等內存,鎖死了,整個應用掛掉了。
2、日志交錯混合,不易讀printStackTrace()默認使用了System.err輸出流進行輸出,與System.out是兩個不同的輸出流,那么在打印時自然就形成了交叉。再就是輸出流是有緩沖區的,所以對於什么時候具體輸出也形成了隨機。
6、日志正確的寫法logger.error("測試日志{}{}",”參數1”, "參數2");//正確logger.error("測試日志{}",”參數1”, e);//正確
logger.error("測試日志"+”參數1”);//錯誤Logger.info("讀取字節數組成文件失敗:" + e);//錯誤
//錯誤,重復輸出日志//錯誤,不用+號拼接字符串的方式 改用占位符{}可以減少參數構造的開銷。
調試階段的日志可用DEBUG級別的日志輸出或者去掉無意義的日志輸出:
7、log4j日志級別說明log4j定義了8個級別的log(除去OFF和ALL,可以說分為6個級別),優先級從高到低依次為:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。ALL 最低等級的,用於打開所有日志記錄。TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志級別,一般不會使用。DEBUG 指出細粒度信息事件對調試應用程序是非常有幫助的,主要用於開發過程中打印一些運行信息。INFO 消息在粗粒度級別上突出強調應用程序的運行過程。打印一些你感興趣的或者重要的信息,這個可以用於生產環境中輸出程序運行的一些重要信息,但是不能濫用,避免打印過多的日志。WARN 表明會出現潛在錯誤的情形,有些信息不是錯誤信息,但是也要給程序員的一些提示。ERROR 指出雖然發生錯誤事件,但仍然不影響系統的繼續運行。打印錯誤和異常信息,如果不想輸出太多的日志,可以使用這個級別。FATAL 指出每個嚴重的錯誤事件將會導致應用程序的退出。這個級別比較高了。重大錯誤,這種級別你可以直接停止程序了。OFF 最高等級的,用於關閉所有日志記錄。