Log4j高级配置实战:从基础属性到自定义Appender的全面指南

Log4j高级配置实战:从基础属性到自定义Appender的完整指南 本文深入解析Log4j高级配置,从基础属性到自定义Appender的完整指南。涵盖核心组件如Loggers、Appenders和Layouts的实战应用,详细介绍滚动日志配置、高并发场景优化及自定义Appender开发技巧,帮助开发者提升日志管理效率与系统稳定性。 阅读详情

1. 从零开始:理解Log4j的核心三要素

如果你刚接触Log4j,可能会被一堆配置文件搞得头晕。别担心,我刚开始用的时候也这样,感觉像是在解谜。其实,Log4j的整个日志系统,就像一家运转有序的快递公司,核心就靠三个“部门”协同工作:Logger(记录器)、Appender(输出源) 和 Layout(布局)。搞懂它们,你就掌握了Log4j的命脉。

想象一下,你的程序里有很多地方需要“说话”(记录日志),比如用户登录、数据计算、错误报警。Logger 就是那个负责“说话”的角色。但它不是随便乱说,而是有规矩的。Log4j给Logger定了五个音量级别,从低到高是:DEBUG、INFO、WARN、ERROR、FATAL。你可以把Logger想象成一个带过滤器的喇叭。比如,你把喇叭的灵敏度设为“INFO”级别,那么只有INFO、WARN、ERROR、FATAL这些“大声”或者“更重要”的话会被广播出去,而DEBUG这种“悄悄话”就被过滤掉了。在配置文件里,你经常看到 log4j.rootLogger=INFO, console, file 这样的配置,意思就是:根记录器(所有Logger的默认配置)的级别是INFO,并且它说的话会同时发给两个“快递员”(Appender):一个叫console,一个叫file。

那么,日志说出来了,要送到哪里去呢?这就是 Appender 的活了。它就是个“快递员”,负责把Logger产生的日志信息投递到指定的目的地。最常用的快递员有:ConsoleAppender(送到控制台,你启动程序时那个黑窗口)、FileAppender(送到一个固定的文件里)、RollingFileAppender(送到文件,但文件大了会自动打包,再开新文件,防止一个文件撑爆磁盘)。你可以配置多个Appender,让同一条日志同时出现在控制台、文件,甚至通过网络发到别的服务器上,非常灵活。

最后,日志送到目的地,总得有个格式吧?是写成纯文本,还是HTML表格,要不要带上时间、线程名?这就是 Layout 负责的“包装”环节。它决定了日志最终呈现的样子。最强大、最常用的是 PatternLayout,它允许你像拼积木一样,用各种“转换字符”自定义输出格式。比如 %d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n 这个模式,就能输出类似 2023-10-27 14:30:00 [main] INFO com.example.MyClass - 用户登录成功 这样清晰易读的日志行。掌握了这三个核心组件的关系,再看配置文件,就不再是一堆乱码了,而是一个清晰的物流流程图:谁说话(Logger)、谁送货(Appender)、包装成什么样(Layout)。

2. 基础配置实战:手把手调优你的日志输出

知道了核心组件,我们就要动手配置了。很多教程只给个配置示例,但为什么这么配?每个参数动了会怎样?这里我结合自己踩过的坑,给你讲透几个关键配置点,让你配得明明白白。

2.1 根Logger与级别过滤的精细控制

配置通常从根Logger开始:log4j.rootLogger=INFO, stdout, file。这里的 INFO 是全局默认的日志级别阈值。但你的应用可能很复杂,不同模块的重要性不同。比如,你希望自己写的核心业务代码输出DEBUG日志方便排查,但引用的某个特别“话痨”的第三方库,只想看它的ERROR日志,怎么办?这就需要用到 Logger的继承体系和级别单独设定。

Log4j的Logger是有层次结构的,用点号(.)分隔,就像Java的包名。log4j.rootLogger 是所有Logger的祖先。你可以为特定的Logger设定级别。例如:

log4j.rootLogger=INFO, stdout
# 让你自己写的服务层代码输出DEBUG级别日志
log4j.logger.com.myapp.service=DEBUG
# 让Hibernate这个ORM框架只输出WARN及以上级别的日志,屏蔽它的INFO信息
log4j.logger.org.hibernate=WARN

