Java分析调试

打印文件名、类名、方法名、行号

IDE工具

Idea:可以通过快捷键模板生成打印信息:File=> Settings=> Editor=> Live Templates=>
本处我将打印类名、方法、行号的快捷键设为:soutd

线程栈

文件名:Thread.currentThread().getStackTrace()[1].getFileName()
类名:Thread.currentThread().getStackTrace()[1].getClassName()
方法名:Thread.currentThread().getStackTrace()[1].getMethodName()
文件名:Thread.currentThread().getStackTrace()[1].getLineNumber()

例如:可以在想要调试的地方直接调用以下语句

System.out.println(String.format("%s : %s : %s : %d", 
		Thread.currentThread().getStackTrace()[1].getFileName(),
		Thread.currentThread().getStackTrace()[1].getClassName(),
		Thread.currentThread().getStackTrace()[1].getMethodName(),
		Thread.currentThread().getStackTrace()[1].getLineNumber()));

可以直接将上边这个代码写到template,以dbg为快捷键。注意:取消选中:Use code formatter

讲解

Thread.currentThread().getStackTrace()返回值:StackTraceElement[],这是一个数组。

第0项:当前线程信息
第1项:当前方法执行的堆栈
第2项:调用者的堆栈

第1项和第2项的讲解

        如果想要把这个调试语句封装为类,则下标就得是2。代码如下

扫描二维码关注公众号,回复: 9134711 查看本文章
public class DBG {
    public static String getFileName() {
        return Thread.currentThread().getStackTrace()[2].getFileName();
    }
    
    public static String getClassName() {
        return Thread.currentThread().getStackTrace()[2].getClassName();
    }
    public static String getMethodName() {
        return Thread.currentThread().getStackTrace()[2].getMethodName();
    }

    public static int getLineNumber() {
        return Thread.currentThread().getStackTrace()[2].getLineNumber();
    }

    public static void printAll(String args[]) {
        System.out.println(getFileName() + " :" + 
                          getClassName() + " :" + 
                          getMethodName() + " :" +
                          getLineNumber());
    }
}

log4j2和log4j的区别

参考网址:http://www.cppcns.com/ruanjian/java/189006.html

1、配置文件类型

    log4j:是通过一个.properties的文件作为主配置文件的,而现在的
    log4j2:则已经弃用了这种方式,采用的是.xml,.json或者.jsn这种方式来做。

2、核心JAR包

log4j:log4j-1.2.17.jar
log4j2:log4j-api-2.13.0.jar 和 log4j-core-2.13.0.jar

        maven管理中,log4j和log4j2的包路径是不同的,Apache为了区分,包路径都更新了,大家甚至可以在一个项目中使用2个版本的日志!

3、文件渲染

log4j:在web.xml中进行配置

log4j2:比较简单,以maven工程为例,我们只需要把log4j2.xml放到工程resource目录下就行了。

4、调用

log4j:private final Logger LOGGER = Logger.getLogger(Test.class.getName());
log4j2:private static Logger logger = LogManager.getLogger(Test.class.getName());

log4j2

参考网址:

Log4j2 简明教程_Flyer的后花园-CSDN博客
log4j2使用教程 - 柠檬五个半 - 博客园
Eclipse使用Log4j2的详细教程_java,log4j2_Confused-KeKe-CSDN博客

配置文件

详细配置:https://www.docs4dev.com/docs/zh/log4j2/2.x/all/manual-configuration.html#XML

        log4j2依然包含三个组件,分别是 Logger(记录器)、Appender(输出目的地)、Layout(日志布局)。

        log4j2有默认的配置,如果要替换配置,只需要在classpath根目录下放置log4j2.xml。
        log4j 2.0与以往的1.x有一个明显的不同,其配置文件只能采用.xml, .json或者 .jsn。在默认情况下,系统选择configuration文件的优先级(classpath下):log4j-test.json/log4j-test.jsn > log4j2-test.xml > log4j.json/log4j.jsn > log4j2.xml

最简配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </Console>
    </Appenders>
 
    <Loggers>
        <Root level="trace">
            <Appender-ref ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

配置详解

