Java日志体系概览 关于Java的日志API可以概括为日志记录的封装API和日志记录实现两类。前一种的典型代表是Apache Commons Logging和SLF4J，后一种的典型代表有JDK自带的日志实现（java.util.logging 包，JUL）以及著名的Log4j。日志封装API是为日志使用者提供了一种统一的接口，使用者可以根据需求来切换具体日志实现方案。 Java日志API 一般来说，日志API一般包括： 记录器（Logger）：日志 API 的使用者通过记录器来发出日志记录请求，并提供日志的内容。在记录日志时，需要指定日志的严重性级别。 格式化器（Formatter）：对记录器所记录的文本进行格式化，并添加额外的元数据。 处理器（Handler）：把经过格式化之后的日志记录输出到不同的地方。常见的日志输出目标包括控制台、文件和数据库等。 Java日志封装API 在这主要介绍一下目前使用较多的SLF4J日志库，SLF4J 库中核心的 API 是提供工厂方法的 org.slf4j.LoggerFactory 类和记录日志的 org.slf4j.Logger 接口。通过 LoggerFactory 类的 getLogger 方法来获取日志记录器对象。Logger 接口中的方法也是按照不同的严重性级别来进行分组的。 参考：Java日志最佳实践 Jeesite中Log4j的使用分析 Jeesite中使用了Log4j日志记录作为实现，下面依次分析一下Log4j的配置文件和封装了Log4j的Manager类。 Log4j的配置 Log4j支持使用Java properties和xml作为配置文件。相对于xml的格式，Java properties更易读。下面以Jeesite中的log4j.properties为例，所有配置项均以log4j开头，主要配置项为rootlogger,输出终端，输出布局模式。 log4j.rootLogger=WARN, Console, RollingFile Logger是日志记录器，而rootLogger则是所有Logger的祖先，可以通过Logger.getRootLogger()来获取。 #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n #RollingFile log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.RollingFile.File=../logs/jeesite.log log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n Log4j的输出终端，由Appender接口定义。其有多种实现，不同实现就对应则不同的日志输出保存方式。例如： ConsoleAppender(控制台) FileAppender(文件) DailyRollingFileAppender(每天都产生一个日志文件) RollingFileAppender(文件大小达到指定尺寸时产生一个新的日志文件，文件名称上会自动添加数字序号。) WriterAppender(将日志信息以流的格式发送到任意指定的地方) 而所有子类Logger均将继承父类Logger的Appender配置。 至于输出布局模式——由Layout接口定义——也有多种实现： PatternLayout（可以灵活地指定布局模式） HTMLLayout（以HTML表格形式布局） SimpleLayout（包含日志信息的级别和信息字符串） TTCCLayout（包含日志产生的时间、线程、类别等信息） ConversionPattern使用的是类似于C语言中printf的格式化输出参数： %c：输出所属的类目，通常就是所在类的全名。 %d：输出日志时间点的日期或时间，默认格式为ISO8601，推荐使用“%d{ABSOLUTE}” %t：输出产生该日志线程的线程名。 %p：输出优先级。 %m：输出代码中指定的消息。 %n：输出一个回车换行符。Windows平台为“\r\n”，UNIX为“\n”。 所以jeesite中的日志输出格式为： Output pattern : date [thread] priority category - message FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 每个Logger都有一个日志记录级别，对应不同程度的信息，按照优先级可以排列如下：ALL<DEBUG<INFO<WARN<ERROR<FATAL<OFF #Hibernate level #log4j.logger.org.hibernate=ERROR log4j.logger.org.hibernate.cache.ehcache.AbstractEhcacheRegionFactory=ERROR log4j.logger.org.hibernate.search.impl.ConfigContext=ERROR log4j.logger.net.sf.ehcache.config.CacheConfiguration=ERROR #Project defalult level log4j.logger.com.thinkgem.jeesite=DEBUG 这里分别配置了Hibernate操作数据库的日志记录级别和项目的默认日志记录级别，均为DEBUG,即与程序运行时的流程相关的详细信息。 Log4jManager类 Log4jManager类对于Log4j，主要是对于Log4j的日志记录级别进行管理配置。使用了叫JMX（Java Management Extensions，即Java管理扩展）——一个为应用程序、设备、系统等植入管理功能的框架——对日志记录级别进行管理。此处把Log4j作为Mbean（管理Bean组件）来管理。首先来看一些Getters/Setters函数 @ManagedAttribute(description = "Level of the root logger") public String getRootLoggerLevel() { Logger logger = Logger.getRootLogger(); return logger.getEffectiveLevel().toString(); } @ManagedAttribute public void setRootLoggerLevel(String newLevel) { Logger logger = Logger.getRootLogger(); Level level = Level.toLevel(newLevel); logger.setLevel(level); managerLogger.info("设置Root Logger 级别为{}", newLevel); } 这是对根日志记录器进行日志级别设置和获取。managerLogger对象是通过LoggerFactory.getLogger(Log4jManager.class)这一日志记录器工厂来获取的。 @ManagedOperation(description = "Get logging level of the logger") @ManagedOperationParameters({ @ManagedOperationParameter(name = "loggerName", description = "Logger name") }) public String getLoggerLevel(String loggerName) { Logger logger = Logger.getLogger(loggerName); return logger.getEffectiveLevel().toString(); } /** * 设置Logger的日志级别. * 如果日志级别名称错误, 设为DEBUG. */ @ManagedOperation(description = "Set new logging level to the logger") @ManagedOperationParameters({ @ManagedOperationParameter(name = "loggerName", description = "Logger name"), @ManagedOperationParameter(name = "newlevel", description = "New level") }) public void setLoggerLevel(String loggerName, String newLevel) { Logger logger = Logger.getLogger(loggerName); Level level = Level.toLevel(newLevel); logger.setLevel(level); managerLogger.info("设置{}级别为{}", loggerName, newLevel); } 同根Logger一样，此处的普通Logger和项目级别的Logger的Setter\Getter方法，也是大同小异的。 SYS模块中的Log部分 这部分的日志log，并未使用日志记录API，而是通过正常模块开发的形式，把一些操作信息存入数据库表（sys_log）中，其保存的信息包含： private String id; // 日志编号 private String type; // 日志类型（1：接入日志；2：错误日志） private User createBy; // 创建者 private Date createDate; // 日志创建时间 private String remoteAddr; // 操作用户的IP地址 private String requestUri; // 操作的URI private String method; // 操作的方式 private String params; // 操作提交的数据 private String userAgent; // 操作用户代理信息 private String exception; // 异常信息 日志查询可以在登录后台系统后，通过host/sys/log这个url来访问。