上一篇我们观察了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” 这样不清不楚的信息,而且非常不利于排查问题,当你排查问题正需要看到某个对象的信息,却发现这样的日志输出,恐怕会长叹一声吧,所以最好还是按照规范来,避免这种情况。