<?xml version="1.0" encoding="UTF-8"?>
<!--status:设置log4j2自身内部的信息输出,可不设置,设置成trace时,会打印log4j2内部各种详细输出-->
<!--        高->低:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL -->
<!--monitorInterval:设置间隔秒数,最小为5s(不用写单位)。Log4j2能自动检测配置文件是否修改,若修改则重新配置,此项-->
<Configuration status="error">
    <!--先定义所有的appender -->
    <Appenders>
        <!-- 输出到控制台的配置 -->
        <!-- target:SYSTEM_OUT 或 SYSTEM_ERR,默认是SYSTEM_OUT -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 输出日志的格式 -->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </Console>

        <!--此文件会打印出所有信息 -->
        <!--append:TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件,默认值是true -->
        <File name="log" fileName="D:/logs/log4j2.log" append="false">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>

        <!--ThresholdFilter:过滤器,可输出某个级别以及以上的类别  -->
        <!--                onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝 -->  
        <File name="ERROR" fileName="D:/logs/error.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>


        <!--打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入文件并进行压缩,作为存档 -->
        <RollingFile name="RollingFile" fileName="D:/logs/web.log"
                     filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="2MB"/>
        </RollingFile>
    </Appenders>

    <!--然后定义logger,只有定义了logger并引入刚才的的appender配置,appender才会生效 -->
    <!--   若logger标签定义了level,则会覆盖root标签的level,否则使用root标签的level。见下边的 “指定特定类的输出” -->
    <Loggers>
        <Root level="trace">
            <Appender-ref ref="RollingFile"/>
            <Appender-ref ref="Console"/>
            <Appender-ref ref="ERROR" />
            <Appender-ref ref="log"/>
        </Root>
    </Loggers>
</Configuration>

 缺省配置(若没有提供自己的配置文件,log4j2会用此配置)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

指定特定类的输出

示例1:com.foo.Bar类下输出TRACE及以上到控制台外,其他只输出ERROR以上的日志。

配置:

<Console name="Console" target="SYSTEM_OUT">
    <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
    <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</Console>

<Loggers>
  <Logger name="com.foo.Bar" level="TRACE"/>
  <Root level="ERROR">
    <AppenderRef ref="Console">
  </Root>
</Loggers>

        因为com.foo.Bar没有自己的Appender,所以会使用ROOT的Appender。如果自己也配置了在控制台打印,就要注意可加性。如过com.foo.Bar如下配置,会打印两次。

<Logger name="com.foo.Bar" level="trace">
  <AppenderRef ref="Console"/>
</Logger>

示例2:com.foo.Bar的trace及以上只打印到文件,不打印到控制台

        如果不想使用Root的Appender,可以加上additivity="false"参数。
        (注意:additivity默认为true。下边配置文件中,如果不加additivity="false",则com.foo.Bar的trace及以上既打印到文件,又打印到控制台)。

<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <RollingFile name="RollingFile" fileName="${sys:user.home}/logs/trace.log"
                     filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
           ...
    </RollingFile>
  </Appenders>
  <Loggers>
    <Logger name="com.foo.Bar" level="trace" additivity="false">
      <AppenderRef ref="RollingFile"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

打印格式化日志信息

符号

含义

示例

%c或%class

列出logger名字空间全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间

假设当前logger名字空间是”a.b.c”

%c       a.b.c

%c{2}     b.c

%C

列出调用logger的类的全名(包含包路径)

假设当前类是”org.apache.xyz.SomeClass”

%C      org.apache.xyz.SomeClass

%C{1}    SomeClass

%d

 

输出日志时间点的日期或时间,默认格式为ISO8601,也可在其后指定格式,

比如:%d{yyyMMMddHH:mm:ss,SSS},

输出:2005/10/12 22:23:30,117

比如:%d{DATE}

输出:12 Oct 2005 22:23:30,117

{}内还可以选:ABSOLUTE,ISO8601等

%F

显示调用logger的类文件名

Myclass.java

%l

输出日志事件的发生位置,包括类目名、发生的线程,行数。

举例:Testlog4.main(TestLog4.java:10)

%L

显示调用logger的代码行

举例:10

%m或%msg

 

显示代码中指定的消息

 

%M

显示调用logger的方法名

 

%n

输出一个当下平台的换行符

 

%p

输出该条日志的优先级,即DEBUG,INFO...

 

%r

输出自应用启动到输出该日志已经经过的毫秒数

 

%t

输出产生该日志事件的线程名

 

%x

按NDC(Nested Diagnostic Context,线程堆栈)顺序输出日志

假设某程序Myapp调用com.foo.Bar

%c %x-%m%n

输出结果:

Myapp-Call com.foo.Bar

com.foo.Bar-Log in Bar

Myapp-Return to Myapp

%X

按MDC(Mapped Diagnostic Context,线程映射表)输出日志。通常用于多个客户端连接同一个服务器,方便服务器区分是哪个客户端访问留下的日志。

%X{5}  记录代号为5的客户端的日志

