zoukankan      html  css  js  c++  java
  • log4j手册

    在看hive源码的时候,因为对log4j不了解而苦于不知道该如何打印log来进行调试。虽然最后我选择了直接使用System.err.println来打印

    log,但是log4j是一个很好的log框架,在很多多线程系统中都有用到,所以值得花点时间好好学习下。

    简介:

    log4j是apache的一个开源项目,是一个流行的java log框架,如今已经有了c,c++,python,shell等各语言的相关版本,如使用于shell的log4shell.

    打印log是最简单和最直接的程序调试方法。即便如此,打印log有时却是唯一可以用的程序调试方法,尤其是对于大型的多线程或分布式系统。它们很难通过gdb等工具就进行单步调试。

    打印log是软件开发过程中非常重要的一环。log提供了程序的相关信息。丰富的log信息有利于对程序的了解与审核。当然log也有它的缺点,冗余的log影响了程序的执行效率,导致满屏的文字信息。正是基于这点的考虑,log4j被设计成可靠,快速而灵活的框架。log4j简单易用,可以方便的控制log的粒度,从而让程序员专注于主程序的业务逻辑。

    Loggers, Appenders and Layouts

    log4j由3个主要模块组成:loggers,appenders,layouts,开发人员通过这3个模块,控制程序运行时log输出的级别,目的地和格式等。

    logger层级

    log4j相较于直接使用System.out.println的最主要的一个优势是,它可以方便的控制在运行时哪些log生效而哪些log失效。这种能力是通过把log语句块根据用户定义的category(类别)划分到不同的logging空间来实现的。因此category在log4j中很重要的一个概念。

    loggers是一个具名实体。logger的名字是大小写敏感的,遵循层级命名规则。

    比如,名字为"com.foo"的logger是名字为"com.foo.Bar"的父亲,这种层级的命名方式对大多开发人员来说应该并不陌生。

    root logger处于logger层级的最顶层,它相对其它logger有两个特点,

    1. 1. root logger是必须存在的

    2. 2. 它不能通过名字来获取

    root logger只能通过静态方法Logger.getRootLogger来获取。其它的logger通过静态方法Logger.getLogger来获取,并且需要传递名字作为参数。

    Logger的基本方法的使用如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package org.apache.log4j;
      
      public class Logger {
      
        // Creation & retrieval methods:
        public static Logger getRootLogger();
        public static Logger getLogger(String name);
      
        // printing methods:
        public void trace(Object message);
        public void debug(Object message);
        public void info(Object message);
        public void warn(Object message);
        public void error(Object message);
        public void fatal(Object message);
      
        // generic printing method:
        public void log(Level l, Object message);
    }

    loggers具有level属性,默认的level集合为:TRACE,DEBUG,INFO,WARN,ERROR and FATAL。level集合在org.apache.log4j.level类中定义。我们可以通过继承level类来定义自己的level,但是我们并不鼓励这样做。

    如果一个logger没有指定level属性,那么它将继承离它最近的那个祖先的level。

    logging请求通过调用logger实例的打印方法实现,而打印方法决定了打印的level,如,c是一个logger实例,则c.info(...)将响应一条INFO级别的logging请求。logging请求只有在其level大于等于logger本身的level时才会被响应。

    这个规则是log4j的核心,它假定level之间是有序的。在标准级别中,DEBUG<INFO<WARN<ERROR<FATAL。

    如下代码体现了这一规则。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // get a logger instance named "com.foo"
       Logger  logger = Logger.getLogger("com.foo");
      
       // Now set its level. Normally you do not need to set the
       // level of a logger programmatically. This is usually done
       // in configuration files.
       logger.setLevel(Level.INFO);
      
       Logger barlogger = Logger.getLogger("com.foo.Bar");
      
       // This request is enabled, because WARN >= INFO.
       logger.warn("Low fuel level.");
      
       // This request is disabled, because DEBUG < INFO.
       logger.debug("Starting search for nearest gas station.");
      
       // The logger instance barlogger, named "com.foo.Bar",
       // will inherit its level from the logger named
       // "com.foo" Thus, the following request is enabled
       // because INFO >= INFO.
       barlogger.info("Located nearest gas station.");
      
       // This request is disabled, because DEBUG < INFO.
       barlogger.debug("Exiting gas station search");

    调用Logger.getLoggger方法时如果传入的是同一个名字参数,那么返回的将是同一个logger实例。所以即使不通过指针也可以在不同的代码段中调用同一个logger。与现实中的父子关系不同,log4j logger的创建和配置是没有顺序要求的,也就是说父logger可以后于子孙logger创建。

    logger的命名是完全自由的。一种比较好的做法是用所在类的类名来命名logger。这种简单的定义logger的方法非常管用。因为输出的log将携带创建该log的logger的名字信息。因此可以方便的识别出某条log是在哪个类中输出的。

    待续。。。。。。

  • 相关阅读:
    ASP.NET缓存全解析(系列)
    updateprogress用法技巧
    text与img对齐
    9款Firefox插件提高设计开发效率
    ASP.NET页面实时进行GZIP压缩优化
    如何收缩和删除SQL日志文件
    闲扯加班
    与大家分享一点游戏管理晋升的心得(完整版)
    FDS (Flex Data Services)
    和我老婆去旅游
  • 原文地址:https://www.cnblogs.com/simonote/p/3095274.html
Copyright © 2011-2022 走看看