一、問題場景
使用Logger.error方法時只能打印出異常類型,無法打印出詳細的堆棧信息,使得定位問題變得困難和不方便。
二、先放出結論
Logger類下有多個不同的error方法,根據傳入參數的個數及類型的不同,自動選擇不同的重載方法。
當error(Object obj)只傳入一個參數時會將異常對象作為Object使用,並最終當做String打印出來,當使用兩個參數error(String message, Throwable t),且第二個參數為Throwable時,才會將完整的異常堆棧打印出來。
三、代碼示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
import
org.apache.logging.log4j.LogManager;
import
org.apache.logging.log4j.Logger;
/**
* @Author: LeeChao
* @Date: 2018/7/25
* @Describe:
* @Modified By:
*/
public
class
TestLogError {
public
static
final
Logger LOGGER = LogManager.getLogger(TestLogError.
class
);
public
static
void
main(String[] args) {
try
{
// 模擬空指針異常
//Integer nullInt = Integer.valueOf(null);
int
[] array = {
1
,
2
,
3
,
4
,
5
};
int
outBoundInt = array[
5
];
}
catch
(Exception e){
// 直接打印,則只輸出異常類型
LOGGER.error(e);
// 使用字符串拼接
LOGGER.error(
"使用 + 號連接直接輸出 e : "
+ e);
LOGGER.error(
"使用 + 號連接直接輸出 e.getMessage() : "
+ e.getMessage());
LOGGER.error(
"使用 + 號連接直接輸出 e.toString() : "
+ e.toString());
// 使用逗號分隔,調用兩個參數的error方法
LOGGER.error(
"使用 , 號 使第二個參數作為Throwable : "
, e);
// 嘗試使用分隔符,第二個參數為Throwable,會發現分隔符沒有起作用,第二個參數的不同據,調用不同的重載方法
LOGGER.error(
"第二個參數為Throwable,使用分隔符打印 {} : "
, e);
// 嘗試使用分隔符,第二個參數為Object,會發現分隔符起作用了,根據第二個參數的不同類型,調用不同的重載方法
LOGGER.error(
"第二個參數為Object,使用分隔符打印 {} "
,
123
);
}
}
}
|
信息輸出:
四、查看源碼中的方法描述
根據方法重載特性,當只輸入一個參數時,此對象會被當做Object進行打印輸出,如果是Exception e的話,這里直接就toString()。
1
2
3
4
5
6
|
/**
* Logs a message object with the {@link Level#ERROR ERROR} level.
*
* @param message the message object to log.
*/
void
error(Object message);
|
根據方法重載特性,當第二個參數為Throwable時,會打印出異常信息,並且包含異常堆棧信息。
1
2
3
4
5
6
7
8
|
/**
* Logs a message at the {@link Level#ERROR ERROR} level including the stack trace of the {@link Throwable}
* <code>t</code> passed as parameter.
*
* @param message the message object to log.
* @param t the exception to log, including its stack trace.
*/
void
error(String message, Throwable t);
|
根據方法重載特性,當第二個參數為Object時,會根據占位符進行替換並打印出錯誤日志。
1
2
3
4
5
6
7
|
/**
* Logs a message with parameters at error level.
*
* @param message the message to log; the format depends on the message factory.
* @param p0 parameter to the message.
*/
void
error(String message, Object p0);
|
五、結論
- 使用Logger.error(e)、Logger.error(e.getMessage())、Logger.error("some msg" + e)、Logger.error("some msg" + e.getMessage()) 都是調用的error(Object message),這個方法都會將入參當作Object輸出,不會打印堆棧信息。
- 在使用Logger.error("first param ",e)時會調用error(String message, Throwable t),此方法會完整的打印出錯誤堆棧信息。
- 原文: http://www.cnblogs.com/lingyejun/p/9366533.html