这样配置后,com.myapp.service.UserService 这个类产生的DEBUG日志就能输出了,而 org.hibernate.SQL 产生的INFO日志(比如每条执行的SQL语句)就不会出现,清静多了。这里有个坑要注意:log4j.additivity 属性。它默认为true,意思是子Logger的日志除了会发送给自己的Appender,还会“追加”给父Logger的Appender。如果你给 com.myapp.service 单独配置了一个写入特定文件的Appender,并且不希望这些DEBUG日志也出现在根Logger配置的控制台里,就需要设置 log4j.additivity.com.myapp.service=false。

2.2 Appender配置详解:不止是输出目的地

Appender的配置远不止指定一个类型。每个Appender都有一些关键选项,直接影响日志行为的稳定性和性能。以最常用的 FileAppender 和 ConsoleAppender 为例。

ImmediateFlush 这个参数我强烈建议你关注。它默认是 true,意思是每写一条日志,就立刻刷新到磁盘或控制台。这样做的好处是日志不丢,如果程序突然崩溃,最后的日志也能保存下来。但代价是严重的性能损耗,每次I/O操作都很慢。对于高并发应用,这可能是性能瓶颈。我曾在一次性能调优中,把一个非关键路径的日志Appender的 ImmediateFlush 设为 false,TPS直接提升了近15%。当然,风险就是程序崩溃时,最近几毫秒的日志可能还在缓冲区,没来得及写入磁盘。你需要根据日志的重要性做权衡:像交易流水、错误日志这类关键信息,保持 true;像一些调试性的、量大的跟踪日志,可以设为 false。

Target 属性对于 ConsoleAppender 也有讲究。默认是 System.out,但很多服务器环境(比如Tomcat)会把 System.err 重定向到单独的错误日志文件。你可以设置 Target=System.err,这样控制台日志就会进入标准错误流,便于和标准输出流分离管理。另一个参数 Threshold 可以在Appender级别再做一次过滤。比如根Logger是INFO,但你配置了一个专门记录ERROR以上级别日志的文件Appender,就可以设置 log4j.appender.errorFile.Threshold=ERROR,这样即使Logger级别是INFO,也只有ERROR和FATAL日志会进入这个文件,非常灵活。

3. 滚动日志配置:告别日志文件撑爆磁盘的噩梦

线上系统最怕的就是日志文件无限增长,一夜之间把磁盘写满,导致服务宕机。滚动日志配置就是来解决这个问题的,这也是高级配置里必须掌握的一环。Log4j提供了两种主流的滚动策略:按时间滚动(DailyRollingFileAppender)和按大小滚动(RollingFileAppender)。现在更推荐使用功能更强大的 RollingFileAppender,因为它可以结合时间和大小策略。

3.1 按大小滚动:应对突发流量

先看一个我项目中常用的、按文件大小滚动的配置片段:

log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=/var/log/myapp/app.log
log4j.appender.rollingFile.MaxFileSize=100MB
log4j.appender.rollingFile.MaxBackupIndex=10
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

这里的关键是 MaxFileSize 和 MaxBackupIndex。当 app.log 文件大小达到100MB时,Log4j会将它重命名为 app.log.1,然后新的日志继续写入新的 app.log。当再次达到100MB时,原来的 app.log.1 变成 app.log.2,app.log 变成新的 app.log.1,依此类推。MaxBackupIndex=10 意味着最多保留10个备份文件(app.log.1 到 app.log.10),最早的那个(app.log.10)会被删除。这样就形成了一个循环缓冲区,总日志量被限制在差不多 100MB * 10 = 1GB 以内,再也不用担心磁盘被撑爆。

3.2 按时间滚动:便于历史追溯

另一种常见需求是按天归档日志,方便日后按天排查问题。DailyRollingFileAppender 可以做到:

log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.File=/var/log/myapp/app.log
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd

DatePattern 参数定义了滚动周期和备份文件的后缀格式。'.'yyyy-MM-dd 表示每天午夜滚动一次,今天的日志叫 app.log,昨天的日志会被重命名为 app.log.2023-10-26。你还可以按小时('.'yyyy-MM-dd-HH)、按分钟甚至按月滚动。但这里有个经典大坑:DailyRollingFileAppender 不支持自动删除历史日志文件!如果你配置了按天滚动,又不做额外处理,日志文件会日积月累,最终还是会吃光磁盘空间。所以生产环境通常需要配合操作系统的定时任务(如Linux的crontab)或者使用更先进的 RollingFileAppender 结合时间触发策略来清理旧文件。

