精华内容
下载资源
问答
  • slf4j+log4j结合使用

    万次阅读 多人点赞 2018-04-03 11:05:11
    参考网址:1、http://www.cnblogs.com/ywlaker/p/6124067.html 2、http://www.cnblogs.com/xing901022/p/4149524.html 3、http://www.cnblogs.com/olmlo/p/3143468.html 4http://www.open-open.com/lib/vi...

    这里借鉴了很多大牛们的观点和资料,参考网址:

    1、http://www.cnblogs.com/ywlaker/p/6124067.html 

    2、http://www.cnblogs.com/xing901022/p/4149524.html 

    3、http://www.cnblogs.com/olmlo/p/3143468.html 

    4、http://www.open-open.com/lib/view/open1418652677495.html 

    5、http://www.cnblogs.com/eflylab/archive/2007/01/11/618001.html 


    一、slf4j介绍

     SLF4J是为各种loging APIs提供一个简单统一的接口,从而使得最终用户能够在部署的时候配置自己希望的loging APIs实现。Logging API实现既可以选择直接实现SLF4J接口的loging APIs如: logback、SimpleLogger。也可以通过开发相应的适配器来使用已有的API实现如Log4jLoggerAdapter、JDK14LoggerAdapter。

     SLF4J 不依赖任何特殊的class loader机制,实际上,SLF4J 和已有日志实现的绑定是在编译时静态执行的,具体绑定工作是通过一个jar包实现的,使用时只要把相应的jar包(只有一个)放到类路径上即可.

     在 SLF4J发行版本中包含了几个jar包,如slf4j-nop.jar, slf4j-simple.jar, slf4j-log4j12.jar, slf4j-log4j13.jar, slf4j-jdk14.jar and slf4j-jcl.jar等.SLF4J支持多个日志系统,比如NOP, Simple, log4j version 1.2, log4j version 1.3, JDK 1.4 logging, JCL and logback。

        使用slf4j尽管很方便,但是让很多人搞不明白slf4j那么多包怎么用。其实slf4j原理很简单,他只提供一个核心slf4j api(就是slf4j-api.jar包),这个包只有日志的接口,并没有实现,所以如果要使用就得再给它提供一个实现了些接口的日志包,比 如:log4j,common logging,jdk log日志实现包等,但是这些日志实现又不能通过接口直接调用,实现上他们根本就和slf4j-api不一致,因此slf4j又增加了一层来转换各日志实 现包的使用,当然slf4j-simple除外。其结构如下:

    slf4j-api(接口层)|
    各日志实现包的连接层( slf4j-jdk14, slf4j-log4j)|
    各日志实现包

    下面这个图更能说明其原理:

    在这里还需要注意的是,连接层的jar包和实现的jar的版本要一致。

    slf4j的构造是通过工厂类生存,我们调用接口时,接口的工厂会自动寻找恰当的实现,返回一个实现的实例给我服务。这些过程都是透明化的,用户不需要进行任何操作。

    loging APIs的接口,

    关于上述所述的“实现查找符合自己接口的实现类”,对于slf4j其实同通过加载器的方式自动来实现。具体的详细实现可以参考:http://www.cnblogs.com/xing901022/p/4149524.html 

    关于JVM加载器,可以参考下图理解:

    二、slf4j具体使用

    Logger logger = LoggerFactory.getLogger(name);

    或者

    Logger logger = LoggerFactory.getLogger(calss.class);

    这样就可使用logger对象进行日志输出。

    slf4j只提供了debug、warn、info、error等几个简单的接口,但由于slf4j只是接口,其具体实现是有对应的实现类完成。所以在在使用slf4j时都是和相应日志实现一起使用。

    常用的使用有:slf4j+log4j、slf4j+Logback等

    三、log4j介绍

    Log4J是Apache的一个开放源代码的项目。通过使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格式,或通过定义每一条日志信息的级别,更加细致地控制日志的生成过程。

    Log4j的组成:
    Log4j由三个重要的组成构成:日志记录器(Loggers),输出端(Appenders)和日志格式化器(Layout)。
    Logger:控制要启用或禁用哪些日志记录语句,并对日志信息进行级别限制:Appenders指定了日志将打印到控制台还是文件中;而Layout则控制日志信息的显示格式。

    A).Logger对象的获得或创建
    Logger被指定为实体,由一个String类的名字识别。Logger的名字是大小写敏感的,且名字之间具有继承关系,子名用父名作为前缀,用点“.”分隔,例如x.y是x.y.z的父亲。
    root Logger(根Logger)是所有Logger的祖先,它有如下属性:
    1.它总是存在的。
    2.它不可以通过名字获得。
    root Logger可以通过以下语句获得:

    public  static Logger Logger.getRootLogger();

    或:

    public  static Logger Logger.getLogger(Class clazz)

    其中调用Logger.getLogger(Class clazz)是目前ogger对象最理想的方法。

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

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

    package log4j;
    import org.apache.log4j.BasicConfigurator;
    import org.apache.log4j.Level;
    import org.apache.log4j.Logger;
    public  class Log4jTest  {
        public static void main(String[] args) {   
            Logger logger = Logger.getLogger(Log4jTest.class);        
            //使用默认的配置信息,不需要写log4j.properties
            BasicConfigurator.configure();
            //设置日志输出级别为info,这将覆盖配置文件中设置的级别
            logger.setLevel(Level.INFO);
            //下面的消息将被输出
            logger.info("this is an info");
            logger.warn("this is a warn");
            logger.error("this is an error");
            logger.fatal("this is a fatal");
        }
    }

    C)输出端Appender
    Appender用来指定日志信息输出到哪个地方,可以同时指定多个输出目的地。Log4j允许将信息输出到许多不同的输出设备中,一个log信息输出目的地就叫做一个Appender。
    每个Logger都可以拥有一个或多个Appender,每个Appender表示一个日志的输出目的地。可以使用Logger.addAppender(Appender app)为Logger增加一个Appender,也可以使用Logger.removeAppender(Appender app)为Logger删除一个Appender。
    以下为Log4j几种常用的输出目的地。
    a:org.apache.log4j.ConsoleAppender:将日志信息输出到控制台。
    b:org.apache.log4j.FileAppender:将日志信息输出到一个文件。
    c:org.apache.log4j.DailyRollingFileAppender:将日志信息输出到一个日志文件,并且每天输出到一个新的日志文件。
    d:org.apache.log4j.RollingFileAppender:将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大小达到指定尺寸时,会自动把文件改名,同时产生一个新的文件。
    e:org.apache.log4j.WriteAppender:将日志信息以流格式发送到任意指定地方。
    f::org.apache.log4j.jdbc.JDBCAppender:通过JDBC把日志信息输出到数据库中。

    日志输出器,指定logger的输出位置

    1
    log4j.appender.appenderName = className

    每种appender都有若干配置项,下面逐一介绍

      ConsoleAppender(常用)

    1
    2
    3
    Threshold = WARN:指定日志信息的最低输出级别,默认DEBUG
    ImmediateFlush = true:表示所有消息都会被立即输出,设为false则不输出,默认值是true
    Target = System.err:默认值是System.out

      FileAppender

    1
    2
    3
    4
    Threshold = WARN:指定日志信息的最低输出级别,默认DEBUG
    ImmediateFlush = true:表示所有消息都会被立即输出,设为false则不输出,默认true
    Append = false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认true
    File = D: / logs / logging.log4j:指定消息输出到logging.log4j文件

      DailyRollingFileAppender(常用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Threshold = WARN:指定日志信息的最低输出级别,默认DEBUG
    ImmediateFlush = true:表示所有消息都会被立即输出,设为false则不输出,默认true
    Append = false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认true
    File = D: / logs / logging.log4j:指定当前消息输出到logging.log4j文件
    DatePattern = '.' yyyy - MM:每月滚动一次日志文件,即每月产生一个新的日志文件。当前月的日志文件名为logging.log4j,前一个月的日志文件名为logging.log4j.yyyy - MM
    另外,也可以指定按周、天、时、分等来滚动日志文件,对应的格式如下:
    1 ) '.' yyyy - MM:每月
    2 ) '.' yyyy - ww:每周
    3 ) '.' yyyy - MM - dd:每天
    4 ) '.' yyyy - MM - dd - a:每天两次
    5 ) '.' yyyy - MM - dd - HH:每小时
    6 ) '.' yyyy - MM - dd - HH - mm:每分钟

      RollingFileAppender

    1
    2
    3
    4
    5
    6
    Threshold = WARN:指定日志信息的最低输出级别,默认DEBUG
    ImmediateFlush = true:表示所有消息都会被立即输出,设为false则不输出,默认true
    Append = false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认true
    File = D: / logs / logging.log4j:指定消息输出到logging.log4j文件
    MaxFileSize = 100KB :后缀可以是KB,MB或者GB。在日志文件到达该大小时,将会自动滚动,即将原来的内容移到logging.log4j. 1 文件
    MaxBackupIndex = 2 :指定可以产生的滚动文件的最大数,例如,设为 2 则可以产生logging.log4j. 1 ,logging.log4j. 2 两个滚动文件和一个logging.log4j文件


     
    日志格式化器Layout
    有三种:
    HTMLLayout:格式化日志输出为HTML表格形式:如下
    SimpleLayout:以一种非常简单的方式格式化日志输出,它打印三项内容:级别-信息

    指定logger输出内容及格式

    1
    log4j.appender.appenderName.layout = className

      layout有4种选择

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

      layout也有配置项,下面具体介绍

      HTMLLayout

    1
    2
    LocationInfo = true:输出java文件名称和行号,默认false
    Title = My Logging: 默认值是Log4J Log Messages

      PatternLayout(最常用的配置)

    1
    ConversionPattern = % m % n:设定以怎样的格式显示消息

      设置格式的参数说明如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    % p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL
    % d:输出日志时间点的日期或时间,默认格式为ISO8601,可以指定格式如: % d{yyyy / MM / dd HH:mm:ss,SSS}
    % r:输出自应用程序启动到输出该log信息耗费的毫秒数
    % t:输出产生该日志事件的线程名
    % l:输出日志事件的发生位置,相当于 % c. % M( % F: % L)的组合,包括类全名、方法、文件名以及在代码中的行数
    % c:输出日志信息所属的类目,通常就是类全名
    % M:输出产生日志信息的方法名
    % F:输出日志消息产生时所在的文件名
    % L:输出代码中的行号
    % m:输出代码中指定的具体日志信息
    % n:输出一个回车换行符,Windows平台为 "rn" ,Unix平台为 "n"
    % x:输出和当前线程相关联的NDC(嵌套诊断环境)
    % % :输出一个 "%" 字符


    例:INFO - info
    PatternLayout::根据指定的转换模式格式化日志输出,或者如果没有指定任何转换模式,就使用默认的转化模式格式。
    下面的代码实现了SimpleLayout和FileAppender的程序

    public  static  void main(String[] args)  {
            
            Logger logger = Logger.getLogger(Log4jTest.class);        
            SimpleLayout layout = new SimpleLayout();
            //HTMLLayout  layout = new HTMLLayout();
            FileAppender appender = null;
            try{
                //把输出端配置到out.txt
                appender = new FileAppender(layout,"out.txt",false);
            }catch(Exception e){            
            }
            logger.addAppender(appender);//添加输出端
            logger.setLevel((Level)Level.DEBUG);//覆盖配置文件中的级别
            logger.debug("debug");
            logger.info("info");
            logger.warn("warn");
            logger.error("error");
            logger.fatal("fatal");
        }

    Log4j的配置
    配置Log4j环境就是指配置root Logger,包括把Logger为哪个级别,为它增加哪些Appender,以及为这些Appender设置Layout,等等。因为所有其他的Logger都是root Logger的后代,所以它们都继承了root Logger的性质。这些可以通过设置系统属性的方法来隐式地完成,也可以在程序中调用XXXConfigurator.configure()方法来显式地完成。有以下几种方式来配置Log4j。
    A:配置放在文件里,通过环境变量传递文件名等信息,利用Log4j默认的初始化过程解析并配置。
    B:配置放在文件里,通过应用服务器配置传递文件甸等信息,利用一个特定的Servlet来完成配置。
    C:在程序中调用BasicConfigor.configure()方法。
    D:配置放在文件里,通过命令行PropertyConfigurator.configure(args[])解析log4j.properties文件并配置Log4j。
    下面对BasicConfigurator.configure()方法和PropertyConfigurator.config()方法分别进行介绍。
    BasicConfigurator.configure()方法
    它使用简单的方法配置Log4j环境。这个方法完成的任务是:
    1:用默认的方式创建PatternLayout对象p:
      PatternLayout p = new PatternLayout("%-4r[%t]%-5p%c%x-%m%n");
    2:用p创建ConsoleAppender对象a,目标是System.out,标准输出设备:
     ConsoleAppender a = new CpnsoleAppender(p,ConsoleAppender.SYSTEM_OUT);
    3:为root Logger增加一个ConsoleAppender p;
     rootLogger.addAppender(p);
    4:把rootLogger的log level设置为DUBUG级别;
     rootLogger.setLevel(Level.DEBUG);

    PropertyConfigurator.configure()方法
    当使用以下语句生成Logger对象时:

      static Logger logger = Logger.getLogger(mycalss. class);

    如果没有调用BasicConfigurator.configure(),PropertyConfigurator.configure()或DOMConfigurator.configure()方法,Log4j会自动加载CLASSPATH下名为log4j.properties的配置文件。如果把此配置文件改为其他名字,例如my.properties,程序虽然仍能运行,但会报出不能正确初始化Log4j系统的提示。这时可以在程序中加上:

    PropertyConfigurator.configure("classes/my.properties");

    四 log4j完整配置示例

      介绍完了log4j.properties内容,我们来配置一些常用的日志输出吧

    1
    2
    log4j.rootLogger = DEBUG,console,dailyFile,rollingFile,logFile
    log4j.additivity.org.apache = true

      控制台console日志输出器

    1
    2
    3
    4
    5
    6
    7
    # 控制台(console)
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Threshold = DEBUG
    log4j.appender.console.ImmediateFlush = true
    log4j.appender.console.Target = System.err
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n

      文件logFile日志输出器

    1
    2
    3
    4
    5
    6
    7
    8
    # 日志文件(logFile)
    log4j.appender.logFile = org.apache.log4j.FileAppender
    log4j.appender.logFile.Threshold = DEBUG
    log4j.appender.logFile.ImmediateFlush = true
    log4j.appender.logFile.Append = true
    log4j.appender.logFile. File = D: / logs / log.log4j
    log4j.appender.logFile.layout = org.apache.log4j.PatternLayout
    log4j.appender.logFile.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n

      滚动文件rollingFile日志输出器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 滚动文件(rollingFile)
    log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
    log4j.appender.rollingFile.Threshold = DEBUG
    log4j.appender.rollingFile.ImmediateFlush = true
    log4j.appender.rollingFile.Append = true
    log4j.appender.rollingFile. File = D: / logs / log.log4j
    log4j.appender.rollingFile.MaxFileSize = 200KB
    log4j.appender.rollingFile.MaxBackupIndex = 50
    log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
    log4j.appender.rollingFile.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n

      定期滚动文件dailyFile日志输出器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 定期滚动日志文件(dailyFile)
    log4j.appender.dailyFile = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.dailyFile.Threshold = DEBUG
    log4j.appender.dailyFile.ImmediateFlush = true
    log4j.appender.dailyFile.Append = true
    log4j.appender.dailyFile. File = D: / logs / log.log4j
    log4j.appender.dailyFile.DatePattern = '.' yyyy - MM - dd
    log4j.appender.dailyFile.layout = org.apache.log4j.PatternLayout
    log4j.appender.dailyFile.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n

    五、log4j局部日志配置

      以上介绍的配置都是全局的,整个工程的代码使用同一套配置,意味着所有的日志都输出在了相同的地方,你无法直接了当的去看数据库访问日志、用户登录日志、操作日志,它们都混在一起,因此,需要为包甚至是类配置单独的日志输出,下面给出一个例子,为“com.demo.test”包指定日志输出器“test”,“com.demo.test”包下所有类的日志都将输出到/log/test.log文件

    1
    2
    3
    4
    5
    log4j.logger.com.demo.test = DEBUG,test
    log4j.appender.test = org.apache.log4j.FileAppender
    log4j.appender.test. File = / log / test.log
    log4j.appender.test.layout = org.apache.log4j.PatternLayout
    log4j.appender.test.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n

      也可以让同一个类输出不同的日志,为达到这个目的,需要在这个类中实例化两个logger

    1
    2
    private  static  Log logger1 = LogFactory.getLog( "myTest1" );
    private  static  Log logger2 = LogFactory.getLog( "myTest2" );

      然后分别配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    log4j.logger.myTest1 =  DEBUG,test1
    log4j.additivity.myTest1 = false
    log4j.appender.test1 = org.apache.log4j.FileAppender
    log4j.appender.test1. File = / log / test1.log
    log4j.appender.test1.layout = org.apache.log4j.PatternLayout
    log4j.appender.test1.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n
      
    log4j.logger.myTest2 = DEBUG,test2
    log4j.appender.test2 = org.apache.log4j.FileAppender
    log4j.appender.test2. File = / log / test2.log
    log4j.appender.test2.layout = org.apache.log4j.PatternLayout
    log4j.appender.test2.layout.ConversionPattern = % d{yyyy - MM - dd HH:mm:ss} [ % p]  % m % n

    六、slf4j与log4j联合使用

      slf4j是什么?slf4j只是定义了一组日志接口,但并未提供任何实现,既然这样,为什么要用slf4j呢?log4j不是已经满足要求了吗?

      是的,log4j满足了要求,但是,日志框架并不只有log4j一个,你喜欢用log4j,有的人可能更喜欢logback,有的人甚至用jdk自带的日志框架,这种情况下,如果你要依赖别人的jar,整个系统就用了两个日志框架,如果你依赖10个jar,每个jar用的日志框架都不同,岂不是一个工程用了10个日志框架,那就乱了!

      如果你的代码使用slf4j的接口,具体日志实现框架你喜欢用log4j,其他人的代码也用slf4j的接口,具体实现未知,那你依赖其他人jar包时,整个工程就只会用到log4j日志框架,这是一种典型的门面模式应用,与jvm思想相同,我们面向slf4j写日志代码,slf4j处理具体日志实现框架之间的差异,正如我们面向jvm写java代码,jvm处理操作系统之间的差异,结果就是,一处编写,到处运行。况且,现在越来越多的开源工具都在用slf4j了

      那么,怎么用slf4j呢?

      首先,得弄到slf4j的jar包,maven依赖如下,log4j配置过程完全不变

    1
    2
    3
    4
    5
    < dependency >
         < groupId >org.slf4j</ groupId >
         < artifactId >slf4j-api</ artifactId >
         < version >1.7.21</ version >
    </ dependency >

      然后,弄到slf4j与log4j的关联jar包,通过这个东西,将对slf4j接口的调用转换为对log4j的调用,不同的日志实现框架,这个转换工具不同

    1
    2
    3
    4
    5
    < dependency >
         < groupId >org.slf4j</ groupId >
         < artifactId >slf4j-log4j12</ artifactId >
         < version >1.7.21</ version >
    </ dependency >

      当然了,slf4j-log4j12这个包肯定依赖了slf4j和log4j,所以使用slf4j+log4j的组合只要配置上面这一个依赖就够了

      最后,代码里声明logger要改一下,原来使用log4j是这样的

    1
    2
    3
    4
    5
    6
    7
    import  org.apache.log4j.Logger;
    class  Test {
         final  Logger log = Logger.getLogger(Test. class );
         public  void  test() {
             log.info( "hello this is log4j info log" );
         }
    }

      现在要改成这样

    1
    2
    3
    4
    5
    6
    7
    8
    import  org.slf4j.Logger;
    import  org.slf4j.LoggerFactory;
    class  Test {
         Logger log = LoggerFactory.getLogger(Test. class );
         public  void  test() {
             log.info( "hello, my name is {}" "chengyi" );
         }
    }

      依赖的Logger变了,而且,slf4j的api还能使用占位符,很方便。


    展开全文
  • zip4j_1.3.2 - Java操作zip压缩文件接口最新版本

    千次下载 热门讨论 2015-01-09 11:27:53
    Java操作zip压缩格式的开源项目,功能强大而且使用方便,能完全满足Java操作Zip压缩文件,官方网址为:http://www.lingala.net/zip4j/ 可以下载到jar包、源码和示例,好像没有提供API文档。 不过需要使用代理访问...
  • SpringBoot出现该错误,log4j冲突,exclusion一下【spring-boot-starter-logging】就好了 我的项目是servicecomb的,同样,也是在引入springboot-starer的时候排除掉logging即可 SLF4J: Class path contains ...

    SpringBoot出现该错误,log4j冲突,exclusion一下【spring-boot-starter-logging】就好了

    我的项目是servicecomb的,同样,也是在引入springboot-starer的时候排除掉logging即可

    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:/Users/liyang/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.12.0/log4j-slf4j-impl-2.12.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/Users/liyang/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
    Exception in thread "main" java.lang.ExceptionInInitializerError
    	at com.uyibai.servicecomb.mall.servicecomb.GatewayMain.main(GatewayMain.java:7)
    Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j
    	at org.apache.logging.slf4j.Log4jLoggerFactory.validateContext(Log4jLoggerFactory.java:49)
    	at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:39)
    	at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:30)
    	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:52)
    	at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:30)
    	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:363)
    	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:388)
    	at org.apache.servicecomb.foundation.common.utils.BeanUtils.<clinit>(BeanUtils.java:34)
    	... 1 more
    Disconnected from the target VM, address: '127.0.0.1:0', transport: 'socket'
    
    Process finished with exit code 1
    

    解决冲突

    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
          <exclusions>
              <exclusion>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-logging</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
    
    展开全文
  • Log4j2与Slf4j的最佳实践

    万次阅读 2018-05-07 21:38:30
    日志对于项目的重要性不言而喻,现在市面上的日志框架多种多样:Log4j、Log4j2、Slf4j、JDKLog、Logback等等,如果没有真正深入了解过,可能会被搞得眼花缭乱。本文将介绍目前Java项目中最常见的Log4j2 + Slf4j的...

    微信搜索【程序员囧辉】,关注这个坚持分享技术干货的程序员。

    前言

    日志对于项目的重要性不言而喻,现在市面上的日志框架多种多样:Log4j、Log4j2、Slf4j、JDKLog、Logback等等,如果没有真正深入了解过,可能会被搞得眼花缭乱。本文将介绍目前Java项目中最常见的Log4j2 + Slf4j的使用组合,这也是我自己项目中目前使用的。

    另外,由于现在项目基本都是Servlet 3.0及以上版本,因此本文针对Servlet 3.0及更高的版本,如果使用的是Servlet 2.5可以参考官方文档进行适当的调整。

    官方文档地址:http://logging.apache.org/log4j/2.x/manual/webapp.html

     

    如何查看Servlet版本?

    查看web.xml文件中<web-app>标签中的version字段即可。

     

    关于Log4j2

    在上面提到的日志框架中,以Log4j + Slf4j的使用组合最为常见,但是我们知道Log4j目前已经停止更新了。Apache推出了新的Log4j2来代替Log4j,Log4j2是对Log4j的升级,与其前身Log4j相比有了显着的改进,并提供了许多Logback可用的改进,同时解决了Logback体系结构中的一些固有问题。因此,Log4j2 + Slf4j应该是未来的大势所趋。

     

    Log4j2的性能

    Log4j2最牛逼的地方在于异步输出日志时的性能表现,Log4j2在多线程的环境下吞吐量与Log4j和Logback的比较如下图。下图比较中Log4j2有三种模式:1)全局使用异步模式;2)部分Logger采用异步模式;3)异步Appender。可以看出在前两种模式下,Log4j2的性能较之Log4j和Logback有很大的优势。

    Log4j2完整的官方性能文档:http://logging.apache.org/log4j/2.x/performance.html

     

    Log4j2使用的几个点

    1. 在Web项目中需要添加 log4j-web jar包。
    2. Log4j允许使用log4jConfiguration参数在web.xml中指定配置文件位置。Log4j将通过以下方式搜索配置文件:
      1. 如果配置了路径(log4jConfiguration参数配置),Log4j将去搜索这个位置。
      2. 如果未配置路径,Log4j将搜索WEB-INF目录中“log4j2”开头的文件。如果找到多个文件,并且存在以“log4j2-name”开头的文件,其中name是Web应用程序的名称,则会使用它。否则,将使用第一个文件。
      3. 在resources目录下搜索配置文件,规则同b。
    3. Log4j2不支持Servlet 2.4及更老的的Web应用程序。

    第2点讲的简单点就是:Log4j2的配置文件名以“log4j2”开头时(例如常见的log4j2.xml),放在WEB-INF和resources的根路径时不需要在web.xml中配置路径,放在其他位置时需要配置路径。

     

    基本的使用(同步模式)

    1.maven依赖

    <!--log4j2核心包-->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.9.1</version>
    </dependency>
    <!-- Web项目需添加 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-web</artifactId>
        <version>2.9.1</version>
    </dependency>
    <!--用于与slf4j保持桥接-->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.9.1</version>
    </dependency>
    <!-- slf4j核心包-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>

     

    2.在resources根路径下添加log4j2.xml配置文件(无需配置路径)

    logj2.xml文件内容:将info及以上级别的日志输出到Console和指定路径的文件中。

     

    3.web.xml配置log4j2配置文件的路径

    如果log4j2.xml放在WEB-INF和resources根路径则不需要。

    <!-- log4j2.xml路径 -->
    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>/config/log4j2.xml</param-value>
    </context-param>

     

    4.如果是从Log4j等其他日志转的Log4j2 + Slf4j的,记得把Mavne中原来日志框架的依赖去掉或exclusion掉

    常见的有:log4j和slf4j-log4j12,如下。

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.25</version>
    </dependency>

     

    5.代码中使用

    import javax.servlet.http.HttpServletRequest;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    /**
     * @Author joonwhee
     * @Date 2018/3/31
     */
    @Controller
    @RequestMapping("/user")
    public class UserController {
        private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
        @RequestMapping("/userList")
        public String userList(HttpServletRequest request, Model model) {
            LOGGER.info("Test log4j2 info");
            LOGGER.warn("Test log4j2 warn");
            LOGGER.error("Test log4j2 error");
            return "userList";
        }
    }

     

    6.使用结果

    调用该方法后,Console输出:

    在log4j2.xml文件中配置的路径下生成日志文件:

    打开日志查看输出内容:

    这里Console输出和日志文件输出“前缀”不完全一致是由于上面log4j2.xml中Console和RollingFile的PatternLayout配置不一致导致的。

     

    至此,Log4j2集成Slf4j就完成了。

     

    扩展测试

    关于上面提到的Log4j2配置文件存放路径的问题,我们来做几个简单的测试:

    场景1:log4j2.xml放在resources/config路径下,在web.xml中配置log4jConfiguration指定路径。

    效果:日志正常输出。

    结论:Log4j能找到配置文件。

     

    场景2:log4j2.xml放在resources/config路径下,注释掉web.xml中的log4jConfiguration配置。

    效果:明显看出我们的配置已经失效了,但是输出了ERROR级别的日志,可以推测这是Log4j在找不到配置文件时的兜底策略。

    结论:Log4j不能找到配置文件。

     

    场景3:log4j2.xml放在resources根路径下,注释掉web.xml中的log4jConfiguration配置。

    效果:日志正常输出。

    结论:Log4j能找到配置文件。

     

    场景4:log4j2.xml放在WEB-INF根路径下,注释掉web.xml中的log4jConfiguration配置。

    效果:日志正常输出。

    结论:Log4j能找到配置文件。

     

    看完测试结果,大家就可以根据自己的习惯将log4j2.xml放到自己喜欢的地方了。

     

    进阶使用(异步模式)

    异步模式下,默认情况不会输出位置信息,因为输出位置信息会慢30-100倍。如果需要位置信息,需要在所有相关记录器(包括根记录器)的配置中设置“includeLocation = true”。

    例如以下代码:

    <asyncRoot level="info" includeLocation="true">
        <AppenderRef ref="RandomAccessFile"/>
    </asyncRoot>

     

    什么是位置信息?

    直接看下面两张图就很明显了。

    有位置信息:

    无位置信息:

     

    1.全局使用异步(在同步模式的基础上修改)

    1.maven增加disruptor依赖,Log4j2版本2.9及以上时需要disruptor-3.3.4.jar或更高版本;Log4j2版本2.9以下时需要disruptor-3.0.0.jar或更高版本。

    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.3.4</version>
    </dependency>

    2.将系统属性log4j2.contextSelector设置为org.apache.logging.log4j.core.async.AsyncLoggerContextSelector。

    方式:添加一个名字为log4j2.component.properties的文件,放到classpath下面,log4j2会在启动的时候自动加载。如下:

    3.log4j2.xml的配置修改成如下,跟同步模式的区别为RollingFile变成了RandomAccessFile。

     

    2.部分Logger采用异步方式(在同步模式的基础上修改)

    1.maven增加disruptor依赖,Log4j2版本2.9及以上时需要disruptor-3.3.4.jar或更高版本;Log4j2版本2.9以下时需要disruptor-3.0.0.jar或更高版本。

    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.3.4</version>
    </dependency>

    2.使用<asyncRoot>或<asyncLogger>配置来指定需要异步的记录器。

    <asyncRoot level="info">
        <AppenderRef ref="RandomAccessFile"/>
    </asyncRoot>

    3.log4j2.xml的配置修改成如下,跟同步模式的区别为:1)RollingFile变成了RandomAccessFile;2)loggers中使用了<asyncRoot>或<asyncLogger>。

    注意:配置只能包含一个根记录器(<root>或<asyncRoot>元素),但可以组合异步和非异步记录器。例如,包含<asyncLogger>元素的配置文件也可以包含同步记录器的<Root>和<Logger>元素。

     

    异步模式完整的官方文档地址:http://logging.apache.org/log4j/2.x/manual/async.html

     

    简单性能测试

    简单的测试下以下三种模式的耗时:全局使用异步的Log4j2、部分Logger使用异步的Log4j2、使用同步模式的Log4j2。

    测试代码

    1.测试例子很简单,就是将之前的3行输出外面加个64万次的循环。

    2.将输出Console去掉,只输出到文件,同步模式下的Appenders为RollingFile;异步模式下的Appenders为RandomAccessFile。

     

    场景1:RollingFile + 同步模式不带位置信息

    场景1的配置文件主要内容如下

    测试结果如下图:总共耗时17678ms

     

    场景2:RollingFile + 同步模式带位置信息

    场景2的配置文件主要内容如下,跟场景1只有includeLocation属性值不同

    测试结果如下图:总共耗时257268ms

     

    场景3:RandomAccessFile + 全局使用异步

    场景3的配置文件主要内容如下

    测试结果如下图:总共耗时2303ms

     

    场景4:RandomAccessFile + 部分使用异步

    场景4的配置文件主要内容如下

    测试结果如下图:总共耗时5864ms

    输出384万行简单日志的测试结果统计:

    以上测试只是简单的测试,仅供参考,详细的性能比较可以查看官方文档:http://logging.apache.org/log4j/2.x/performance.html

     

    结论:

    1. 通过测试结果可以看出,Log4j2的异步模式性能提升还是比较明显的,但是需根据实际情况来确认是否需要。正常项目使用同步模式一般都够用了。
    2. 输出位置信息带来的性能损耗太高了。因此,在线上项目的日志记录一定不要输出位置信息。
    展开全文
  • Spring Boot配置log4j记录日志

    万次阅读 多人点赞 2019-02-18 16:57:18
    转载请注明出处:Spring Boot配置log4j记录日志 我们在老的项目框架ssh,springMVC中都使用过log4j日志模块。 例如:java日志功能log4j模块的使用方法 Spring Boot框架也能很好的快速集成log4j,本篇文章记录如何在...

    转载请注明出处:Spring Boot配置log4j记录日志

    我们在老的项目框架ssh,springMVC中都使用过log4j日志模块。

    例如:java日志功能log4j模块的使用方法

    Spring Boot框架也能很好的快速集成log4j,本篇文章记录如何在Spring Boot框架中使用log4j。

    引入log4j依赖

    在创建Spring Boot工程时,我们引入了spring-boot-starter,其中包含了spring-boot-starter-logging,该依赖内容就是Spring Boot默认的日志框架Logback,所以我们在引入log4j之前,需要先排除该包的依赖,再引入log4j的依赖。

    需要注意的是
    Spring Boot 只有1.3.x和1.3.x以下版本才支持log4j的日志配置,1.3.x以上版本只支持log4j2。

    区别在于需要引入的包

    <artifactId>spring-boot-starter-log4j</artifactId>
    

    <artifactId>spring-boot-starter-log4j2</artifactId>
    

    Spring Boot 1.3.x和1.3.x以下版本的pom文件如下:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion> 
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j</artifactId>
    </dependency>
    

    Spring Boot 1.3.x以上版本的pom文件如下:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <exclusions>
            <exclusion> 
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    

    如果找不到

      <artifactId>spring-boot-starter</artifactId>
    

    则查找

    <artifactId>spring-boot-starter-web</artifactId>
    

    因为log4j2对于log4j来说有很多变动,如果不喜欢用log4j2,1.3.x版本以上的spring boot框架也可以引入以下两个包使用log4j。

    <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
    </dependency>
    
    <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
    </dependency>
    

    参考文章:
    spring boot 使用log4j,不是log4j2

    本文以Spring Boot1.5 和 log4j2的版本为例。

    代码中打印日志

    使用方式非常简单

    log4j2静态加载配置文件

    如下:

    package com.biologic.api.service.impl;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.core.config.ConfigurationSource;
    import org.apache.logging.log4j.core.config.Configurator;
    import org.springframework.stereotype.Service;
    
    import com.biologic.api.service.LogService;
    
    @Service
    public class LogServiceImpl implements LogService {
    
    
    	public static void main(String[] args) throws IOException {
    			
    		File file = new File("F:/eclipseworkspace/platform/report-api/src/main/resources/log4j.xml");
    		BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
    		final ConfigurationSource source = new ConfigurationSource(in);
    		Configurator.initialize(null, source);
    		
    		Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    
    		logger.debug("统计异常池数量异常,异常信息如下:e.getStackTrace().toString()");
    		logger.error("统计异常池数量异常,异常信息如下:e.getStackTrace().toString()");
    		logger.info("统计异常池数量异常,异常信息如下:e.getStackTrace().toString()");
    	}
    
    
    }
    
    

    静态加载多用于测试环境调整输出的格式。

    Spring Boot框架中使用log4j2

    Spring Boot框架中使用很方便,会自动加载配置文件,直接使用即可。
    如下:

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    
    @RestController
    public class SampleController {
    
    	Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    	
    	
    	@GetMapping(value = "/sample/testlog")
    	@ResponseBody
    	Object testlog() {
    		logger.info("统计异常池数量异常,异常信息如下:e.getStackTrace().toString()");
    		return "ok";
    	}
    }
    

    至于日志输出到什么地方,则需要看我们的配置。

    配置log4j2.xml

    在引入了log4j依赖之后,只需要在src/main/resources目录下加入log4j-spring.properties配置文件,就可以开始对应用的日志进行配置使用。

    注意:Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用log4j-spring.properties,而不是log4j.properties,不过取名为log4j.properties也是没有问题的)

    但是 log4j2版本则需要注意,只能使用非properties文件进行配置,xml或者yml,或者Json。

    更多配置文件格式相关参考:https://logging.apache.org/log4j/2.x/manual/configuration.html

    在application.properties中指定特定配置文件

    logging.config=classpath:log4j2.xml
    

    配置输出日志到控制台

    通过如下配置,设定root日志的输出级别为INFO,appender为控制台输出stdout

    LOG4J根配置

    log4j.rootCategory=INFO, stdout
    

    其中INFO是日志输出级别,共有5级:

    FATAL       0  
    ERROR      3  
    WARN       4  
    INFO         6  
    DEBUG      7 
    

    控制台输出log4j-spring.properties格式配置

    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target = System.out
    log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
    

    对应的xml格式如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="INFO">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Root level="info">
          <AppenderRef ref="Console"/>
        </Root>
      </Loggers>
    </Configuration>
    

    更多配置文件格式相关参考:https://logging.apache.org/log4j/2.x/manual/configuration.html

    Layout:日志输出格式,Log4j提供的layout有以下几种:

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

    打印参数: Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,如下:

       %m   输出代码中指定的消息
      %p   输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL 
      %r   输出自应用启动到输出该log信息耗费的毫秒数 
      %c   输出所属的类目,通常就是所在类的全名 
      %t   输出产生该日志事件的线程名 
      %n   输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n” 
      %d   输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss ,SSS},输出类似:2002年10月18日  22 : 10 : 28 , 921  
      %l   输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java: 10 ) 
    

    log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n

    日志信息格式中几个符号所代表的含义:

     -X号: X信息输出时左对齐;
     %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
     %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
     %r: 输出自应用启动到输出该log信息耗费的毫秒数
     %c: 输出日志信息所属的类目,通常就是所在类的全名
     %t: 输出产生该日志事件的线程名
     %l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main (TestLog4.java:10)
     %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
     %%: 输出一个"%"字符
     %F: 输出日志消息产生时所在的文件名称
     %L: 输出代码中的行号
     %m: 输出代码中指定的消息,产生的日志具体信息
     %n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行
     可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:
     1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
     2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
     3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
     4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉。
    

    配置输出日志到文件log4j-spring.properties格式配置

    在开发环境,我们只是输出到控制台没有问题,但是到了生产或测试环境,或许持久化日志内容,方便追溯问题原因。可以通过添加如下的appender内容,按天输出到不同的文件中去,同时还需要为log4j.rootCategory添加名为file的appender,这样root日志就可以输出到logs/all.log文件中了。

    LOG4J配置

    log4j.rootCategory=INFO, stdout, file
    

    输出到文件

    log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.file.file=logs/all.log
    log4j.appender.file.DatePattern='.'yyyy-MM-dd
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
    

    Appender 为日志输出目的地,Log4j提供的appender有以下几种:

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

    配置日志分类输出log4j-spring.properties格式配置

    当我们日志量较多的时候,查找问题会非常困难,常用的手段就是对日志进行分类,比如:

    例子一:

    可以按不同package进行输出。通过定义输出到logs/my.log的appender,并对com.test包下的日志级别设定为DEBUG级别、appender设置为输出到logs/my.log的名为test的appender。

    # com.test包下的日志配置
    log4j.category.com.test=DEBUG, testfile
    
    # com.test下的日志输出
    log4j.appender.testfile=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.testfile.file=logs/my.log
    log4j.appender.testfile.DatePattern='.'yyyy-MM-dd
    log4j.appender.testfile.layout=org.apache.log4j.PatternLayout
    log4j.appender.testfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L ---- %m%n
    
    可以对不同级别进行分类,比如对ERROR级别输出到特定的日志文件中,具体配置可以如下。
    
    log4j.logger.error=errorfile
    # error日志输出
    log4j.appender.errorfile=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.errorfile.file=logs/error.log
    log4j.appender.errorfile.DatePattern='.'yyyy-MM-dd
    log4j.appender.errorfile.Threshold = ERROR
    log4j.appender.errorfile.layout=org.apache.log4j.PatternLayout
    log4j.appender.errorfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
    

    例子二:

     ### set log levels ###
    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 =  %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 ## 输出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 ## 只输出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
    

    配置日志输出到数据库log4j-spring.properties格式配置

    将日志文件输出到数据库配置:

    LOG4J配置

    log4j.rootCategory=INFO,stdout,jdbc
    

    数据库输出

    log4j.appender.jdbc=org.apache.log4j.jdbc.JDBCAppender
    log4j.appender.jdbc.driver=com.mysql.jdbc.Driver
    log4j.appender.jdbc.URL=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=true
    log4j.appender.jdbc.user=root
    log4j.appender.jdbc.password=root
    log4j.appender.jdbc.sql=insert into log_icecoldmonitor(level,category,thread,time,location,note) values('%p','%c','%t','%d{yyyy-MM-dd HH:mm:ss:SSS}','%l','%m')
    

    引入数据库驱动:

    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
    </dependency>
    

    创建表:

    CREATE TABLE `log_icecoldmonitor` (
      `Id` int(11) NOT NULL AUTO_INCREMENT,
      `level` varchar(255) NOT NULL DEFAULT '' COMMENT '优先级',
      `category` varchar(255) NOT NULL DEFAULT '' COMMENT '类目',
      `thread` varchar(255) NOT NULL DEFAULT '' COMMENT '进程',
      `time` varchar(30) NOT NULL DEFAULT '' COMMENT '时间',
      `location` varchar(255) NOT NULL DEFAULT '' COMMENT '位置',
      `note` text COMMENT '日志信息',
      PRIMARY KEY (`Id`)
    )
    

    这样就可以保存到日志到数据库了,可能会出现如下异常信息:
    Java连接Mysql数据库警告:Establishing SSL connection
    原因是MySQL在高版本需要指明是否进行SSL连接。解决方案如下:
    在mysql连接字符串url中加入ssl=true或者false即可,如下所示。

    url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=true
    

    配置日志输出到邮件log4j-spring.properties格式配置

    发送email通知管理员:
    首先下载JavaMail和JAF, 
    http://java.sun.com/j2ee/ja/javamail/index.html
    http://java.sun.com/beans/glasgow/jaf.html
    在项目中引用mail.jar和activation.jar。
    或者通过pom中引用

    <!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
    

    或者

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
        <version>2.1.1.RELEASE</version>
    </dependency>
    

    写配置文件

     # 将日志发送到email
     log4j.logger.MailLog=WARN,A5
     #  APPENDER A5
     log4j.appender.A5=org.apache.log4j.net.SMTPAppender
     log4j.appender.A5.BufferSize=5
     log4j.appender.A5.To=chunjie@yeqiangwei.com
     log4j.appender.A5.From=error@yeqiangwei.com
     log4j.appender.A5.Subject=ErrorLog
     log4j.appender.A5.SMTPHost=smtp.263.net
     log4j.appender.A5.layout=org.apache.log4j.PatternLayout
     log4j.appender.A5.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
    

    调用代码:

     //把日志发送到mail
     Logger logger3 = Logger.getLogger("MailLog");
     logger3.warn("warn!!!");
     logger3.error("error!!!");
     logger3.fatal("fatal!!!");
    

    本文主要介绍如何在spring boot中引入log4j,以及一些基础用法,对于更多log4j的用法,参考log4j官方网站

    可能遇到的问题–SLF4J: Class path contains multiple SLF4J bindings.

    报错如下:

    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:/F:/maven/repository/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/F:/maven/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
    SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
    

    表现为配置的日志格式不生效。

    原因: pom文件中还有其他的包引入了logback-classic包。如下:

    解决方法:需要找出来进行排除。
    如下:

    		<!-- JPA Data (We are going to use Repositories, Entities, Hibernate, etc...) -->
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-jpa</artifactId>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-logging</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    

    可能遇到的问题 —[Fatal Error] :1:1: 前言中不允许有内容,ERROR StatusLogger Error parsing null

    报错如下:

    [Fatal Error] :1:1: 前言中不允许有内容。
    ERROR StatusLogger Error parsing null
     org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。
    	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
    	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
    	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.<init>(XmlConfiguration.java:96)
    	at org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory.getConfiguration(XmlConfigurationFactory.java:46)
    	at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:540)
    	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:176)
    	at org.apache.logging.log4j.core.config.Configurator.initialize(Configurator.java:85)
    	at org.apache.logging.log4j.core.config.Configurator.initialize(Configurator.java:67)
    	at com.biologic.api.service.impl.LogServiceImpl.main(LogServiceImpl.java:46)
    ERROR StatusLogger No logging configuration
    

    原因:log4j2里一般不建议使用properties文件,而是使用xml文件。

    解决方法:把properties文件修改成xml文件格式。

    参考链接:
    http://blog.didispace.com/springbootlog4j/
    https://blog.csdn.net/l1028386804/article/details/80464909

    转载请注明出处:Spring Boot配置log4j记录日志

    展开全文
  • Java Log4j和Log4j2的区别

    万次阅读 2019-06-28 19:01:56
    Java Log4j和Log4j2的区别 一、核心JAR包 log4j核心包:log4j:log4j:[version] 而log4j2的核心包有2个: org.apache.logging.log4j:log4j-core:[version] org.apache.logging.log4j:log4j-api:[version] 二、...
  • Java日志的使用——log4j和slf4j

    千次阅读 2019-06-17 19:01:04
    ### 设置### log4j.rootLogger = debug,stdout,D,E ...log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.ap...
  • log4j与slf4j的区别

    万次阅读 多人点赞 2019-04-27 11:11:18
    log4j : 即 log for java;Java的日志4英文名 four 与for同音 slf4j : simple log facade for java :简单日志门面 区别: log4j是真正实现日志功能的产品,像这样的产品有很多 slf4j 是一个适配器,我们通过...
  • 【解决】SLF4J: Class path contains multiple SLF4J bindings.

    千次阅读 多人点赞 2021-02-19 17:46:56
    【解决】SLF4J: Class path contains multiple SLF4J bindings. 在启动springboot项目时,遇到了这个问题,上网查询多个方案,最终这个方法得到解决 问题描述: SLF4J: Class path contains multiple SLF4J bindings...
  • Log4j2-Log4j 2介绍及使用

    万次阅读 2017-07-15 11:08:39
    Log4j 2 官网https://logging.apache.org/log4j/2.x/Log4j 2简介Log4j的1.x版本已经被广泛使用于很多应用程序中。然而,它这些年的发展已经放缓。它变得越来越难以维护,因为它需要严格遵循很老的Java版本,并在2015...
  • Log4j,Log4j2,logback,slf4j日志学习

    万次阅读 多人点赞 2016-10-22 09:20:46
    Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、数据库等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志...
  • log4j2 HTTP请求日志异步

    千次阅读 2017-10-10 15:28:37
    1、首先maven项目加入依赖包 <groupId>org.apache.logging.log4j <artifactId>log4j-core <version>2.9.0 <groupId>org.apache.logg
  • Log4j2漏洞复现

    千次阅读 2021-12-15 14:19:14
    Apache Log4j是一个基于Java的日志记录组件,通过重写Log4j引入了丰富的功能特性,该日志组件被广泛应用于业务系统开发,用以记录程序输入输出日志信息。Apache Log4j2存在远程代码执行漏洞,攻击者可利用该漏洞向...
  • 1.解决SLF4J报错 我们在自己的项目中使用了SLF4J,或者引入了某开源项目时,他的项目中用了SLF4J,运行时会报如下的错误... SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details. 检查自己的
  • log4j2 pom中引入以下依赖 <dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-log4j-2.x</artifactId> <version>6.4.0</version> <...
  • Log4j.properties配置详解

    万次阅读 2020-04-02 15:19:25
    1 入门示例 1.1 新建一个Java工程,导入包log4j-1.2.17.jar,整个工程最终目录如下 1.2 src同级创建并设置log4j.properties ### 设置### ...log4j.appender.stdout = org.apache.log4j.Conso...
  • 本节,将分享如何在一个SpringMVC web应用中整合log4j记录系统日志。更多精彩请阅读 东陆之滇的csdn博客:http://blog.csdn.net/zixiao217准备工作(根据自己的要求调整) Log4j 1.2.17 Spring 4.2.5.RELEASE Maven ...
  • Apache Log4j 远程代码注入漏洞

    千次阅读 2021-12-11 22:11:31
    2021年12月9日,Apache Log4j2 Java 日志模块存在远程命令执行漏洞可直接控制目标服务器问题,攻击者攻击难度极低。由于 Apache Log4j2 某些功能存在递归解析功能,攻击者可直接构造恶意请求,触发远程代码执行漏洞...
  • Knife4j使用指南

    千次阅读 2020-12-29 21:03:50
    knife4j是swagger的增强版,更契合微服务架构,ui前身是swagger-bootstrap-ui,api注解的使用方式和swagger一致。   springboot整合knife4j 依赖 <!-- 包含了ui界面 --> <dependency> <groupId...
  • log4j2 实际使用详解

    万次阅读 多人点赞 2017-05-12 19:31:07
    日志框架简单比较(slf4j、log4j、logback、log4j2 ) log4j2基础知识 log4j2实用配置 实战部分 slf4j + log4j2 实际使用 二、日志框架比较(slf4j、log4j、logback、log4j2 ) 日志接口(slf4j) slf4j是对所有日志...
  • docx4j是Java操作office2007+中的Word、Excel、PPT的开源项目,其主要针对WordXML同时也可以处理Excel和PPT,比POI要强大很多(POI对Word2007支持很弱)。 资源中包含docx4j项目的jar包(及主要依赖Jar)、javadoc...
  • Log4j框架配置文件log4j.properties配置使用详解

    万次阅读 多人点赞 2018-06-05 19:12:19
    log4j.properties配置文件详解 Log4j支持两种配置文件格式,一种是XML格式的文件,一种是properties(key=value)文件,其中properties格式的配置文件最为常用,其有一个固定的文件名log4j.properties,下面我们...
  • 学习SpringBoot的日志管理时发现了这个问题,想将SpringBoot的日志系统换成log4j,但只添加了slf4j-log4j12.jar导致报错,虽然解决办法很简单,将SpringBoot中原有的log4j-over-slf4j.jar依赖去除即可,但一直不明白...
  • Log4j maven依赖配置

    万次阅读 2017-08-27 15:42:10
    做项目的时候,经常需要给应用打印日志,LOG4J是我们的不二选择,项目管理使用maven构建时,pom.xml配置如下 <!--日志 start--> <dependency> <groupId>log4j</groupId> <...
  • Log4j2配置文件详解

    千次阅读 2019-09-28 18:29:49
    的格式点击http://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout PatternLayout:控制台或文件输出源(Console、File、RollingRandomAccessFile)都必须包含一个PatternLayout节点,用于指定...
  • 为什么要使用SLF4J而不是Log4J

    万次阅读 2016-09-07 10:08:21
    每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不同的日志库如java.util.logging、Apache log4j、logback。但如果你还不知道SLF4J(Simple ...
  • log4j漏洞 es升级log4j

    千次阅读 2021-12-15 17:09:49
    1.检查环境 ...srping-boot-strater-log4j2 flume dubbo logstash kafka 影响范围log4j版本 Apache Log4j 2.x <= 2.15.0 检查攻击 1. 可以通过检查日志中是否存在 “jndi:ldap://”、“jndi:rmi” 等
  • log4j2 的使用【超详细图文】

    万次阅读 多人点赞 2020-12-06 16:11:03
    log4j2 的使用 Apache Log4j2 是对Log4j 的升级版本,参考了logback 的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有: 异常处理,在logback中,Appender中的异常不会被应用感知到,但是...
  • Log4j  Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务 器、NT的事件记录器、UNIX Syslog守护进程等;用户也可以控制每一条日志的输出...
  • Log4j,Log4j2,logback,slf4j日志框架比较

    万次阅读 多人点赞 2018-07-12 09:35:10
    Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、数据库等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 969,518
精华内容 387,807
关键字:

http4j

友情链接: V4L2 API及数据结构.zip