%%

显示一个百分号

 

ThresholdFilter

level:将被过滤的级别。
onMatch:默认值是NEUTRAL
onMismatch:默认是DENY

        如果LogEvent 中的 Log Level 大于 ThresholdFilter 中配置的 Log Level,那么返回 onMatch 的值, 否则返回 onMismatch 的值,例如 : 如果ThresholdFilter 配置的 Log Level 是 ERROR , LogEvent 的Log Level 是 DEBUG。 那么 onMismatch 的值将被返回, 因为 ERROR 小于DEBUG。如果是Accept,将自己被接受,而不经过下一个过滤器

把每个层次的日志保存到不同文件的方法

法1:

        <!-- 也可以把每个层次的都保存到特定文件,本处以debug和info举例,其他设置方法一样 -->
        <!-- 本法和上边方法选择一种。 -->
        <File name="MyDebugFile" fileName="logs/debug.log">
            <Filters>
                <!-- 第一步 onMatch="DENY":匹配到info及更高级别就禁止进入,其他的允许进入(向下继续操作) -->
                <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
                <!-- 第二步 onMatch="ACCEPT":匹配到debug及更高级别就ACCEPT,其他的 -->
                <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
                <!-- 经过两步过滤,把debug以上的和以下的级别全部过滤,最终剩下debug级别 -->
            </Filters>
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} %-6level [%t] (%F:%L) - %msg%n"/>
        </File>

        <File name="MyInfoFile" fileName="logs/info.log">
            <Filters>
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} %-6level [%t] (%F:%L) - %msg%n"/>
        </File>

法2

        下面的例子可以这样理解:如果是INFO级别及其以上,将经过通过第一个过滤,进入第二个,否则是onMismatch:拒绝进入。对于第二个,如果是大于等于WARN(WARN/ERROR/ERROR),那么将返回onMatch,也就是拒绝,如果是其他情况(也就是INFO),将是中立情况,因为后面没有其他过滤器,则被接受。最后的结果就只剩下INFO级别的日志。也就符合了RollingFileInfo只记录Info级别的规则。

<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
             filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
    <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->        
    <Filters>
        <ThresholdFilter level="INFO"/>
        <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
    </Filters>
    <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
    <Policies>
        <TimeBasedTriggeringPolicy interval="24" modulate="true"/>
        <SizeBasedTriggeringPolicy size="50 MB"/>
    </Policies>
    <DefaultRolloverStrategy max="20"/>
</RollingFile>

RollingFileAppender

    日志文件回滚,即删除最旧的日志文件,默认是3个文件。可以通过DefaultRolloverStrategy设置max参数为多个。

例如:

<Appenders>
    <RollingFile name="RollingFile" fileName="logs/app.log"
                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="20"/>
    </RollingFile>
</Appenders>

TimeBasedTriggeringPolicy:基于时间的rollover。
        其中一个参数是interval,表示多久滚动一次。默认是1 hour。
        modulate=true:调整时间:若现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am

SizeBasedTriggeringPolicy:如果大小大于某个阈值,上面是50MB的时候就会滚动。

简单示例

1.下载

下载地址:https://logging.apache.org/log4j/2.x/download.html
下载文件:apache-log4j-2.13.0-bin.zip   解压后得到:log4j-api-2.13.0.jar 和 log4j-core-2.13.0.jar

将其放到包路径(对于Eclipse是Build Path)

若使用maven:

<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
</dependency>

2.创建并设置配置文件

配置文件只能是这两个中的任意一个:log4j2.properties、log4j2.xml。Eclipse:放到src目录下。Idea:放到src\main\resource

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </Console>
 
        <File name="log" fileName="D:/logs/log4j2.log" append="false">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>
 
        <File name="ERROR" fileName="D:/logs/error.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>
 
        <RollingFile name="RollingFile" fileName="D:/logs/web.log"
                     filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="2MB"/>
        </RollingFile>
    </Appenders>
 
    <Loggers>
        <Root level="trace">
            <Appender-ref ref="RollingFile"/>
            <Appender-ref ref="Console"/>
            <Appender-ref ref="ERROR" />
            <Appender-ref ref="log"/>
        </Root>
    </Loggers>
</Configuration>

3.测试程序

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
 
public class log4j2Test {
    private static Logger logger= LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
 
    public static void main(String[] args) {
        logger.trace("log4j2日志输出:This is trace message.");
        logger.debug("log4j2日志输出:This is debug message.");
        logger.info("log4j2日志输出:This is info message.");
        logger.error("log4j2日志输出:This is error message.");
    }
}

