Logback 日志打印对性能影响的探讨

Logback 日志打印导致程序崩溃的实战分析 日志记录是必不可少的一环,帮我们追踪程序的行为,定位问题所在。然而,有时日志本身却可能成为问题的根源。所以要根据实际情况选择合适的日志输出方式,避免造成程序阻塞而导致业务收到影响。从理论到实践:零拷贝技术的全面解读_零拷贝详解-CSDN博客Sentinel与Nacos强强联合,构建微服务稳定性基石的重要实践_nacos sentinel-CSDN博客从0开始理解云原生架构-CSDN博客TiDB高手进阶:揭秘自增ID热点现象与高级调优技巧_tidb 分布式自增id-CSDN博客。 阅读详情

一、引言

在日常系统业务开发中,日志记录是不可或缺的一部分,不仅帮助我们调试和排查问题,还能提供系统的运行状态和健康状况。然而,配置使用不当可能会对性能产生负面影响。在我们的项目中,服务耗时优化是提升系统性能的关键任务。在压测过程中,我们发现单机 QPS 存在明显的性能瓶颈,进一步分析表明,平常看似不起眼的日志打印实际上对性能产生了不小的影响。本文将探讨 Logback 日志打印对性能的影响,并提供一些优化建议。

二、日志记录的基本原理

日志消息打印的过程包括以下几个步骤:

2.1 获取 Logger

调用 org.slf4j.LoggerFactory 类的 getLogger 方法,即可获取 Logger 对象

Logger log = LoggerFactory.getLogger("HelloWord");

2.2 调用 logger.info 打印方法

log.info("NewIt");

2.2.1 取得过滤链的判定结果

调用log.info()方法,实际调用的是filterAndLog_1方法,第一步会进行TurboFilter过滤,可以在早期阶段决定是否丢弃日志事件,从而提高性能和减少不必要的日志处理开销。它支持根据日志级别、MDC 数据、标记等多种条件进行灵活的过滤。

2.2.2 检查日志级别

对 Logger 的有效级别与日志请求级别进行比较。如果请求级别数值小于有效级别,本次请求将 被禁用,Logback 会直接跳过本次请求

private void filterAndLog_1(final String localFQCN, final Marker marker, final Level level, final String msg, final Object param, final Throwable t) {
        /**
         * 这里先经过一串过滤器处理,根据传入的marker满足的条件不同返回不同的结果,
         */
        final FilterReply decision = loggerContext.getTurboFilterChainDecision_1(marker, this, level, msg, param, t);
        /**
         * 过滤后返回NEUTRAL则进一步判断当前想要打印的日志等级
         * 如果小于有效日志级别,则表示该日志无效,直接返回,不做具体输出动作。
         */
        if (decision == FilterReply.NEUTRAL) {
            if (effectiveLevelInt > level.levelInt) {
                return;
            }
        } else if (decision == FilterReply.DENY) {
            return;
        }
        buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] { param }, t);
}

2.2.3 创建 LoggingEvent 对象

如果日志级别允许,Logback 会构建一个 LoggingEvent 对象,该对象包含所有与请求相关的参数,如请求用的 logger、请求级别、日志消息、请求携带的异常、当前时间、当前线程、MDC信息等等。

private void buildLoggingEventAndAppend(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params,
                    final Throwable t) {
        LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params);
        le.setMarker(marker);
        callAppenders(le);
    }

2.2.4 调用 appenders 的 doAppend() 方法

在创建 LoggingEvent 对象以后,logback 将调用所有可用 appender 的 doAppend()方法,进行日志输出。

常见的 Appender 包括:

ConsoleAppender:将日志输出到控制台

FileAppender:将日志输出到文件

RollingFileAppender:将日志输出到文件,并支持日志滚动

SMTPAppender:将日志发送到电子邮件

DBAppender:将日志写入数据库

public void callAppenders(ILoggingEvent event) {
        int writes = 0;
        for (Logger l = this; l != null; l = l.parent) {
            writes += l.appendLoopOnAppenders(event);
            if (!l.additive) {
                break;
            }
        }
        if (writes == 0) {
            loggerContext.noAppenderDefinedWarning(this);
        }
    }

2.2.5 格式化日志信息

Appender 在输出日志信息前,需要对日志事件(LoggingEvent)进行格式化。它使用 Encoder 将日志事件转换为字节数组并把字节数组写出到相应的输出流,在转换为字节数组前,Encoder 通过调用 Layout 的 doLayout() 方法将日志事件格式化为字符串。