3.3 综合策略:大小与时间双重保障

在Log4j 1.2.x的后期版本以及Log4j 2.x中,可以通过策略组合实现更精细的控制。虽然原始Log4j 1.x的 RollingFileAppender 本身不支持直接按时间触发,但我们可以通过变通或升级来应对。更现代的做法是,如果你的项目允许,考虑升级到Log4j 2,它的 RollingFileAppender 功能强大得多,可以直接配置基于时间和大小的复合触发策略。如果必须停留在Log4j 1.x,一个实用的土办法是:使用按大小滚动的 RollingFileAppender,再配合一个外部脚本,定期(比如每天凌晨)删除超过N天的 *.log.* 备份文件,这样既能防止单个文件过大,又能清理历史数据。

4. 深入PatternLayout:打造你的专属日志格式

PatternLayout 是日志的“化妆师”,它决定了日志输出长什么样。一个清晰、信息丰富的日志格式,能在排查问题时让你事半功倍。它的核心是 ConversionPattern,由一系列转换说明符组成,每个都以百分号(%)开头。

最常用的模式串我推荐这个:%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{36} - %m%n。我们来拆解一下:

  • %d{yyyy-MM-dd HH:mm:ss.SSS}:输出精确到毫秒的时间戳。这是排查问题的第一要素,知道事情什么时候发生的。
  • [%t]:输出线程名。在Web应用或分布式系统中,一个请求可能穿越多个线程,记录线程名对追踪执行流至关重要。
  • %-5p:输出日志级别(DEBUG, INFO等)。-5 表示左对齐且最小宽度为5个字符,这样各级别能纵向对齐,视觉上更整齐。
  • %c{36}:输出Logger名称(通常是类名)。{36} 表示最大输出长度,超过会简化,防止超长类名破坏格式。这是定位日志来源的关键。
  • %m:输出应用程序真正写入的日志消息内容。
  • %n:换行符。

你还可以加入更多信息,比如 %L 输出行号(对调试极有帮助,但注意获取行号有性能损耗,生产环境慎用)、%F 输出文件名、%M 输出方法名。我习惯在开发环境的配置里加上行号,格式像 %d{HH:mm:ss.SSS} [%t] %-5p %c{1}.%M(%L) - %m%n,这样一旦看到错误日志,就能直接定位到代码的某一行,效率极高。

还有一个高级用法是 MDC(Mapped Diagnostic Context),它可以通过 %X{key} 输出。这在处理Web请求时特别有用。你可以在请求入口处,将一个唯一的追踪ID(比如UUID)放入MDC:MDC.put("traceId", uuid);,然后在PatternLayout中配置 %X{traceId}。这样,这个请求在整个处理链路中打印的所有日志,都会自动带上这个 traceId。无论日志多么分散,你都能用这个ID把它们全部串起来,完整还原一个请求的生命周期,是排查复杂分布式问题的神器。

5. 突破限制:动手编写一个自定义Appender

当内置的Appender不能满足你的脑洞时,自定义Appender就派上用场了。比如,你想把错误日志实时推送到团队的即时通讯工具(如钉钉、企业微信),或者写入到Elasticsearch、Kafka中,构建日志分析平台。别觉得这很难,其实继承 AppenderSkeleton 类,实现几个关键方法就行。下面我带你写一个最简单的、将日志输出到控制台的同时也打印一句特色标语的自定义Appender,你理解了原理,就能举一反三。

首先,创建一个Java类,继承 org.apache.log4j.AppenderSkeleton:

package com.myapp.logging;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;

public class MyCustomAppender extends AppenderSkeleton {

    // 这是一个可以配置的属性示例
    private String customTag;

    public String getCustomTag() {
        return customTag;
    }

    public void setCustomTag(String customTag) {
        this.customTag = customTag;
    }

    @Override
    protected void append(LoggingEvent event) {
        // 这是核心方法,每条日志都会调用这里
        if (this.layout == null) {
            // 如果没有设置Layout,直接输出日志消息
            System.out.println("[MyAppender-" + customTag + "] " + event.getMessage());
        } else {
            // 如果设置了Layout,就用Layout格式化日志事件
            String formattedMessage = this.layout.format(event);
            System.out.println("[MyAppender-" + customTag + "] " + formattedMessage);
        }
        // 这里就是你可以发挥创意的地方:
        // 可以将 formattedMessage 发送HTTP请求到Webhook
        // 可以写入到Redis
        // 可以生产到Kafka主题
    }

