java之日志管理

Posted wuxiaochang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java之日志管理相关的知识,希望对你有一定的参考价值。

一. 为什么要使用日志

二. 常见日志框架介绍

三. Logback+SLF4J实战

四. 项目源码下载

五. 参考文章

 
技术图片

一. 为什么要使用日志

1. 对IT安全至关重要

  当您使用强大的日志管理软件自动触发以保护您的系统时,您已经赢得了一半的战斗,以确保您的IT基础设施安全。某些日志管理工具具有阻止可疑IP地址,删除帐户,甚至完全关闭显示受感染迹象的计算机的内置功能。
  此外,有效的日志管理工具可以实现并简化您的入侵检测系统。因此,当您的入侵检测系统发出恶意活动信号时,您可以快速检查由日志管理工具生成和维护的日志文件。日志文件可以进一步提供重要线索,便于故障排除以帮助您。

2. 帮助企业更有效地运营

  使用日志管理工具的直接好处之一是它可以最大限度地减少生产中的停机时间。日志管理工具是解决方案带中的主要力量,可以使您智能地掌握与生产相关的可能问题。它允许您知道什么时候重要的事情已经改变或改变。反过来,这会对您的技术平稳运行以及整个业务流程产生重大影响。
  此外,有效的日志管理对于满足合规性也很重要。某些合规性要求您监控和记录每个应用程序以及IT基础架构中的系统的事件。

3. 找到问题的根源

  使用复杂的日志管理工具维护日志文件允许进行根本原因分析,稍后便于调试。你可以避免艰苦的手工努力,试图弄清楚什么是轨道,以及究竟是什么导致了一个可能的问题。这进一步使您在处理所有类型的问题时越来越有效。
  您可以浏览日志文件,甚至可以使用该工具发现任何违规行为。这有助于使系统恢复正常工作。日志管理工具可帮助您更深入地识别现代组织遇到的威胁。

二. 常见日志框架介绍

1. JDKLog

  JDKLog是JDK官方提供的一个记录日志的方式,直接在JDK中就可以使用

import java.util.logging.Logger;
 
/****
 ** JDKLog Demo
 **/
public class JDKLog
{
    public static void main( String[] args )
    {
        Logger logger = Logger.getLogger("JDKLog");
        logger.info("Hello World.");
    }
}

温馨提示:JDKLog 的有点是使用非常简单,直接在 JDK 中就可以使用。但 JDKLog 功能比较太过于简单,不支持占位符显示,拓展性比较差,所以现在用的人也很少

2. Log4J

  Log4J 是 Apache 的一个日志开源框架,有多个分级(DEBUG/INFO/WARN/ERROR)记录级别,可以很好地将不同日志级别的日志分开记录,极大地方便了日志的查看。

3. LogBack

  LogBack 其实可以说是 Log4J 的进化版,因为它们两个都是同一个人(Ceki Gülcü)设计的开源日志组件。LogBack 除了具备 Log4j 的所有优点之外,还解决了 Log4J 不能使用占位符的问题。

4. SLF4J:适配器

  JDKLog、Log4J、LogBack 这几个常用的日志记录框架,它们都有各自的优缺点,适合在不同的场景下使用。可能简单的项目直接用 JDKLog 就可以了,而复杂的项目需要用上 Log4J。
  很多时候我们做项目都是从简单到复杂,也就是我们很可能一开始使用的是 JDKLog,之后业务复杂了需要使用 Log4J,这时候我们如何将原来写好的日志用新的日志框架输出呢?
  一个最死板的方法就是一行行代码修改,把之前用 JDKLog 的日志代码全部修改成 Log4J 的日志接口。但是这种方式不仅效率低下,而且做的工作都是重复性的工作,这怎么能忍呢。
  正是因为在实际的项目应用中,有时候可能会从一个日志框架切换到另外一个日志框架的需求,这时候往往需要在代码上进行很大的改动。为了避免切换日志组件时要改动代码,这时候一个叫做 SLF4J(Simple Logging Facade for Java,即Java简单日志记录接口集)的东西出现了。
  SLF4J(Simple Logging Facade for Java,即Java简单日志记录接口集)是一个日志的接口规范,它对用户提供了统一的日志接口,屏蔽了不同日志组件的差异。这样我们在编写代码的时候只需要看 SLF4J 这个接口文档即可,不需要去理会不同日之框架的区别。而当我们需要更换日志组件的时候,我们只需要更换一个具体的日志组件Jar包就可以了。