常见的 Layout 包括:

PatternLayout:使用模式字符串来格式化日志消息

HTMLLayout:生成 HTML 格式的日志

XMLLayout:生成 XML 格式的日志

2.2.6 输出日志信息

Appender 会根据配置的 Layout 将 LoggingEvent 转换为最终的日志消息,并将其输出到指定的目标

protected void subAppend(E event) {
        ......
        try {
            if (event instanceof DeferredProcessingAware) {
                ((DeferredProcessingAware) event).prepareForDeferredProcessing();
            }
            // 格式化日志文件        
            byte[] byteArray = this.encoder.encode(event);
            // 写入日志到特定的输出流中
            writeBytes(byteArray);
        } catch (IOException ioe) {
          ......
        }
    }

2.2.7 清理资源

在日志输出完成后,Appender 会清理相关的资源,如关闭文件句柄等。

public void stop() {
    synchronized (lock) {
      closeOutputStream();
      super.stop();
    }
  }
  • 性能影响因素

通过 Logback 的原理,我们可以了解到日志记录在提高应用程序的可维护性和可调试性的同时,因为日志生成和格式化会消耗 CPU 资源、日志写入和网络传输引入 I/O 延迟,以及日志事件对象占用内存等方面,也会对系统的性能产生一定的影响。

1. CPU 使用率增加

日志生成和格式化:每次生成日志时,需要执行字符串拼接、日期格式化等操作,这些操作会消耗 CPU 资源。

日志级别检查:每次调用日志方法时,Logback 都会检查当前日志级别是否允许记录该级别的日志。虽然这是一个简单的比较操作,但在高并发场景下也会累积成显著的开销。

2. 内存使用增加

日志事件对象:每个日志事件都会创建一个 LoggingEvent 对象,这些对象需要占用内存。在高并发场景下,大量的 LoggingEvent 对象可能会导致内存压力。

缓冲区:某些 Appender(如 AsyncAppender)会使用缓冲区来异步处理日志,这也会占用一定的内存。

3. I/O 操作延迟

文件写入:将日志写入文件系统是一个 I/O 操作,可能会导致磁盘 I/O 延迟。特别是在高并发场景下,频繁的文件写入操作可能会成为性能瓶颈。

网络传输:如果日志被发送到远程服务器(如通过 SMTPAppender 发送邮件或通过 SocketAppender 发送网络日志),网络传输也会引入延迟。

4. 线程阻塞

同步 I/O 操作:默认情况下,大多数 Appender 是同步的,这意味着日志写入操作会阻塞当前线程,直到写入操作完成。在高并发场景下,可能会导致线程阻塞,影响程序的响应速度。

日志滚动:某些 Appender(如 RollingFileAppender)在日志文件达到一定大小时会进行日志滚动操作,可能会导致短暂的阻塞。

5. 系统调用开销

文件描述符:每次打开和关闭文件描述符都会涉及系统调用,这会带来额外的开销。虽然 FileAppender 通常会保持文件描述符打开状态,但在某些情况下(如日志滚动)仍然会涉及文件描述符的管理。

线程切换:在多线程环境下,日志操作可能会导致线程切换,会增加调度开销。

  • 优化建议

   为了减少日志记录对性能的影响,可以采取以下措施:

    1. 合理设置日志级别:

在生产环境中,将日志级别设置为 INFO 或更高,避免记录过多的 DEBUG 和 TRACE 日志。

使用条件日志记录,例如:

if (logger.isDebugEnabled()) {
    logger.debug("This is a debug message with computation: {}", computation());
}
    1. 使用高效的 Appender:

选择适合应用场景的 Appender,在高性能场景下使用 AsyncAppender ,减少主线程的阻塞时间。

<appender name="asyncInfoAppender" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE" />
</appender>
    1. 优化日志格式:

减少不必要的日志信息,简化日志格式,减少字符串拼接和格式化的开销。

    1. 合理的配置 Appender属性:

如配置 RollingFileAppender 时,合理设置日志滚动策略,避免频繁的文件滚动操作。

    1. 限制日志文件大小:

设置合理的日志文件大小限制,避免单个日志文件过大导致的 I/O 延迟

  • 实践案例

我们有个高并发的 Web 应用,需要最大的提升服务的TPS,在发现日志记录有性能影后,于是对日志开始优化。

使用 Logback 进行日志记录。初始配置如下:

<configuration>
    ......
    <appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
	    <file>${log.dir}/logs/${APP_NAME}-ss_micro_app_${APP_NAME}_lt_info.log</file>
	    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
		    <level>INFO</level>
	    </filter>
	    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
		    <fileNamePattern>${log.dir}/logs/${APP_NAME}_${projectname}-%d{yyyy-MM-dd}.log
		    </fileNamePattern>
		    <maxHistory>30</maxHistory>
	    </rollingPolicy>
	    <encoder charset="UTF-8">
		    <pattern>%d [%thread] %-5p [%c] [%F:%L] [trace=%X{trace_id},span=%X{span_id}] - %msg%n</pattern>
	    </encoder>
    </appender>
    
    <!-- 监控耗时 -->
    <appender name="BizRollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log_dir}/logs/${APP_NAME}-ss_micro_app_${projectname}_lt_biz.log</file>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log_dir}/logs/${APP_NAME}-ss_micro_app_${projectname}_lt_biz.log-%d{yyyy-MM-dd}.log
            </fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder charset="UTF-8">
              <pattern>%msg%n</pattern>
        </encoder>
    </appender>
    
    <logger name="com.newit.core.payment.common.interceptors.MonitorLogUtil" additivity="false">
        <level value="INFO"/>
    	<appender-ref ref="BizRollingFile"/>
    </logger>
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="infoAppender" />
    </root>
    ......
</configuration>

在高并发场景下,发现应用性能明显下降,日志文件迅速增大。经过分析、我们进行了以下优化:

  1. 关闭不需要的日志输出

在对外输出项目中,biz日志其实并不需要使用,可以对其停止打印

<logger name="com.newit.core.payment.common.interceptors.MonitorLogUtil" additivity="false">
    <level value="OFF"/>
    <appender-ref ref="BizRollingFile"/>
</logger>
  1. 优化日志格式化方式

a.使用 %d{MM-dd HH:mm:ss.SSS} 来格式化日期和时间,在确保时间和日期的可读性的同时,可减少日志字符

b. 使用%C{15} 等占位符来截断长的日志记录器名称和类名

<encoder charset="UTF-8">
	<pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5p [%c{15}] [%F%L] [trace=%X{trace_id},span=%X{span_id}] - %msg%n</pattern>
</encoder>
  1. 使用异步日志记录:
<appender name="asyncInfoAppender" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 设置为0不丢弃日志,默认队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
    <discardingThreshold>0</discardingThreshold>
    <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
    <queueSize>1024</queueSize>
    <!-- 队列满了不阻塞调用者-->
    <neverBlock>true</neverBlock>
    <appender-ref ref="infoAppender" />
</appender>
<root level="info">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="asyncInfoAppender" />
</root>

AsyncAppender提升了日志记录的性能和响应速度,但可能导致日志顺序不一致和增加内存消耗。在高并发场景下需要高性能的服务非常有用,但在需要严格日志顺序的应用中需谨慎使用

小插曲:

在用AsyncAppender进行日志输出后,日志中的%L号无法转换,最后查看logback的源码:org.apache.log4j.AsyncAppender发现有一个参数:includeCallerData,根本原因是获取方法名、代码行号的方法的性能不太好,AsyncAppender默认关闭该实现,日志中如果需要显示该属性,将这个参数设置为true即可:

<appender name="asyncInfoAppender" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="infoAppender"/>
    <param name="includeCallerData" value="true"/>
</appender>

  1. 配置单个日志文件大小

可以在现有的按天归档日志的配置上,再加上根据文件大小分割配置,在一个自然日多个文件会按照后缀为yyyy-MM-dd-%i.log的格式顺序生成。

限制单个日志文件的大小可以提高文件管理和备份的效率,减少磁盘 I/O 操作,提高日志写入速度,同时也增强日志读取和分析的便捷性。此外它还能简化日志轮转过程,避免大文件带来的性能和管理问题。

<appender name="infoAppender"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        ......
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log_dir}/logs/${APP_NAME}_${projectname}-%d{yyyy-MM-dd}-%i.log
            </fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>500MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
       ......
    </appender>
  • 优化效果
性能:

为了减少其它中间件对优化效果的影响,我们屏蔽了其它中间件对性能的影响,压测方法中仅有日志的输出,来看看优化前后的区别:

日志优化前TPS:

日志优化后TPS:

根据一些其它基准测试,调整压测方法中日志输出比例,使用优化后的配置通常可以带来以下性能提升:

低频日志记录:如果日志记录频率较低,性能提升可能不太明显,大约在 10% 到 30% 之间

高频日志记录:如果日志记录频率较高,性能提升可以达到 50% 到 100% 甚至更高

存储:

通过优化日志格式,在不影响日志分析的前提下,每行日志输出可以固定减少大约20个字符左右。按照每天1000万条日志计算,每天可以节省大约200MB的存储空间。这对于处理大量日志的应用程序来说,能够有效降低存储成本。

七、总结

Logback 是一个强大且灵活的日志框架,但在使用过程中需要注意日志记录对性能的影响。通过合理设置日志级别、使用异步日志记录、记录必要的信息、简化日志格式、启用日志轮转和过滤敏感信息等措施,可以最大限度地发挥日志的作用,同时尽量避免因日志打印引起的性能问题。然而,优化日志记录还需要结合具体的应用场景,特别是在互联网应用中追求高性能、高并发和高可用的“三高”要求。每个服务在这些维度上的侧重点不同,因此需要根据实际情况进行针对性的优化。以上是一些相关影响点的优化探讨,希望大家在实际项目中更好地使用 Logback,提升应用的性能和稳定性。

logback自定义appender、policy实现输出日志的逻辑处理 以下只贴出核心代码,运行代码详见这里 背景 目前所在的一个组为api接口平台,需要对注册上的接口进行相应的性能监控。因为是中途接手的项目,对于接口性能的监控比较好奇,就花了点时间了解下,又学了一手,写了个例子,记录下。 代码结构概览 文件名 说明 LogbackMain 应用main启动类 LogPrint 业务类(需要打印日志的类) HandleAppender l... 阅读详情

相关推荐

LabView实战:精准实现float到十六进制的转换与高低位拆分

本文详细讲解了在LabVIEW中实现单精度浮点数(float)到十六进制字符串转换,并进行高低16位拆分的实战方法。针对工业通信中设备协议要求,核心使用强制类型转换(Type Cast)获取内存原始数据,避免数值转换错误,并提供了完整的VI构建步骤、交叉验证技巧及常见踩坑经验(如字节序、字符串格式),确保数据通信的准确性。

assembly8low的博客 1757

日志相关问题

日志打印过多,会对磁盘IO和CPU性能造成比较大的压力,所以可以通过日志分级去控制日志的输出。

qq_43361066的博客 1977

从零搭建一个虚拟ECU:手把手用Autosar CP模块模拟汽车灯控系统(基于Vector工具链)

本文详细介绍了如何使用Vector工具链从零搭建一个基于Autosar CP架构的虚拟ECU系统,模拟汽车灯光控制功能。通过环境搭建、模块配置、通信栈设置到灯光控制逻辑实现的全流程指导,帮助开发者掌握Autosar CP模块术语的实际应用,并提供了系统集成与测试的实用方案。

weixin_42628688的博客 304

日志对性能的影响以及我的几个日志习惯

本文内容:1、背景2、影响性能的日志因素3、好的日志习惯|| 背景写这篇文章有 2 个原因,一是前段时间架构组同事的一次性能优化分享,单单日志(log4j2)这一项优化性能就提升了 19 倍,QPS 从1660 升到 32000,被震撼到了。二是最近接手的一个项目中,日志加了彩色打印,按日志的级别设置了不同的高亮颜色,看得我眼花缭乱,用 less 等一些命令查看时还会展.........

JiuQianWan的博客 4581

深入解析set_input_delay:从理论到实践的关键时序约束

本文深入解析了FPGA/ASIC设计中关键的时序约束命令set_input_delay,从理论到实践详细阐述了其工作原理。文章重点讲解了如何结合setup time和hold time,通过计算-max与-min值来精确描述外部延迟,确保芯片内部逻辑能稳定捕获数据,并介绍了虚拟时钟、DDR接口约束等实战技巧与常见陷阱。

weixin_29313423的博客 309

Altium Designer 21 DRC检查:从新手到高手,这10个常见错误你踩过几个?

本文详细解析Altium Designer 21 DRC检查中的10个高频错误,包括间距违规、线宽违规、未连接网络等常见问题,并提供精准修复方案和实战技巧。通过分层诊断、智能规则设置和三维排查等方法,帮助工程师从新手进阶为高手,提升PCB设计效率和质量。

weixin_26873711的博客 220

打印日志会不会影响性能?怎么办?

