(2) 在log4j.xml中如下配置:
<appender name="PROJECT" class="org.apache.log4j.FileAppender">
<param name="file" value="${myApp.root}/logs/mylog.log"/>
<param name="append" value="false"/>
<param name="encoding" value="utf-8"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
这样就可以实现日志输出目录的动态配置了!
如果配置的是配置文件,需要如下的配置:
log4j.appender.info.File=${myApp.root}/WEB-INF/logs/info.log
(3) 注意:要将log4j.xml或log4j.property放在WEB-INF目录下面,如果放在通常的classes下面的话会有一个问题,当Tomcat启动的时候,Log4j会到classes下面去找这个配置 文件,然后因为这时候还没有设置系统变量,那么就会报找不到对应文件的错误了!但其实这个错误是不会影响接下来的功能,就是为了避免出现这个异常将配置文件放到WEB-INF下面。
在log4j 1.2.8 的api中JDBCAppender类的说明中有一段红字
WARNING: This version of JDBCAppender is very likely to be
completely replaced in the future. Moreoever, it does
not log exceptions.
1. 在mysql中创建库logdb
create database;
2. 在库logdb中创建表muglog,
create table muglog{
id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
logdate DATE,
logger VARCHAR(50),
priority VARCHAR(50),
message VARCHAR(255)
};
3. 修改log4j.properties
### 限制com.bob.digester(名:dig)才会log on JDBCAppender ###
log4j.logger.com.bob.digester=info, dig
log4j.appender.dig=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.dig.URL=jdbc:mysql://localhost/logdb
log4j.appender.dig.driver=com.mysql.jdbc.Driver
log4j.appender.dig.user=root
log4j.appender.dig.password=
log4j.appender.dig.sql=INSERT INTO MUGLOG (LOGDATE, LOGGER, PRIORITY, MESSAGE) VALUES ('%d', '%c', '%p', '%m')
log4j.appender.dig.layout=org.apache.log4j.PatternLayout
4. 注意,这里mysql的driver是mysql-connector-java-3.0.14-production-bin.jar里的com.mysql.jdbc.Driver
所以,把它放到classpath里, 如在Eclipse测试,需放到project的java build path的Libraries里
1. log4j的一个简单例子
把日志输出到MySQL数据库
Hello.java
import org.apache.log4j.*;
public class Hello {
static Logger logger = Logger.getLogger(Hello.class);
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties");
logger.info("Entering Application");
for(int i = 1; i < 10; i++) {
logger.debug("" + i);
}
logger.info("Exit Application");
}
}
log4j.properties
log4j.rootLogger=DEBUG,DATABASE
log4j.addivity.org.apache=true
########################
# JDBC Appender
#######################
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.URL=jdbc:mysql://127.0.0.1:3306/JAVA002?characterEncoding=utf8
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=username
log4j.appender.DATABASE.password=123
log4j.appender.DATABASE.sql=INSERT INTO log4j(DATE, THREAD, LEVEL, CLASS, MESSAGES) VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%t', '%p', '%l', '%m')
四、log4j与Commons-logging的结合
Jakarta Commons Logging (JCL)提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具。它提供给中间件/日志工具开发者一个简单的日志操作抽象,允许程序开发人员使用不同的具体日志实现工具。用户被假定已熟悉某种日志实现工具的更高级别的细节。JCL提供的接口,对其它一些日志工具,包括Log4J, Avalon LogKit, and JDK 1.4等,进行了简单的包装,此接口更接近于Log4J和LogKit的实现。
log4j与commons-logging两个包,都是记日志的,为什么要两个一起用呢? commons-logging是为"所有的Java日志实现"提供一个统一的接口,它自身的日志功能平常弱,而log4j功能非常强大全面,所以拿两者配合使用。
强调一点,“同时使用commons-logging和Log4j”,与“单独使用Log4j”相比,并不会带来更大的学习、配置和维护成本,反而更加简化了我们的工作。
Commons-logging提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密耦合,很贴心的帮开发者自动选择适当的日志实现系统,它甚至不需要配置。
commons-logging工作原理:
1. 首先在classpath下寻找自己的配置文件commons-logging.properties中当前factory中名叫org.apache.commons.logging.Log配置属性的值,如果找到,则使用其中定义的Log实现类。
2. 如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log对应的值,找到则使用其定义的Log实现类。
建立一个叫 :CATALINA_OPTS 的环境变量 .commons.logging.simplelog.defaultlog = warn |
3. 查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类则,使用相关的包装(wrapper)类(Log4JLogger)。
4. 使用JDK自身的日志实现类(JDK1.4以后才有日志实现类) ,使用相关的包装类(Jdk14Logger)。
5. 使用commons-logging自己提供的一个简单的日志实现类SimpleLog 。
org.apache.commons.logging.Log的具体实现有如下:
-org.apache.commons.logging.impl.Jdk14Logger //使用JDK1.4。
-org.apache.commons.logging.impl.Log4JLogger //使用Log4J。
-org.apache.commons.logging.impl.LogKitLogger //使用 avalon-Logkit。
-org.apache.commons.logging.impl.SimpleLog
common-logging自带日志实现类。它实现了Log接口,把日志消息都输出到系统错误流System.err 中。
-org.apache.commons.logging.impl.NoOpLog common-logging自带日志实现类。它实现了Log接口。 其输出日志的方法中不进行任何操作。
总之,commons-logging总是能找到一个日志实现类,并且尽可能找到一个"最合适"的日志实现类。
1、可以不需要配置文件。
2、自动判断有没有Log4j包,有则自动使用之。
3、最悲观的情况下也总能保证提供一个日志实现(SimpleLog)。
为了简化配置commons-logging,一般不使用commons-logging的配置文件,也不设置与commons-logging相关的系统环境变量,而只需将Log4j的Jar包放置到classpash中就可以了。这样就很简单地完成了commons-logging与Log4j的融合。如果不想用Log4j了怎么办?只需将classpath中的Log4j的Jar包删除即可。
因为Log4j的强大,同时开发者又不希望对Log4j的依赖性太强。所以目前比较流行的是Commons-logging和Log4j结合使用。
1. 部署日志器
下载commons-logging.jar和log4j.jar包,能后把它们放到工程的lib目录下,引入工程中。
2. 指定日志器
在属性文件common-logging.properties中设置实现接口的类。如下(这里设置Log4j为所使用的日志包):
#commons-logging.properties文件配置信息 #org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog # Must be one of ("trace", "debug", "info", "warn", "error", or "fatal"). #利用log4j为输出介质 org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JCategoryLog #JDK5 Logger #org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger |
3.org.apache.commons.logging.Log接口中定义的方法,按严重性由高到低的顺序有:
log.fatal(Object message); log.fatal(Object message, Throwable t); log.error(Object message); log.error(Object message, Throwable t); log.warn(Object message); log.warn(Object message, Throwable t); log.info(Object message); log.info(Object message, Throwable t); log.debug(Object message); log.debug(Object message, Throwable t); log.trace(Object message); log.trace(Object message, Throwable t); |
除此以外,还提供下列方法以便代码保护。
log.isFatalEnabled(); log.isErrorEnabled(); log.isWarnEnabled(); log.isInfoEnabled(); log.isDebugEnabled(); log.isTraceEnabled(); |
4.信息级别
确保日志信息在内容上和反应问题的严重程度上的恰当,是非常重要的。
1)fatal非常严重的错误,导致系统中止。期望这类信息能立即显示在状态控制台上。
2)error其它运行期错误或不是预期的条件。期望这类信息能立即显示在状态控制台上。
3)warn使用了不赞成使用的API、非常拙劣使用API, '几乎就是'错误, 其它运行时不合需要和不合预期的状态但还没必要称为 "错误"。期望这类信息能立即显示在状态控制台上。
4)info运行时产生的有意义的事件。期望这类信息能立即显示在状态控制台上。
5)debug系统流程中的细节信息。期望这类信息仅被写入log文件中。
6)trace更加细节的信息。期望这类信息仅被写入log文件中。
通常情况下,记录器的级别不应低于info.也就是说,通常情况下debug的信息不应被写入log文件中。