    @Override
    public void close() {
        // 当Appender关闭时,释放资源,比如关闭网络连接、数据库连接等
        System.out.println("MyCustomAppender is closing.");
    }

    @Override
    public boolean requiresLayout() {
        // 告诉Log4j我们这个Appender是否需要Layout来格式化消息
        // 返回true,意味着我们希望在配置文件中可以配置layout
        return true;
    }
}

这个自定义Appender做了什么事呢?它重写了 append 方法,每当有日志事件到来,它除了用Layout格式化消息外,还在前面加上了我们自定义的标签 [MyAppender-xxx]。customTag 是一个属性,可以在配置文件中注入。

接下来,在 log4j.properties 中使用它:

# 定义自定义Appender,指定我们刚写的类全限定名
log4j.appender.myCustom=com.myapp.logging.MyCustomAppender
# 给自定义属性customTag赋值
log4j.appender.myCustom.customTag=PROD_ENV
# 为它指定一个Layout,和普通Appender一样
log4j.appender.myCustom.layout=org.apache.log4j.PatternLayout
log4j.appender.myCustom.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c - %m%n

# 将自定义Appender添加到根Logger
log4j.rootLogger=INFO, console, myCustom

配置好后,程序运行时,每条日志除了会像往常一样输出到控制台,还会经过我们的 MyCustomAppender 处理,打上 [MyAppender-PROD_ENV] 的标签再输出一次。这只是一个演示。在实际项目中,你可以在 append 方法里集成任何你需要的服务客户端。比如,接入钉钉机器人,当遇到 ERROR 或 FATAL 级别日志时,构造一个消息体,通过HTTP POST发送到钉钉的Webhook URL,这样团队就能在第一时间收到报警。需要注意:自定义Appender中的操作(如网络I/O)不能阻塞主线程,否则会影响程序性能,对于耗时操作,可以考虑引入简单的异步队列处理。

6. 性能调优与生产环境最佳实践

配置好了,功能也实现了,但在高并发、高流量的生产环境,日志记录本身也可能成为性能瓶颈。我总结了几条实战中得出的经验,能帮你避开不少坑。

第一,合理设置日志级别。 这是最重要的性能开关。生产环境一定要把根Logger级别设为 WARN 或 ERROR,彻底关闭DEBUG和INFO输出。对于你自己需要监控的模块,再通过单独配置 log4j.logger.com.myapp.service=INFO 来开启。我曾经见过一个案例,生产环境把日志级别误设为DEBUG,一个高频接口每秒打印大量调试日志,磁盘I/O被打满,导致应用整体响应变慢。

第二,谨慎使用立即刷新(ImmediateFlush)和位置信息(LocationInfo)。 如前所述,ImmediateFlush=false 能极大提升性能,但要做好日志可能丢失一点点的心理准备。另外,PatternLayout中的 %L(行号)、%F(文件名)、%M(方法名)这些位置信息的获取,是通过抛出异常分析堆栈轨迹来实现的,开销非常大。在开发调试阶段可以用,但在生产环境的配置中,务必去掉它们。用 %c(类名)通常就足够定位问题了。

第三,异步日志记录(AsyncAppender)。 如果你的Log4j版本支持(通常是1.2.16以上),强烈建议使用 AsyncAppender。它的原理是把日志事件先放到一个内存队列里,然后由后台线程异步地取出并交给真正的Appender(如FileAppender)去写磁盘。这样,业务线程在记录日志时,只需要把事件放入队列,几乎不会阻塞,可以瞬间返回。配置示例:

log4j.appender.async=org.apache.log4j.AsyncAppender
log4j.appender.async.BufferSize=512
log4j.appender.async.Blocking=false
log4j.appender.async.appender-ref=rollingFile

这里 BufferSize 是队列大小,Blocking=false 表示队列满时,新日志事件会被丢弃(不会阻塞业务线程),避免日志系统反过来拖垮应用。你需要根据日志流量评估一个合适的队列大小,并在监控中观察是否有丢弃情况。

第四,日志文件的路径和磁盘。 千万不要把日志文件放在和系统盘或应用相同的磁盘上。最好有独立的、高速的(如SSD)磁盘分区用于存放日志。同时,日志路径的配置要使用绝对路径,避免因工作目录问题导致日志不知去向。定期检查日志滚动和清理策略是否生效,这是运维的日常工作。可以写个简单的监控脚本,检查日志目录的大小和文件数量,设置报警阈值。

