LoggerFactory(slf4j)与log4j的一点积累

       有的时候看过的文章也要通过自己的语言表达出来才更加又印象,日志文件是一个开发人员的好助手,一般是使用log4j或者slf4j+log4j的组合。相对log4j可能更为大家所耳闻,通过它可以控制日志信息输送的目的地是控制台、文件等,它获取logger的方式是:

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

       log4j中有一个NDC采用了一个类似栈的机制来push存储上下文信息,每一个线程都独立地储存上下文信息。比如说一个servlet就可以针对每一个request创建对应的NDC,储存客户端地址等等信息。存储相关的信息使用NDC.push(message),然后在打印日志的时候将信息输出。在相应的PatternLayout中使用”%x”来输出存储的上下文信息。

 <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

     Log4J为同一类别的线程生成一个Logger,多个线程共享使用,而它仅在日志信息中添加能够区分不同线程的信息。NDC是什么?举例来说,如果一个Servlet接到并发请求时,为每一个客户端创建一个新的线程,然后分配一个用于保存该请求上下文的NDC堆栈。该上下文可能是发出请求的主机名、IP地址或其它任何可以用于标识该请求的信息。这样,由于不同的客户端处理线程具有不同的NDC堆栈,即使这个Servlet同时生成多个线程处理不同的请求,这些日志信息仍然可以区分出来,就好像Log4J为每一个线程都单独生成了一个Logger实例一样,它是使用DNC来实现的:

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

       那么要讲讲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里面有:

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

  4. singleImplementationSanityCheck()-特定类存在判断

  5. 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>

发现自己项目里只有log4j,原因是slf4j和log4j都是依赖log4j库。

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

猜你喜欢

转载自blog.csdn.net/LCF_lxf_ldy/article/details/82558172