三. Logback+SLF4J实战

1. maven添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.wxc</groupId>
    <artifactId>testlog</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <!-- 添加slf4j日志api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.20</version>
        </dependency>
        <!-- 添加logback-classic依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 添加logback-core依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>

    </dependencies>

</project>

2. 在项目的资源文件中添加logback.xml代码

xml存放位置

 
技术图片

代码如下

<!-- ch.qos.logback.classic.filter.ThresholdFilter  临界值过滤器, 过滤掉低于指定临界值的日志
ch.qos.logback.classic.filter.LevelFilter   将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。 -->
<configuration>
    <property name="APP_Name" value="testlog" /> //这里为此项目的日志文件夹名
    <property name="log.dir" value="F:/home"></property> //这里为日志的存储地址
    <timestamp key="bySecond" datePattern="yyyyMMdd HHmmss"/>
    <contextName>${APP_Name}</contextName>
 
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} [%file:%line] - %msg%n</Pattern>
        </layout>
    </appender>
 
    <!-- 按日期和大小区分的滚动日志 -->
    <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.dir}/${APP_Name}/info/info.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
 
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
 
 
    <!-- 按日期和大小区分的滚动日志 -->
    <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 必须指定,否则不会往文件输出内容 -->
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
 
        <!-- 必需要指定rollingPolicy 与 triggeringPolicy 属性   否则不会生成文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.dir}/${APP_Name}/debug/debug.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
 
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
 
        </rollingPolicy>
    </appender>
 
 
    <!-- error级别只按日期滚动生成日志 -->
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 必须指定,否则不会往文件输出内容 -->
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
            <!--    <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>-->
        </filter>
 
        <!-- 必需要指定rollingPolicy 与 triggeringPolicy 属性   否则不会生成文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.dir}/${APP_Name}/error/error.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 默认值是10MB。 -->
        <!--     <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                  <maxFileSize>5MB</maxFileSize>
            </triggeringPolicy>  -->
    </appender>
 
    <!-- 滚动记录文件 -->
    <appender name="MONITOR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{85} - %msg%n</Pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.dir}/${APP_Name}/monitor/monitor.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
 
    <logger name="org" level="INFO" />  <!--将org包下面的所有日志级别设为了ERROR -->
    <logger name="monitor" additivity="false" level="DEBUG" />
 
    <logger name="monitor" additivity="false" level="DEBUG">
        <appender-ref ref="MONITOR" />
    </logger>
 
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE_INFO" />
        <appender-ref ref="FILE_DEBUG" /> //上线时 这个需注释掉,debug级别的日志
        <appender-ref ref="FILE_ERROR" />
    </root>
</configuration>

3. 测试代码

public class TestLogback {

    private final static Logger logger = LoggerFactory.getLogger(TestLogback.class);

    public static void main(String[] args) {

        logger.error("测试出错了");

        logger.info("测试出错了");

        logger.debug("测试出错了");
    }

    public static void testErr()
    {

        String[] name = {"1", "2", "3"};

        try
        {
            System.out.println(name[5]);
        }
        catch (Exception e)
        {

            e.printStackTrace();
            logger.error("出现异常:"+e);

            logger.error("数据越界了");

        }
    }
}

4. 运行结果

 
技术图片
 
技术图片
 
技术图片

四. 项目源码下载

链接:https://pan.baidu.com/s/1pzxMlDKl92AlamO8cg9jFA
提取码:rhgu

五. 参考文章

https://www.cnblogs.com/baizhanshi/p/7911123.html

 

以上是关于java之日志管理的主要内容,如果未能解决你的问题,请参考以下文章

java之日志管理

nodejs之日志管理

J2SE之综合使用java代码进行简单的WEB服务器研发(软件测试技术单元测试以及日志管理器概念说明)

系统管理之组织机构树形化结构优化篇

argparse 代码片段只打印部分日志

常用python日期日志获取内容循环的代码片段