日志:log4j与slf4j

log4j

通过它可以控制日志信息输送的目的地是控制台、文件等,它获取logger的方式是:

static Logger logger = Logger.getLogger ( XXXXj.class.getName () );

log4j中有两个主要的类:NDC(Nested Diagnostic Context)和MDC(Mapped Diagnostic Context),它们用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。

NDC采用了一个类似栈的机制来push和pop上下文信息,每一个线程都独立地储存上下文信息。比如说一个servlet就可以针对每一个request创建对应的NDC,储存客户端地址等等信息。

当使用的时候,我们要尽可能确保在进入一个context的时候,把相关的信息使用NDC.push(message);在离开这个context的时候使用NDC.pop()将信息删除。另外由于设计上的一些问题,还需要保证在当前thread结束的时候使用NDC.remove()清除内存,否则会产生内存泄漏的问题。

1、 在进入一个环境时调用NDC.push(String),然后就创建了一个NDC;
NDC.push(Msg.toString());
2、所做的日志操作输出中包括了NDC的信息;
3、离开该环境时调用NDC.pop方法
NDC.pop();
4、当从一个线程中退出时调用NDC.remove方法,以便释放资源。

存储了上下文信息之后,我们就可以在log的时候将信息输出。在相应的PatternLayout中使用”%x”来输出存储的上下文信息,下面是一个PatternLayout的例子:

%r [%t] %-5p %c{2} %x - %m%n

 <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyy-MM-dd HH\:mm\:ss,SSS} %p %c{1}(%L) - %m%n"/>
</layout>

或者在log4j.properties文件中作如下的配置即可:

log4j.appender.console.layout.ConversionPattern=%-d{yyyy/MM/dd HH:mm:ss,SSS} [%X] -[%c]-[%p] %m%n

使用NDC最重要的好处就是,当我们想输出一些上下文的信息的时候,不需要让logger去寻找这些信息,而只需要在适当的位置进行存储,然后再配置文件中修改PatternLayout。在最新的log4j 1.3版本中增加了一个org.apache.log4j.filters.NDCMatchFilter,用来

根据NDC中存储的信息接受或拒绝一条log信息

MDC和NDC非常相似,所不同的是MDC内部使用了类似map的机制来存储信息,上下文信息也是每个线程独立地储存,所不同的是信息都是以它们的key值存储在”map”中。相对应的方法,MDC.put(key, value); MDC.remove(key); MDC.get(key); 在配置PatternLayout的时候使用:%x{key}来输出对应的value。同样地,MDC也有一个org.apache.log4j.filters.MDCMatchFilter。这里需要注意的一点,MDC是线程独立的,但是一个子线程会自动获得一个父线程MDC的copy。

至于选择NDC还是MDC要看需要存储的上下文信息是堆栈式的还是key/value形式的。

动态修改日志配置

在开发过程中,我们经常会遇到修改log4j配置的情况,在这种情况下,频繁重启应用显然是不可接受的。幸好log4j提供了自动重新加载配置文件的能力,在配置文件修改后,便会自己重新加载配置。在1.2及以前的版本中DOMConfigurator和PropertyConfigurator都提供了configureAndWatch方法,对指定的配置文件进行监控,并且可以设置检查的间隔时间

slf4j

它是为java简单打印日志的工具,但是不是一个日志的实现,而是一个抽象层,允许在后台使用任何一个日志类库。使用SLF4J可以使得日志独立于任何一个特定的日志实现,这意味着不需要管理多个日志配置或者多个日志类库,因为提供了统一的记录日志的接口,对不同日志系统的具体实现进行了抽象化,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过绑定具体的日志系统来实现。还是log4j没有的优点,SLF4J支持{}作为占位符,等价于C语言中的%s,而不必再进行字符串的拼接,节省字符串的内存消耗。

SLF4J获取logger的方式是通过LoggerFactory,LoggerFactory主要是用来打印日志的,一般使用

 private static final Logger logger = LoggerFactory.getLogger(XXXServiceImpl.class);
 
//打印异常信息 throws Throwable
logger.error(throwable.getMessage(), throwable);
//一般是将捕捉到的Exception对象作为日志记录的最后一个参数
(会显示具体的出错信息以及出错位置),
而且要放在{}可以格式化的参数之外,防止被{}转为e.toString()

来指定类初始化的日志对象,在日志输出的时候可打印日志输出所在的类。LoggerFactory里面有:

getLogger()-获取日志对象
getILoggerFactory()-获取真实的日志工厂
performInitialization()-初始化日志操作

singleImplementationSanityCheck()-特定类存在判断

bind()-绑定获取真实的日志处理类

        如果是使用maven来管理项目,就在pom.xml中添加SLF4J JAR包的依赖,然后在需要的地方添加一个log4j.properties的配置文件。

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.1</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.1</version>
</dependency>

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值