使用日志系统有很多种方式,最常见有logback一套,log4j一套等,以下是log4j这一套的使用说明(Maven工程)。另外,此处只是介绍一种可以使用日志系统的方式,以此还有很多引申出来的概念和其他使用方式没有做详细的介绍,可以自行百度扩展。最后会将一下本人在使用的时候遇到的问题。
一、使用步骤
1.加载对用的包
2.增加log的配置文件
3.在类中使用
二、详细使用说明:
1.在.pom文件中加载对应的包,最初使用时会想,为什么使用Log4j海的引入slf相关包,这个可以自行百度一下(类似与jdbc的模式);
<!--slf4j-Log4j驱动包 会自动添加4个对应包 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.6</version>
</dependency>
2.增加配置文件:
a.配置文件有两种使用方式,xml文件或者properties文件,以下是对xml使用的示例,另外一种可以百度以下其配置格式即可。
b.配置文件的存放位置也有两种,一种是直接存放到resource目录下工程加载时会自动去读取;第二种是自行定义存放位置,自己写listener类去加载,这种方式还可以配置文件刷新时间等,可以百度一下如何完成;这里是直接存放到resource下的示例,文件(2个)可以直接拷贝使用,但需需改一下自己日志的存放路径(这里是存放到tomcat的日志记录中,关于日志记录的存放方式可绝对路径、也可以放到项目路径下等,这些有那些优劣也可以百度了解),文件见文章最后的附件。
c.另外,这里的配置已经够使用了,若需配置自己喜欢的打印格式或者日志级别(5个级别打印不同日志)(这里是error级别)设置,可以在xml中改变和增加。
3.使用示例
a.声明:一般声明为private static final 标识只为本类使用,也不用多次new不同对象浪费内存,注意在import包的时候引org.apache.log4j包,另外还有中声明方式是LoggerFactory.getLogger()方法,这个就是使用的slf的接口,至于为什么,可以搜索一下slf 和 log4j的关系(类似于jdbc的模式)。
b.使用:使用的时候直接在catch中如下使用即可。
private static Logger logger = Logger.getLogger(xx.class.getName());
logger.info(e.getMessage());
logger.error(e.getMessage());
logger.debug(e.getMessage());
logger.fatal(e.getMessage());
logger.warn(e.getMessage());
三、在使用的过程中遇到的问题
本人在使用的过程中,由于刚开始使用java的log包,发现这个职能使用logger.info方法,后来又改为使用logback方法,再后来使用Log4j。
就出现在使用@postConstruct的类A中去使用Loooger时总是报错,找不到Log的类文件导致该类初始化失败,在其他类中使用不报错,但是当A类使用到其他类中有Log类时也报同样的错。
于是就开始找,pom是否对,Extennal Libraries包中有没有这几个包,发现是有的。没再怀疑是保不存在这个问题,开始怀疑是不是@postConstruct特性,导致在加载A类的时候Log类还没有加载,所以就开始想办法去手动加载Logger类,1.在web.xml中配置启动就加载,2.手动使用Class.forname在使用Log前加载,还是报同样的找不到类的错误,3.还想过但没试Listeher,或者实现HttpServlet,在init方法中加入A类需要实现的功能,是因为在遇到这个问题的时候去深入学习了一下累的加载机制和servlet的声明周期,觉得不是因为类没有加载。
最后的最后,折腾了一天,发现target中没有log相关的几个包,哎,然后又是一顿删掉pom中的dependency文件 删除target 重启idea,target终究还是没有这几个包。最后只有从新创建一个工程,将文件拷进去,发现好使了,最后的总结是,可能是之前使用多种方式的时候引入的包间依赖或者是什么有问题,哎。
四、关于使用log4j的一些常用问题的官方回答
http://logging.apache.org/log4j/1.2/faq.html#noconfig
附件
文件1(log4j.xml顶部会引用第二个文件)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- appender -->
<appender name="console_appender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n" />
</layout>
</appender>
<appender name="monitor_appender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/suggestion/monitor.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n" />
</layout>
</appender>
<appender name="biz_file_appender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/suggestion/biz.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d{HH:mm:ss}] %c - %m%n" />
</layout>
</appender>
<appender name="stdout_file_appender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/suggestion/stdout.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d{HH:mm:ss}] %c - %m%n"/>
</layout>
</appender>
<appender name="sql_file_appender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/suggestion/sql.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d{HH:mm:ss}] %c - %m%n"/>
</layout>
</appender>
<appender name="error_file_appender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/suggestion/stderr.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%-5p] [%d{HH:mm:ss}] %c - %m%n"/>
</layout>
</appender>
<!--记录到文件-->
<root>
<level value="ERROR"/>
<appender-ref ref="console_appender"/>
<appender-ref ref="monitor_appender"/>
<appender-ref ref="biz_file_appender"/>
<appender-ref ref="stdout_file_appender"/>
<appender-ref ref="sql_file_appender"/>
<appender-ref ref="error_file_appender"/>
</root>
</log4j:configuration>
文件2(log4j.dtd)
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Authors: Chris Taylor, Ceki Gulcu. -->
<!-- Version: 1.2 -->
<!-- A configuration element consists of optional renderer
elements,appender elements, categories and an optional root
element. -->
<!ELEMENT log4j:configuration (renderer*, appender*,plugin*, (category|logger)*,root?,
(categoryFactory|loggerFactory)?)>
<!-- The "threshold" attribute takes a level value below which -->
<!-- all logging statements are disabled. -->
<!-- Setting the "debug" enable the printing of internal log4j logging -->
<!-- statements. -->
<!-- By default, debug attribute is "null", meaning that we not do touch -->
<!-- internal log4j logging settings. The "null" value for the threshold -->
<!-- attribute can be misleading. The threshold field of a repository -->
<!-- cannot be set to null. The "null" value for the threshold attribute -->
<!-- simply means don't touch the threshold field, the threshold field -->
<!-- keeps its old value. -->
<!ATTLIST log4j:configuration
xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
threshold (all|trace|debug|info|warn|error|fatal|off|null) "null"
debug (true|false|null) "null"
reset (true|false) "false"
>
<!-- renderer elements allow the user to customize the conversion of -->
<!-- message objects to String. -->
<!ELEMENT renderer EMPTY>
<!ATTLIST renderer
renderedClass CDATA #REQUIRED
renderingClass CDATA #REQUIRED
>
<!-- Appenders must have a name and a class. -->
<!-- Appenders may contain an error handler, a layout, optional parameters -->
<!-- and filters. They may also reference (or include) other appenders. -->
<!ELEMENT appender (errorHandler?, param*,
rollingPolicy?, triggeringPolicy?, connectionSource?,
layout?, filter*, appender-ref*)>
<!ATTLIST appender
name CDATA #REQUIRED
class CDATA #REQUIRED
>
<!ELEMENT layout (param*)>
<!ATTLIST layout
class CDATA #REQUIRED
>
<!ELEMENT filter (param*)>
<!ATTLIST filter
class CDATA #REQUIRED
>
<!-- ErrorHandlers can be of any class. They can admit any number of -->
<!-- parameters. -->
<!ELEMENT errorHandler (param*, root-ref?, logger-ref*, appender-ref?)>
<!ATTLIST errorHandler
class CDATA #REQUIRED
>
<!ELEMENT root-ref EMPTY>
<!ELEMENT logger-ref EMPTY>
<!ATTLIST logger-ref
ref CDATA #REQUIRED
>
<!ELEMENT param EMPTY>
<!ATTLIST param
name CDATA #REQUIRED
value CDATA #REQUIRED
>
<!-- The priority class is org.apache.log4j.Level by default -->
<!ELEMENT priority (param*)>
<!ATTLIST priority
class CDATA #IMPLIED
value CDATA #REQUIRED
>
<!-- The level class is org.apache.log4j.Level by default -->
<!ELEMENT level (param*)>
<!ATTLIST level
class CDATA #IMPLIED
value CDATA #REQUIRED
>
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named category. -->
<!ELEMENT category (param*,(priority|level)?,appender-ref*)>
<!ATTLIST category
class CDATA #IMPLIED
name CDATA #REQUIRED
additivity (true|false) "true"
>
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named logger. -->
<!ELEMENT logger (level?,appender-ref*)>
<!ATTLIST logger
name CDATA #REQUIRED
additivity (true|false) "true"
>
<!ELEMENT categoryFactory (param*)>
<!ATTLIST categoryFactory
class CDATA #REQUIRED>
<!ELEMENT loggerFactory (param*)>
<!ATTLIST loggerFactory
class CDATA #REQUIRED>
<!ELEMENT appender-ref EMPTY>
<!ATTLIST appender-ref
ref CDATA #REQUIRED
>
<!-- plugins must have a name and class and can have optional parameters -->
<!ELEMENT plugin (param*, connectionSource?)>
<!ATTLIST plugin
name CDATA #REQUIRED
class CDATA #REQUIRED
>
<!ELEMENT connectionSource (dataSource?, param*)>
<!ATTLIST connectionSource
class CDATA #REQUIRED
>
<!ELEMENT dataSource (param*)>
<!ATTLIST dataSource
class CDATA #REQUIRED
>
<!ELEMENT triggeringPolicy ((param|filter)*)>
<!ATTLIST triggeringPolicy
name CDATA #IMPLIED
class CDATA #REQUIRED
>
<!ELEMENT rollingPolicy (param*)>
<!ATTLIST rollingPolicy
name CDATA #IMPLIED
class CDATA #REQUIRED
>
<!-- If no priority element is specified, then the configurator MUST not -->
<!-- touch the priority of root. -->
<!-- The root category always exists and cannot be subclassed. -->
<!ELEMENT root (param*, (priority|level)?, appender-ref*)>
<!-- ==================================================================== -->
<!-- A logging event -->
<!-- ==================================================================== -->
<!ELEMENT log4j:eventSet (log4j:event*)>
<!ATTLIST log4j:eventSet
xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
version (1.1|1.2) "1.2"
includesLocationInfo (true|false) "true"
>
<!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?,
log4j:locationInfo?, log4j:properties?) >
<!-- The timestamp format is application dependent. -->
<!ATTLIST log4j:event
logger CDATA #REQUIRED
level CDATA #REQUIRED
thread CDATA #REQUIRED
timestamp CDATA #REQUIRED
time CDATA #IMPLIED
>
<!ELEMENT log4j:message (#PCDATA)>
<!ELEMENT log4j:NDC (#PCDATA)>
<!ELEMENT log4j:throwable (#PCDATA)>
<!ELEMENT log4j:locationInfo EMPTY>
<!ATTLIST log4j:locationInfo
class CDATA #REQUIRED
method CDATA #REQUIRED
file CDATA #REQUIRED
line CDATA #REQUIRED
>
<!ELEMENT log4j:properties (log4j:data*)>
<!ELEMENT log4j:data EMPTY>
<!ATTLIST log4j:data
name CDATA #REQUIRED
value CDATA #REQUIRED
>