3.测试结果

控制台输出

 log文件

log4j

基础教程

        Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。

一、定义配置文件

        其实您也可以完全不使用配置文件,而是在代码中配置Log4j环境。但是,使用配置文件将使您的应用程序更加灵活。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(键=值)。下面我们介绍使用xml特性文件做为配置文件的方法。

1.配置根Logger,其语法为:

log4j.rootLogger = [ level ] , appenderName, appenderName, …

        其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优 先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定 义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指日志信息输出到哪个地方。

        可同时指定多个输出目的地。例如:log4j.rootLogger=info,A1,B2,C3 配置了3个输出地方,这个名字可以任意(如上面的db),但必须与我们在后面进行的设置名字对应。见下边的使用示例。

2.配置日志信息输出目的地Appender,其语法为:

log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1

log4j.appender.appenderName.option = valueN
其中,Log4j提供的appender有以下几种:

org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

3.配置日志信息的格式(布局),其语法为:

log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1

log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以e几种:

org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

二、在代码中使用Log4j

1.得到记录器

使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:
public static Logger getLogger( String name)

通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:
static Logger logger = LogManager.getLogger ( ServerWithLog4j.class.getName () )

2.读取配置文件

当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:

BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。
PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件。
DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。

3.插入记录信息(格式化日志信息)

当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:

Logger.debug ( Object message ) ;
Logger.info ( Object message ) ;
Logger.warn ( Object message ) ;
Logger.error ( Object message ) ;

三、日志级别

每个Logger都被了一个日志级别(log level),用来控制日志信息的输出。日志级别从高到低分为:
A:off 最高等级,用于关闭所有日志记录。
B:fatal 指出每个严重的错误事件将会导致应用程序的退出。
C:error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
D:warn 表明会出现潜在的错误情形。
E:info 一般和在粗粒度级别上,强调应用程序的运行全程。
F:debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
G:all 最低等级,用于打开所有日志记录。

        上面这些级别是定义在org.apache.log4j.Level类中。Log4j只建议使用4个级别,优先级从高到低分别是error,warn,info和debug。通过使用日志级别,可以控制应用程序中相应级别日志信息的输出。例如,如果使用了info级别,则应用程序中所有低于info级别的日志信息(如debug)将不会被打印出来。

简单示例

        日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录。

1.下载

下载地址:http://logging.apache.org/log4j/1.2/download.html
下载文件:log4j-1.2.17.zip   解压后得到:log4j-1.2.17.jar

参考网址:https://www.cnblogs.com/caozx/p/11585239.html

对于maven:

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2.创建并设置配置文件

配置文件只能是这两个中的任意一个:log4j.properties、log4j.xml。Eclipse:放到src目录下。Idea:放到src\main\resource

本处以log4j.properties为例

log4j.properties

### 设置###
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

### 输出DEBUG 级别以上的日志到=E://logs/debug.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://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

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://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

3.编写测试程序

com.mucfc;
import org.apache.log4j.Logger;

public class Test {
    private static Logger logger = Logger.getLogger(Test.class);  

    public static void main(String[] args) {  
        // System.out.println("This is println message.");  

        // 记录debug级别的信息  
        logger.debug("This is debug message.");  
        // 记录info级别的信息  
        logger.info("This is info message.");  
        // 记录error级别的信息  
        logger.error("This is error message.");  
    }  
}

4.输出结果

(1)控制台结果

(2)输出文件及结果

Web项目中使用log4j实例

在J2EE应用使用Log4j,必须先在启动服务时加载Log4j的配置文件进行初始化,可以在web.xml中进行。

1、web应用的log4j使用基本上都采用:新建一个servlet,这个servlet在init函数中为log4j执行配置。一般就是读入配置文件。
     所以需要在web.xml中为这个servlet配置,同时设定load-on-startup为1。
2、这个servlet配置log4j就是读出配置文件,然后调用configure函数。
     这里有两个问题:一、需要知道文件在哪里;二、需要正确的文件类型
3、配置文件位置在web.xml中配置一个param即可,路径一般是相对于web的root目录
4、文件类型一般有两种,一个是Java的property文件,另一种是xml文件
    配置文件的大致内容:输出的log级别的最低等级,log的输出配置格式,每个log可以指定多个输出方式

(1)创建Web工程

log4j.properties放到src下,log4j库文件放到WebContent\WEB-INF\lib下。
说明:log4j.properties与上边一致即可。

(2)web.xml

xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns="http://java.sun.com/xml/ns/javaee"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
    id="WebApp_ID" version="3.0">  
    <display-name>LogLearning</display-name>  

    <servlet>  
        <servlet-name>Log4JTestServlet</servlet-name>  
        <servlet-class>com.mucfc.Log4JTestServlet</servlet-class>  
    </servlet>  

    <!--用来启动 log4jConfigLocation的servlet -->  
    <servlet>  
        <servlet-name>Log4JInitServlet</servlet-name>  
        <servlet-class>com.mucfc.Log4JInitServlet</servlet-class>  
        <init-param>  
            <param-name>log4j-properties-location</param-name>  
            <param-value>/WEB-INF/classes/log4j.properties</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  

    <servlet-mapping>  
        <servlet-name>Log4JTestServlet</servlet-name>  
        <url-pattern>/test</url-pattern>  
    </servlet-mapping>  

</web-app>

(3)web容器一来就初始化的servlet

Log4JInitServlet.java

/** 
 * Servlet implementation class Log4JInitServlet 
 */  
@WebServlet("/Log4JInitServlet")  
public class Log4JInitServlet extends HttpServlet {  
    private static final long serialVersionUID = 1L;  

    /** 
     * @see HttpServlet#HttpServlet() 
     */  
    public Log4JInitServlet() {  
        super();  
        // TODO Auto-generated constructor stub  
    }  

    /** 
     * @see Servlet#init(ServletConfig) 
     */  
    public void init(ServletConfig config) throws ServletException {  
        System.out.println("Log4JInitServlet 正在初始化 log4j日志设置信息");  
        String log4jLocation = config.getInitParameter("log4j-properties-location");  

        ServletContext sc = config.getServletContext();  

        if (log4jLocation == null) {  
            System.err.println("*** 没有 log4j-properties-location 初始化的文件, 所以使用 BasicConfigurator初始化");  
            BasicConfigurator.configure();  
        } else {  
            String webAppPath = sc.getRealPath("/");  
            String log4jProp = webAppPath + log4jLocation;  
            File yoMamaYesThisSaysYoMama = new File(log4jProp);  
            if (yoMamaYesThisSaysYoMama.exists()) {  
                System.out.println("使用: " + log4jProp+"初始化日志设置信息");  
                PropertyConfigurator.configure(log4jProp);  
            } else {  
                System.err.println("*** " + log4jProp + " 文件没有找到, 所以使用 BasicConfigurator初始化");  
                BasicConfigurator.configure();  
            }  
        }  
        super.init(config);  
    }  

    /** 
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
     */  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        // TODO Auto-generated method stub  
    }  

    /** 
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
     */  
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        // TODO Auto-generated method stub  
    }  

}

 调用日志Log4JTestServlet.java

package com.mucfc;  

/** 
 * Servlet implementation class Log4JTestServlet 
 */  
@WebServlet("/Log4JTestServlet")  
public class Log4JTestServlet extends HttpServlet {  
    private static final long serialVersionUID = 1L;  
    private static Logger logger = Logger.getLogger(Log4JTestServlet.class);    

    /** 
     * @see HttpServlet#HttpServlet() 
     */  
    public Log4JTestServlet() {  
        super();  
        // TODO Auto-generated constructor stub  
    }  

    /** 
     * @see Servlet#init(ServletConfig) 
     */  
    public void init(ServletConfig config) throws ServletException {  
        // TODO Auto-generated method stub  
    }  

    /** 
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
     */  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        // 记录debug级别的信息    
        logger.debug("This is debug message.");    
        // 记录info级别的信息    
        logger.info("This is info message.");    
        // 记录error级别的信息    
        logger.error("This is error message.");    
    }  

    /** 
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
     */  
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        doGet(request,response);  
    }  
}

Spring中使用log4j

(1)接上面的工程,然后再导入Spring的包

(2)web.xml增加

<context-param>    
       <param-name>webAppRootKey</param-name>    
       <param-value>webapp.root</param-value>    
   </context-param>    

   <context-param>  
    <param-name>log4jConfigLocation</param-name>  
    <param-value>/WEB-INF/classes/log4j.properties</param-value>  
</context-param>  
<!-- 3000表示 开一条watchdog线程每60秒扫描一下配置文件的变化;这样便于日志存放位置的改变 -->  
<context-param>    
        <param-name>log4jRefreshInterval</param-name>    
        <param-value>3000</param-value>    
   </context-param>   
<listener>  
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
</listener>

这里Log4JInitServlet.java就相当于没用到了。

(3)applicationContext.xml

没有内容:

<xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xsi:schemaLocation="    
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">  
</beans>
发布了126 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/103792015