最后,对于全新的项目,我建议直接考虑使用 Log4j 2 或者 SLF4J + Logback 组合。它们在性能、功能(如真正的异步日志、更强大的过滤器和脚本支持)和配置灵活性上,都比经典的Log4j 1.x有巨大提升。但如果你正在维护一个遗留系统,那么深入理解并优化现有的Log4j 1.x配置,依然能解决绝大多数问题,让这个老将焕发新的活力。记住,好的日志系统不是配出来的,而是在理解原理后,根据实际业务场景和问题,一步步调优出来的。多观察、多测试、多思考,你的日志就会成为你排查问题时的最强助力,而不是一堆占地方的文本垃圾。

Log4j日志框架:从基础配置到性能优化实战 日志系统是软件开发中关键的监控和诊断工具,其核心原理是通过日志级别控制信息过滤,结合Appender实现多目标输出。Log4j作为Java生态经典日志框架,采用层次化Logger体系,支持灵活的PatternLayout格式化。在电商等高并发场景中,通过AsyncAppender异步日志和合理的滚动策略,能显著提升系统性能。本文以支付系统为例,详解Log4j的配置技巧与生产环境最佳实践,包括多环境配置方案和常见问题排查方法,帮助开发者构建高效的日志管理体系。 阅读详情

相关推荐

Log4j2日志框架实战:从配置到性能优化的完整指南

本文提供了一份Log4j2日志框架从基础配置到高级性能优化的完整实战指南。详细解析了多环境配置策略、异步日志(AsyncLogger)的核心原理与参数调优,并分享了监控、延迟计算等高级技巧,帮助开发者构建高效、稳定且易于维护的日志系统。

weixin_29269441的博客 92

Log4j2 高级插件开发指南:自定义 Appender、Filter 与注解深度解析使用

讲解如何利用 @Plugin、@PluginFactory、@PluginBuilderFactory 等核心注解开发自定义 Appender、Filter 和日志级别。内容涵盖从基础插件创建到复杂的建造者模式实现,包括参数验证、配置注入、性能优化等高级特性,并提供了完整的 XML 配置

肖哥弹架构博客 927

log4j.properties深入解析与配置实践指南

log4j是一款广泛使用的Java日志记录框架,它为开发者提供了记录日志信息的强大工具,这些信息可以输出到控制台、文件、GUI组件、套接字服务器等多种目的地。自2001年首次发布以来,log4j经历了多个版本的迭代和升级,每一个版本都在尝试解决新的问题,并增强其功能,以适应不断变化的应用需求。log4j框架的设计目的是为了帮助开发者捕捉重要信息,调试应用程序,记录生产环境中的事件以及改善错误追踪。log4j的核心概念包括日志级别、日志记录器、Appender以及Layout。

weixin_42350014的博客 1161

log4j2的Appender基础介绍

功能:接受对其他 Appender 的引用,并在单独的线程上异步地将日志事件写入这些 Appender。注意,在写入这些 Appender 时发生的异常将对应用程序隐藏。配置参数:要异步调用的 Appender 的名称,可以配置多个。blocking:如果为true,当队列已满时,Appender 将等待直到有空闲位置。如果为false,当队列已满时,事件将被写入错误 Appender(如果配置了)。默认是true。

Java程序员的知识博客 1891

掌握Log4j日志记录框架的实践指南

Log4j是由Apache软件基金会提供的一个日志记录库,它是Java应用中广泛使用的一款日志管理工具。核心组件包括Loggers、Appenders、Layouts以及Filters,它们共同构成了Log4j强大的日志处理能力。

weixin_35797963的博客 770

01-SA8155 QNX 虚拟机Hypervisor

Hypervisor运行在Host OS操作系统上,其他操作系统均在Hypervisor上运行。:Hypervisor直接运行在硬件上,操作系统在Hypervisor之上运行。终止(关闭):echo control 0 dev/vmm。路径:qnx_ap/AMSS/platform/vm/resources/关闭/终止 qvm(GVM):slay -s SIGQUIT qvm。", //host PVM --- 主机。不直接操作/dev/vmm 实现关闭,启动vm。

静虚待令,有物混成 1万+

Log4j2-10-log4j2 Appender 入门介绍