刚开始做开发的时候就有一个疑问, 我们开发一般为了调试方便都会给自己的业务代码加上一些日志, 那么问题来了, 打印这么多日志不会影响性能吗?这个肯定是必然的, 毕竟需要计算机分出一些性能来打印日志的, 但一般要求不苛刻的场景可以忽略这个问题前面说了一般情况下日志影响的性能是可以忽略的, 既然有一般那肯定就有不一般的情况, 今天来了解一下如何减少日志对性能的影响。

梧桐树的博客 1427

Flutter模块打包AAR集成Android原生项目实践

跨平台开发框架Flutter通过将UI组件渲染为原生代码实现高性能表现,其核心优势在于一套代码可同时运行在iOS和Android平台。在工程实践中,将Flutter模块打包为AAR(Android Archive)进行集成,成为混合开发的主流方案。这种方案既保留了原生项目的稳定性,又能渐进式引入Flutter的高效开发特性。通过配置MethodChannel实现原生与Dart代码通信,开发者可以灵活控制Flutter引擎生命周期,优化内存占用和渲染性能。对于电商、社交等需要快速迭代的业务场景,该方案能显著提

weixin_34025051的博客 392

logback性能优化详解

不正确的日志打印不但会降低程序运行性能,还会占用大量IO资源和硬盘存储空间。本文主要总结一些能提高日志打印性能的手段。

弹指天下 6015

【05】昊一源科技——昊一源科技 嵌入式笔试, 校招,题目记录及解析

本文记录了昊一源科技嵌入式校招笔试题目及解析,涵盖计算机基础、汇编语言、网络协议、C语言编程等内容。主要包括:1)补码真值计算;2)MCS51汇编指令执行后寄存器状态;3)网络广播地址计算;4)TCP协议特点;5)C语言三目运算符应用;6)宏定义优先级问题;7)字符指针与数组的区别;8)C++静态成员变量应用;9)三位完全平方数查找程序。题目难度适中,涉及嵌入式开发常见知识点,对求职者基础能力考察全面。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1302

高效内存管理与性能优化:Java Hotspot G1 GC全景解析

本文深入分析了 Java Hotspot G1 GC 的工作原理、特点以及优化策略。G1 GC 是一种为低延迟和高吞吐量设计的垃圾回收器,适用于大内存和高响应要求的应用。文章详细介绍了 G1 GC 的基本回收流程、各类垃圾回收策略,以及如何通过调优 JVM 参数来优化垃圾回收过程。通过监控工具和 GC 日志分析,开发者可以精准调整 G1 GC 的行为,提升应用的性能和响应速度。 参考文献、书籍及链接 1.https://tech.meituan.com/2016/09/23/g1.html 2.书

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 170万+

高并发系统谨防被一行日志击垮

复制代码这就意味着同一个 appender 的日志写是串行的,在高并发的场景下因为有锁的争用现象,所以看似很简单的一行日志,耗费的时间却不少。接下来我们在本地简单的模拟一下高并发的场景,并记录打一行日志的耗时是多少复制代码需要说明的是,现实中高并发的请求应当用一个线程池向另一个线程池反复提交任务来模拟,这里我们简化了这个过程。

Q54665642ljf的博客 986

Android 12,通过JNI写framebuff实现白板书写加速

Android 书写加速

448313096@qq.com 1196

磁盘满了对日志打印(Logback)的影响

使用Logback日志框架,当磁盘满了后不必惊慌,它不会对应用程序产生太负面影响。仔细考虑,做为一个日志框架本该如此,不能因为写不了日志就抛出异常进而影响应用本身,毕竟,日志终究是个辅助的旁路逻辑,没有它应用也应该work well。底层知识的掌握有助于迅速理解上层应用。在阅读源码的过程中,我发现了非常熟悉的设计逻辑:即类似于Hystrix的断路器和RocketMQ消费失败重试的策略。由于之前有相关经验,因此我很快就能够理解作者的设计意图。

七夜 1538

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

LogBack+MybatisPlus实现打印sql日志

LogBack+MybatisPlus实现打印sql日志

我从不打没有准备的仗! 9761

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

logback异步日志打印阻塞工作线程

实际上这个问题是使用问题,非常简单,不过越是简单的使用,却可能出现致命问题,一般公司都会统一脚手架或者统一规范的方式来实现标准的日志配置文件,防止错误配置导致业务问题,不知道未来Java虚拟线程大规模使用会不会缓解日志打印阻塞工作线程的问题,毕竟调度更优,不过如果线程池满载,虚拟线程也是无能为力。还是需要在丢日志和存储消费日志的能力作取舍。

