??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
1. 能支持多个参敎ͼq过{} 占位W进行替换,避免老写logger.isXXXEnabled q种无奈的判断,带来性能提升见:http://www.slf4j.org/faq.html#logging_performance ?/span>
2.OSGI 机制更好兼容支持
一图胜千言Q官|上的一个图Q?/p>
常用输出格式
%c 列出logger名字I间的全Uͼ如加上{<层数>}表示Z最内层v的指定层数的名字I间
%X 按MDCQMapped Diagnostic Context,U程映射表)输出日志。通常用于多个客户端连接同一台服务器Q方便服务器区分是那个客L讉K留下来的日志?br />
%p 日志信息U别
%d %d{<日期格式>}:日志信息产生旉,使用ISO8601定义的日期格?br />
%C 日志信息所在地Q全限类名)
%m 产生的日志具体信?br />
%n 输出日志信息换行
%F 昄调用logger的源文g?br />
%l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数
%L 昄调用logger的代码行
%M 昄调用logger的方法名
%r 昄从程序启动时到记录该条日志时已经l过的毫U数
%t 输出产生该日志事件的U程?br />
%% 昄一?/p>
获取logger
Logger.getRootLogger() 获取根logger
Logger.getLogger(String name)获取子logger
Logger.getLogger(Class clazz)?br />
Logger.getLogger(clazz.getName())
讄日志U别(.setLevel(int,Exception))
Level.ALL打开所有日?br />
Level.DEBUG 用于调试
Level.INFO 用于q行q程
Level.WARN 用于潜在的错?br />
Level.ERROR 用于错误事g
Level.FATAL 用于严重错误旉
Level.OFF 关闭所有日?/p>
输出端Appender(.addAppender(Appender).setAdditivity(boolean additive)是否覆盖)
org.apache.log4j.ConsoleAppender 输出到控制台
targer:
ConsoleAppender.SYSTEM_OUT(Default)
ConsoleAppender.SYSTEM_ERR
public ConsoleAppender(Layout)
public ConsoleAppender(Layout,String targer)
org.apache.log4j.FileAppender 输出到文?br />
public FileAppender(Layout,String fileName)
public FileAppender(Layout,String fileName,boolean append)是否覆盖
org.apache.log4j.DailyRollingFileAppender 输出到文?每天一个新文g
org.apache.log4j.RollingFileAppender 输出到文?自动新增改名
public RollingFileAppender(Layout,String fileName)
void setMaxBackupIndex(int index) 讄日志文g最大备份数
void setMaximumFileSize(long size) 讄日志文g最大尺?br />
org.apache.log4j.WriterAppender 格式输出到L地方
org.apache.log4j.JDBCAppender 输出到数据库
日志格式?Layout)
%c cd?br />
%d 旉
%f cd
%l 位置
%m 信息
%n 换行
%p U别
%r 耗时
%t U程?/p>
public PatternLayout() 使用默认讄DEFAULT_CONVERSION_PATTERN 只打C?br />
public PatternLayout(String)使用自定义的pattern构造一个PatternLayout
void setConversionPattern(String) 讄日志格式
HTMLLayout
SimpleLayout
5.
1.BasicConfigurator.configure()
PatternLayout p = new PatternLayout("%p [%t] %c (%F:%L) - %m%n");
ConsoleAppender a = new ConsoleAppender(p,ConsoleAppender.SYSTEM_OUT);
root.addAppender(a);
rootLogger.setLevel(Level.DEBUG);
2.PropertyConfigurator.configure("/help/example.properties")
String resource = "/help/example.properties";
URL configFileResource = Log4J.class.getResource(resource);
PropertyConfigurator.configure(configFileResource);
3.DOMConfigurator.configure("/help/example.xml")
xml declaration and dtd
|
log4j:configuration
|
+-- appender (name, class)
| |
| +-- param (name, value)
| +-- layout (class)
| |
| +-- param (name, value)
+-- logger (name, additivity)
| |
| +-- level (class, value)
| | |
| | +-- param (name, value)
| +-- appender-ref (ref)
+-- root
|
+-- param (name, class)
+-- level
| |
| +-- param (name, value)
+-- appender-ref (ref)
0.log4j.properties模板
log4j.rootLogger=info,CONSOLE,RFILE,FILE,DB 讄U别和三个输出端
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out 控制台类?br />
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= %4p [%t] (%F:%L) - %m%n
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=/help/my.properties 目标文g
log4j.appender.FILE.Append=false 是否q加
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 布局模式
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %c:%L - %m%n 格式化布局
log4j.appender.RFILE=org.apache.log4j.RollingFileAppender
log4j.appender.RFILE.File=/help/my.properties 目标文g
log4j.appender.RFILE.MaxFileSize=1KB 最大长?br />
log4j.appender.RFILE.MaxBackupIndex=3 最多备?br />
log4j.appender.RFILE.layout=org.apache.log4j.PatternLayout 布局模式
log4j.appender.RFILE.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %c:%L - %m%n 格式化布局
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:oracle:thin:@127.0.0.1:1521:mumu URL
log4j.appender.DB.driver=oracle.jdbc.driver.OracleDriver 驱动
log4j.appender.DB.user=liulibo 用户?br />
log4j.appender.DB.password=liulibo 密码
log4j.appender.DB.layout=org.apache.log4j.PatternLayout 布局模式
log4j.appender.DB.layout.ConversionPattern=insert into log4j(createdate,thread,level_,class,message) values(\'%d\',\'%t\',\'%-5p\',\'%c\',\'%m\')
create table log4j(createdate varchar2(32),thread varchar2(32),level_ varchar2(32),class varchar2(32),message varchar2(32));
0.XML模板
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n"/>
</layout>
</appender>
<appender name="RollingFileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="false"/>
<param name="MaxFileSize" value="1KB"/>
<param name="File" value="dom/my.log"/>
<param name="MaxBackupIndex" value="3"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n"/>
</layout>
</appender>
<appender name="JDBCAppender" class="org.apache.log4j.jdbc.JDBCAppender">
<param name="URL" value="jdbc:oracle:thin:@127.0.0.1:1521:mumu"/>
<param name="user" value="liulibo"/>
<param name="password" value="liulibo"/>
<param name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="insert into log4j(createdate,thread,level_,class,message) values(\'%d\',\'%t\',\'%-5p\',\'%c\',\'%m\')"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
<appender-ref ref="JDBCAppender"/>
</root>
</log4j:configuration>
应用
web.xml
<context-param>
<param-name>props</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>cart.listener.SCServletContextListener</listener-class>
</listener>
初始化方法中d
private void initLog4j(ServletContext context){
String prefix = context.getRealPath("/");
System.out.println("prefix:"+prefix);
String props = context.getInitParameter("props");
if(props != null) {
PropertyConfigurator.configure(prefix+props);
}
Logger logger = Logger.getLogger(SCServletContextListener.class);
}
import org.apache.log4j.Logger;
public class MyClass {
/*
* Obtain a logger for a message category. In this case, the message category is
* the fully qualified class name of MyClass.
*/
private static final Logger logger = Logger.getLogger(MyClass.class.getName());
...
public void myMethod() {
...
if (logger.isDebugEnabled()) {
logger.debug("Executing with parameters: " + param1 + ":" + param2);
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="fileAppender" class="org.apache.log4j.FileAppender">
<param name="File" value="log.txt"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
<category name="com.ambrosesoft.log.MyClass">
<priority value="error"/>
<appender-ref ref="fileAppender"/>
</category>
<root>
<priority value="debug"/>
<appender-ref ref="fileAppender"/>
</root>
</log4j:configuration>
import org.apache.log4j.Logger;
public interface Loggers {
Logger performance = Logger.getLogger("performance");
Logger security = Logger.getLogger("security");
Logger business = Logger.getLogger("business");
}
...
public class MyClass {
....
if (Loggers.security.isWarnEnabled()) {
Loggers.security.warn("Access denied: Username [" + userName + "] ...");
}
...
}
import javax.servlet.Filter;
...
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.log4j.MDC;
public class LoggerFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Retrieves the session object from the current request.
HttpSession session = ((HttpServletRequest)request).getSession();
// Put the username into the diagnostic context.
// Use %X{username} in the layout pattern to include this information.
MDC.put("username", session.getAttribute("username"));
// Continue processing the rest of the filter chain.
chain.doFilter(request, response);
// Remove the username from the diagnostic context.
MDC.remove("username");
}
...
}
import org.apache.log4j.Logger;
import java.lang.reflect.Field;
public aspect AutoTrace {
private static final Logger logger = Logger.getLogger(AutoTrace.class);
pointcut publicMethods() : execution(public * com.ambrosesoft..*(..));
pointcut loggableCalls() : publicMethods();
/**
* Inspect the class and find its logger object. If none is found, use
* the one defined here.
*/
private Logger getLogger(org.aspectj.lang.JoinPoint joinPoint) {
try {
/*
* Try to discover the logger object.
* The logger object must be a static field called logger.
*/
Class declaringType = joinPoint.getSignature().getDeclaringType();
Field loggerField = declaringType.getField("logger");
loggerField.setAccessible(true);
return (Logger)loggerField.get(null);
} catch(NoSuchFieldException e) {
/*
* Cannot find a logger object, use the internal one.
*/
return logger;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
/**
* An aspect to log method entry.
*/
before() : loggableCalls(){
getLogger(thisJoinPoint).debug("Entering.." + thisJoinPoint.getSignature().toString());
}
/**
* An aspect to log method exit.
*/
after() : loggableCalls(){
getLogger(thisJoinPoint).debug("Exiting.." + thisJoinPoint.getSignature().toString());
}
}
*
* Configure Log4J library and periodically monitor log4j.xml for any update.
*/
DOMConfigurator.configureAndWatch("/apps/config/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 name="fileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="log.txt"/>
<param name="Append" value="true"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
...
</log4j:configuration>
一、ؓ多个目指定使用哪个log4j文g
情况一Q多个小目合成一个大目Q多个小目有自׃同的入口Q这个时候如果用同一个log4j文gQ各个项目的?br>Z混ؕ在一P如果拆分成多个小目Q看h又比较散不太好管理?br>情况二:一个项目实施在linux上,~写在windows?log4j的输出目?opt/xxx/web.log
q个时候开发者被q必d本机的workspace所在的目录加入一个opt/xxx/web.log的目录和文g
同时Q大多数情况下linux上的服务是不要输出log到ConsoleQ只要输出到文g
而windows大部份是只须要输出到consoleQ不要输出到文?br>本地调试的时候log4j的别多是debug ,而实际实施的时候多是之上的U别
造成要不停的修改log4j的属性文?cvs同步的时候不停的提示
也许你说可以整个目完成再来写log4j的属性文Ӟ但有的时候这个效果ƈ不好?br>因ؓq有q种时候,目完成Q包括logQ,反复试的这D|间?/p>
解决Q解军_法很单,建立一个log4j的配制文件的目录Q在q个目录下ؓ每个项目徏立一个目录,
每个目录下放着自己的log4j配制,然後把这些目录作为每个小工程的classpath的第一个,ok上边的问题就
解决了。这个时候可以写一个log4j攑֜src下,用来开发时候调试用Q而真正服务器上用的都在各自的文件夹?/p>
?为默写包Q某些类定义不同的log4jU别
是否惌q中需求呢Q一个项目调试的时候,希望其中默写包不打出log信息?br>比如struts的包Qspring的包Q还有你引用的别人已l开发好包,或者你自己写的c,但是你不想看到这?br>cȝlog信息.但是你须要调试当前的一些classQlogU别必须讄在debugU别
q个时候可以在log4j的属性文件中加入如下内容:
log4j.logger.包名orcd=高的U别
例如:
log4j.logger.org.springframework=error
三、注意事?br> if (logger.isDebugEnabled()) {
4 logger.debug(getStr());
5 }
解决的办法自然是惛_法用相对路径代替l对路径Q其实log4j的FileAppender本n有q样的机Ӟ如:
log4j.appender.logfile.File=${WORKDIR}/logs/app.log
其中?{WORKDIR}/”是个变量,会被System Property中的“WORKDIR”的gѝ这P我们可以在log4j加蝲配置文g之前Q先用System.setProperty讄好根路径?/p>
?没有发现q个技巧之前,Z解决q个问题Q我曾自己扩展了log4j的RollingFileAppenderc,其他的FileAppender同样?理。扩展的ҎQ就是用一个子cd覆盖setFileҎQ这个方法在log4jd配置文g生成appender的时候调用,传入的就是配|文件中的\ 径,q样我就可以按照自己的想法在路径前面加上根\径了?br />
2.
可以使用环境变量
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.base}/logs/logs_tomcat.log
log4j.appender.R.MaxFileSize=10KB
3.具体实现:一般在我们开发项目过E中,log4j日志输出路径固定到某个文件夹,q样如果我换一个环?日志路径又需要重C?比较不方?目前我采用了动态改变日志\径方法来实现相对路径保存日志文g
(1).在项目启动时,装入初始化类:public class Log4jInit extends HttpServlet {
static Logger logger = Logger.getLogger(Log4jInit.class);public Log4jInit() {
}public void init(ServletConfig config) throws ServletException {
String prefix = config.getServletContext().getRealPath("/");
String file = config.getInitParameter("log4j");
String filePath = prefix + file;
Properties props = new Properties();
try {
FileInputStream istream = new FileInputStream(filePath);
props.load(istream);
istream.close();
//toPrint(props.getProperty("log4j.appender.file.File"));
String logFile = prefix + props.getProperty("log4j.appender.file.File");//讄路径
props.setProperty("log4j.appender.file.File",logFile);
PropertyConfigurator.configure(props);//装入log4j配置信息
} catch (IOException e) {
toPrint("Could not read configuration file [" + filePath + "].");
toPrint("Ignoring configuration file [" + filePath + "].");
return;
}}public static void toPrint(String content) {
System.out.println(content);
}}(2).Web.xml中的配置<servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>WEB-INF/classes/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
最后决?在项目中选择W二U比较方?/div>
]]>
Log4J的配|文?Configuration File)是用来讄记录器的U别、存攑֙和布局的,它可接key=value格式的设|或xml格式的设|信息。通过配置Q可以创建出Log4J的运行环境?br />
1. 配置文g
Log4J配置文g的基本格式如下:
### set log levels ###
log4j.rootLogger = info,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 = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = 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 = 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