appender负责将LogEvents传递到它们的目的地。每个Appender都必须实现Appender接口。大多数appender都扩展了AbstractAppender,后者增加了生命周期和可过滤的支持。生命周期允许组件在配置完成后完成初始化,并在关闭期间执行清理。Filterable允许组件附加过滤器,在事件处理期间对其进行评估。appender通常只负责将事件数据写入目标目的地。在大多数情况下,他们将格式化事件的责任委托给布局。

1085

【学习笔记】人群归因分数 PAF 以及combined PAF

人群归因风险比例(Population Attributable Fraction,PAF)是一个流行病学指标,它估计了在总体中,如果能消除一个特定的危险因素,能预防多少百分比的疾病或健康结果。简单来说,PAF回答的是:“如果没有这个风险因素,总体中会有多少病例是可以避免的?

weixin_53499537的博客 4899

2017-08-09-log4j-Appender输出目的地

Log4j 6. Appender 6.1 类图 6.2 Appender 6.3 OptionHandler 6.4 AppenderSkeleton threshold 6.5 AppenderAttachable 在日志那一节中,我们知道AppenderAttachable是日志器中用来处理Appender提供的接口,那么为什么这个接口会出现在Appender自己的类图中呢? 6...

小肥的胖 4874

Blender关于GIS安装及使用天地图

Blender下载安装及GIS插件的安装及使用

Miss_SQ的博客 6969

Matlab/simulink频率响应分析方法

Matlab/Simulink仿真系列问题一.电气模块与信号模块 一.电气模块与信号模块

virtuoso~晓晓 3万+

Log4j日志框架:从基础配置到企业级应用实践

日志系统是软件开发中不可或缺的基础组件,用于记录程序运行状态和异常信息。Log4j作为Java生态中最经典的日志框架,通过Logger、Appender和Layout三大核心组件实现灵活的日志管理。其分级日志控制机制(DEBUG/INFO/WARN/ERROR等)允许开发者根据不同环境调整日志详细程度,而多样化的输出方式(控制台、文件、数据库等)满足不同场景需求。在分布式系统和微服务架构中,结合ELK等工具可以实现日志的集中收集与分析。本文以Log4j 1.x为例,详细讲解配置技巧、性能优化方案以及常见问题

weixin_33851177的博客 404

098、C3k2_Ghost:用 GhostConv 替代 C3k2 内标准卷积的轻量化改造代码

本文介绍了用GhostConv轻量化改造YOLOv11中C3k2模块的实践。作者通过线上部署案例引出问题,详细解析了GhostConv的核心实现逻辑,指出直接替换标准卷积会导致的两个关键问题:通道数不匹配和kernel_size冲突。文章提供了完整的C3k2_Ghost实现代码,包含注意事项和调试技巧。消融实验显示,该方法在小模型上可减少27%-28%参数量、34%-35%FLOPs,仅损失0.8mAP。作者总结了适用场景:小模型效果显著,大模型需谨慎;检测小目标任务不推荐;训练时需调整学习率。最后强调sh

sundong_81的博客 62

Log4j2-study

一、配置文件 常用配置选项 <?xml version="1.0" encoding="UTF-8"?> <configuration status="WARN" monitorInterval="30" > <!--配置常量--> <properties></properties> <!--扩展、插件(可选项)--> <Appenders></Appenders> <Loggers>&l

a123123sdf的博客 2820

ThingsBoard PE专业版解决方案技术文档——温度&湿度

温湿度解决方案

weixin_67440240的博客 817

SIMULINK开发项目实例 1000 例专栏之第960例--基于电力系统稳定性的建模与仿真场景:-含分布式电源的配电网电压稳定性研究

间歇性与随机性:例如,太阳能依赖于日照强度,风能依赖于风速,这使得它们的输出功率具有不确定性。逆变器接口:大多数分布式电源通过逆变器接入电网,这对电网的动态响应特性产生了影响。位置分散:通常分布在用户侧或靠近负荷中心的位置。本文详细介绍了如何使用Simulink结合Simscape Electrical 构建一个用于研究含分布式电源配电网电压稳定性的模型,并提供了详细的仿真流程说明。

xiaoheshang_123的博客 153

Log4j2.xml配置全解析:从基础到高级实践,打造高效日志系统

