上一篇我們觀察了System.out.println()方式打印簡單類對象信息的一些注意事項,本篇我們仍以Person類爲例看一下Log4j下對這種對象的處理。
《二》採用Log4j打印對象信息:
首先引入Log4j的jar包,本篇採用的是
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
然後配置Log4j,把log4j.properties放到maven項目的resources目錄下:
### 設置###
log4j.rootLogger = debug,stdout,D,E
### 輸出信息到控制擡 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File =E:/test0serv/test01serv/logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E:/test0serv/test01serv/logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
測試用例代碼:
import org.apache.log4j.Logger;
public class Person {
private static Logger logger = Logger.getLogger(Person.class);
private int age;
private String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String[] args) {
Person p = new Person(22, "Allen");
System.out.println("System.out.println:");
System.out.println(p);
System.out.println("org.apache.log4j.Logger:");
logger.info(p);
}
}
程序運行輸出結果爲:
System.out.println:
Person@17d0685f
org.apache.log4j.Logger:
[INFO ] 2018-08-05 18:51:47,458 method:Person.main(Person.java:22)
Person@17d0685f
生成的log中的信息如下圖:
可以看出在Person類沒有重寫 toString()函數的情況下,Log4j的輸出對象信息和System.out.println是一致的,都不能明確打印出對象的成員信息。下面我們重寫Object類中的toString()函數:
import org.apache.log4j.Logger;
public class Person {
private static Logger logger = Logger.getLogger(Person.class);
private int age;
private String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "年齡:" + age + ";名字:" + name;
}
public static void main(String[] args) {
Person p = new Person(22, "Allen");
System.out.println("System.out.println:");
System.out.println(p);
System.out.println("org.apache.log4j.Logger:");
logger.info(p);
}
}
程序運行結果爲:
System.out.println:
年齡:22;名字:Allen
org.apache.log4j.Logger:
[INFO ] 2018-08-05 19:03:33,970 method:Person.main(Person.java:27)
年齡:22;名字:Allen
log文檔中也打印出了對象的信息:
下面我們刪除重寫的toString()函數,改成使用Lombok插件試一試效果:
import lombok.Data;
import org.apache.log4j.Logger;
@Data
public class Person {
private static Logger logger = Logger.getLogger(Person.class);
private int age;
private String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public static void main(String[] args) {
Person p = new Person(22, "Allen");
System.out.println("System.out.println:");
System.out.println(p);
System.out.println("org.apache.log4j.Logger:");
logger.info(p);
}
}
程序輸出結果:
System.out.println:
Person(age=22, name=Allen)
org.apache.log4j.Logger:
[INFO ] 2018-08-05 19:07:38,808 method:Person.main(Person.java:23)
Person(age=22, name=Allen)
log文檔中也有對應的信息:
經過測試,我們想說的是,在定義一個類時,如果沒有使用Lombok類似功能的插件,最好按照JDK文檔的建議,實現Object類中的toString()函數,這樣在打印日誌對象的時候,不會出現打印出“Person@17d0685f” 這樣不清不楚的信息,而且非常不利於排查問題,當你排查問題正需要看到某個對象的信息,卻發現這樣的日誌輸出,恐怕會長嘆一聲吧,所以最好還是按照規範來,避免這種情況。