fenglllle的博客 4144

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Slf4j + logback 打印日志的最佳实践

我们抛开业务逻辑,仅仅从日志的角度来考虑日志问题。集合最近对项目的日志优化,总结以下几点最佳实践。 Slf4j + logback 打印日志的最佳实践 1,日志级别使用不当 2,谨慎使用e.printStackTrace() 3,使用占位符,而不是字符串拼接 4,尽量打印更少的日志 5,尽量不要在for循环中log日志 下面结合代码,来具体讲解。 ...

reggergdsg的博客 2041

logback打印日志不显示具体的信息,显示问号

目录 表象: 原因:日志打印的Appender是使用的ch.qos.logback.classic.AsyncAppender 正确配置 表象: 配置:<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{68} %line - %msg%n </Pattern> 日志体现: //配置...

吃素只吃肉的博客 4426

Logback与Log4j2日志框架性能对比与调优

性能测试 logback 同步日志 耗时 未经过任何调优,采用Logback默认配置得出上图,一百万条日志打印耗时(ms),如图:单线程下性能最佳,耗时随线程数增加而下降。 线程占用 单线程 无阻塞状态 多线程 多线程打印日志时,会产生大量线程阻塞,线程越多阻塞状态越多 四线程 八线程 十六线程 锁占用 线程发生多次占用锁的情况。查看Logback源码可得知,检查容量、放入队列、取出队列都需要在取得锁后进行 异步日志(队列扩容) 样本数100万,队列长度110万 耗时 线程占用 单线程 多线

小老板_BK 9728

Springboot 学习 之 logback-spring.xml 日志打印

简单精要控制日志打印,学好日志打印,提高排查问题的效率

zxguan 的博客 1070

Spring Boot logback日志

slf4j和log4j、log4j2、logback 之间的关系 log4j(作者Ceki Gülcü)出来时就等到了广泛的应用(注意这里是直接使用),是Java日志事实上的标准,并成为了Apache的项目 Apache要求把log4j并入到JDK,SUN拒绝,并在jdk1.4版本后增加了JUL(java.util.logging) 毕竟是JDK自带的,JUL也有很多人用。同时还有其他日志组件,如SimpleLog等。这时如果有人想换成其他日志组件,如log4j换成JUL,因为api完全不同,就需要改动代

这个需求,做不了 2335

Spring Boot 日志 配置 SLF4J 和 Logback

在开发 Java 应用时,日志记录是不可或缺的一部分。日志可以记录应用的运行状态、错误信息和调试信息,帮助开发者快速定位和解决问题。Spring Boot 项目默认集成了 SLF4J 和 Logback,使得日志配置变得简单而灵活。本文将详细介绍如何在 Spring Boot 项目中配置 SLF4J 和 Logback,包括基本的日志配置、日志文件的输出路径、日志级别、日志格式和环境区分配置。日志的重要性快速定位问题:通过分析日志,开发者可以迅速定位应用程序中的错误或性能问题。确保合规性。

qq_44231797的博客 3476

采用logback打印日志遇到的问题总结

最近在项目问题排查过程中发现,日志显示的程序执行时间 远大于 程序中计算的耗时,程序示例如下: private static final Logger LOGGER = LoggerFactory.getLogger(Test.class); public static void main(String[] args) throws InterruptedException { LOGGER.info("start"); long start = System.

fusugongzi的博客 1814

Java日志脱敏——基于logback MessageConverter实现

**日志脱敏** 是常见的安全需求,最近公司也需要将这一块内容进行推进。看了一圈网上的案例,很少有既轻量又好用的轮子可以让我直接使用。我一直是反对过度设计的,而同样我认为轮子就应该是可以让人拿去直接用的。所以我准备分享两篇博客分别实现两种日志脱敏方案。

“实用”是软件压倒一切的要素 2140

Springboot logback.xml配置 JdbcTemplate 打印日志

如果你确实需要在级别进行日志记录(虽然这通常不是必需的),你可能需要编写一个自定义的实现或装饰器,在其中包装原始的并添加日志记录逻辑。然而,这种方法比较复杂,并且通常不是必需的,因为JDBC驱动和连接池通常已经提供了足够的日志记录功能。

qq_43071699的博客 1719
上一篇: Mysql - 数据库备份和恢复
下一篇: Mysql - 多表连接和连接类型
acegi13579
博客等级 码龄16年 211粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值