日志是软件开发和运维中不可或缺的组成部分,它记录了系统运行时的关键信息,是问题排查、性能监控和系统审计的重要依据。其核心原理在于通过不同级别的日志记录(如DEBUG、INFO、WARN、ERROR),将程序运行状态输出到指定目的地(如控制台、文件或远程服务)。一个设计良好的日志系统不仅能提升问题定位效率,还能通过结构化输出和异步处理等技术,为日志分析和系统监控提供强大支持。在实际应用场景中,尤其是在微服务和分布式架构下,结合**异步日志**和**JSON结构化输出**,可以显著提升系统性能,并方便与ELK等

weixin_30654419的博客 544

基于FPGA的AGC自适应增益控制系统开发

自动增益控制(AGC)是一种在接收信号过程中自动调整放大器增益的技术,以确保输出信号的幅度保持在一个恒定的水平。基于FPGA实现AGC系统具有高性能、低延迟和高度可配置的特点,广泛应用于无线通信、音频处理和雷达等领域。FPGA上的AGC系统提供了一种高效且灵活的方法来处理变化的信号环境。在实际应用中,通过合理的设计和优化,可以显著提高信号处理系统的鲁棒性和可靠性。

走向CTO的路上... 1694

Log4j2配置实战:从环境隔离到性能调优的完整指南

日志系统是软件开发和运维中的关键基础设施,它通过记录程序运行时的状态、事件和错误信息,为问题诊断、性能监控和系统审计提供数据支持。其核心原理是基于日志级别(如DEBUG、INFO、ERROR)和输出目的地(Appender)的过滤与路由机制,实现对不同重要性信息的分类收集。一个设计良好的日志系统能显著提升线上问题的排查效率,是保障系统可观测性的重要环节。在Java生态中,Apache Log4j2凭借其异步日志、灵活配置和高性能特性,成为众多项目的首选。本文将深入探讨Log4j2的核心配置,特别是针对生产环

weixin_30847939的博客 360

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

日志框架(二)Log4j XML配置详解

Log4j2 XML配置指南摘要:Log4j2 XML配置文件包含Configuration根元素,内含Properties(全局变量)、Appenders(输出目标)和Loggers(日志器)三大核心部分。Appenders支持控制台、文件、数据库等多种输出方式,RollingFile可实现按时间/大小切割日志。Loggers通过分级和additivity属性控制日志继承关系。高级功能包括异步日志、多环境配置、过滤器和热加载(monitorInterval)。PatternLayout提供丰富的占位符定制

onlymscn的博客 1089

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Log4j Properties 配置项详细说明

Log4j Properties 配置项详细说明

爱的叹息的专栏 1017

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Java日志:log4j2

java日志框架、log4j2

a4453368的博客 1663

[log4j]从零开始深入理解日志配置的核心原理

这种层次结构允许继承配置,例如com.example的配置会自动应用到com.example.service。理解Log4j配置的核心原理,能够帮助开发者根据具体需求设计出高效、可靠的日志方案。通过合理配置三大核心组件,结合项目实际情况调整日志级别和输出策略,可以构建出既满足调试需求又不影响系统性能的日志体系。Log4j作为Java领域最流行的日志框架之一,其配置灵活性源于其精心设计的架构。要深入理解Log4j配置,需要从三个核心组件入手:Logger、Appender和Layout。

uHpCqKQs的博客 408

Log4j2 进阶使用(转载)

使用属性 在复杂的项目中,可能有一些约定的属性比如项目名称、配置文件路径等等。这些属性可能会在多个日志的配置中用到。这样就可以将这些属性配置到Log4j2的配置文件中,方便在多个Logger中共享。 定义属性需要在配置文件中添加properties节点,然后添加多个property。配置完成之后使用${property_name}就可以在项目中引用了。正如下面的一个配置文件中PatternLayo...

向心行者 516

Log4j 配置

一、log4j配置,一般可以采用两种方式,资源文件和XML文件。 1、属性文件 log4j.rootLogger=DEBUG,stdout,R ##日志文件的名称(定义为控制台输出) log4j.appender.stdout=org.apache.log4j.ConsoleAppender ##灵活定义输出格式 log4j.appender.stdout.layout=org.apache.lo...

iteye_17600的博客 137

log4j2的配置使用

主要介绍log4j2在maven项目中的应用

readerjun0314的专栏 434
上一篇: Vue2项目中WebSocket实时通信实战:从工具封装到状态管理
下一篇: 从硬盘到网络:奇偶校验、CRC、海明码在真实场景中的选择指南
人间清醒863
博客等级 码龄3年 33粉丝 1544原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值