Day36 - 1. 日志


Day36 - 1. 日志

1.1 作用:

 跟输出语句一样,可以把程序在运行过程中的详细信息都打印在控制台上。

 利用log日志还可以把这些详细信息保存到文件和数据库中。

🧠 理论理解
日志的本质是程序运行状态的一种“记录手段”。它可以实时输出程序执行的详细信息,便于开发者调试错误、跟踪程序执行过程、定位问题。和简单的 System.out.println() 不同,日志可以按不同级别分类(比如 info、error)、可以定制输出格式,还支持输出到文件、数据库、远程服务器等多个媒介,从而实现专业化的运维监控。在我看来就是比如不当操作导致的bug能记录追踪。

🏢 企业实战理解
在大厂(如阿里、字节跳动、Google 等),日志不仅是“打印”这么简单,而是系统级的监控手段:

  • 会按模块、级别、节点统一采集。

  • 日志会被采集到 ELK(Elasticsearch+Logstash+Kibana)、Prometheus 或字节自研的 APOLLO 等系统中,形成实时日志流,用于报警、追踪、甚至作为大数据分析的一部分。

  • 例如字节跳动的在线广告推荐系统,日志会细粒度记录推荐链路的每一步执行细节,用来做A/B测试与效果归因。

 

1️⃣ 问题:请你详细说说 Java 日志框架的体系?它们之间的关系是什么?

答案:
Java 日志框架体系主要包含三个层次:

1️⃣ 日志门面(Facade)层

  • 代表:SLF4J、JCL(Jakarta Commons Logging)、Log4j2 API

  • 作用:定义标准接口,屏蔽底层实现的差异,让上层代码不直接依赖某个具体实现。

2️⃣ 日志实现层

  • 代表:Logback、Log4j2 Core、JUL(Java Util Logging)

  • 作用:真正负责日志的格式化、输出、轮转、持久化等操作。

3️⃣ 桥接层(Adapter)

  • 比如:slf4j-log4j12、jul-to-slf4j

  • 作用:打通门面和实现层,比如用 SLF4J + Logback 时,SLF4J 是门面,Logback 是实现。

🔎 它们的关系:

  • 大型企业一般推荐 “门面 + 实现”分离。业务代码依赖 SLF4J(解耦),底层通过配置切换 Logback、Log4j2 等实现。这样即便未来要替换日志实现,也无需改动业务代码。

  • Spring Boot 默认:内部使用 SLF4J 门面 + Logback 实现。

 

场景题 1️⃣:
你在字节跳动负责一套实时推荐系统,突然监控发现日志写入速率异常飙升,磁盘 I/O 利用率接近 100%,服务响应时间显著上升。请问你会如何排查并解决这个问题?

答案:

1️⃣ 第一步:快速定位原因

  • 登录服务器,查看磁盘空间和 I/O 情况,验证是否是日志文件导致磁盘占用。

  • lsof | grep log 查看哪些日志文件写入最频繁。

  • 检查线上日志配置,重点排查是否误开启 DEBUG / TRACE 级别。

2️⃣ 第二步:短期缓解措施

  • 动态修改日志级别(Logback 支持热加载配置),将日志级别提高到 WARNERROR,立刻减少输出量。

  • 判断日志是否采用异步输出,如果是同步日志,立即切换为 AsyncAppender

  • 考虑将热点日志路径暂时挂载到独立磁盘,避免影响主业务盘。

3️⃣ 第三步:深度分析

  • 查看最近代码变更,是否引入了新的日志点或循环输出场景。

  • 检查是否有异常大对象序列化到日志(如完整的请求 JSON、堆栈等)。

  • 结合监控(如 ELK、Prometheus)统计日志量的变化趋势,找出“爆炸点”。

4️⃣ 长期优化

  • 增加日志采样机制,对高频请求日志采样输出(比如只打 1% 请求日志)。

  • 对日志 SDK 做封装,加入日志内容大小限制和输出频率保护。

  • 建立日志输出规范 + 发布审核机制,防止 DEBUG 日志上线。

🚩 总结:大厂线上日志事故不罕见,字节跳动、阿里巴巴都经历过“日志风暴”。最佳实践是:日志实时监控 + 动态调级 + 采样限流 三位一体,既满足调试需求,又保障系统稳定。

1.2 使用步骤:

 不是java的,也不是自己写的,是第三方提供的代码,所以我们要导入jar包。

  • 把第三方的代码导入到当前的项目当中

    新建lib文件夹,把jar粘贴到lib文件夹当中,全选后右键点击选择add as a ....

    检测导入成功:导入成功后jar包可以展开。在项目重构界面可以看到导入的内容。

  • 把配置文件粘贴到src文件夹下。

  • 在代码中获取日志对象。

  • 调用方法打印日志。

 

🧠 理论理解
因为日志不是 JDK 自带的功能(虽然 JDK 里也有 java.util.logging,但应用场景比较弱),所以工业界常用的是第三方库,比如 Log4j、SLF4J、Logback。它们提供了专业的 API 和丰富的功能,需要通过导入 jar 包 + 配置文件集成到项目中,通常通过日志对象获取方法,调用 debug() / info() / error() 等方法打印日志。

🏢 企业实战理解

  • 大厂内部使用时会封装一层“日志SDK”,统一集成日志格式、异常链路ID、上下文信息(比如机器 IP、线程 ID、用户 ID)。

  • 例如阿里巴巴内部会强制要求所有接口日志必须有 traceId 追踪号,方便定位一次调用的完整链路。

  • 实际操作中很少“手动导包”,而是通过 Maven/Gradle 自动管理依赖,并结合 Spring Boot 的自动配置机制实现“开箱即用”。

2️⃣ 问题:日志级别 TRACE、DEBUG、INFO、WARN、ERROR 各自适合什么场景?为什么要分级?

答案:

  • TRACE:最细粒度的日志,适合用在开发调试阶段跟踪方法调用、循环内部状态变化,生产环境几乎不启用。

  • DEBUG:用于开发环境调试输出,记录接口请求参数、SQL 执行语句、缓存命中情况等。线上环境通常关闭,以避免日志膨胀。

  • INFO:业务流程正常日志,适合打印关键节点信息(如:服务启动、任务完成、支付成功等)。线上环境默认开启。

  • WARN:提示潜在问题,比如缓存未命中、接口响应时间超标等,但程序仍能正常运行。

  • ERROR:记录程序异常、关键故障,比如数据库连接失败、空指针异常。必须开启,且配合报警系统。

🚩 为什么要分级?
1️⃣ 减少无用日志污染,帮助开发者/运维精准定位问题。
2️⃣ 日志分级能动态调整策略,比如线上开启 INFO/WARN/ERROR,开发环境开启 DEBUG/TRACE,提高开发效率。
3️⃣ 对接日志系统时,支持按级别筛选和汇总,便于数据统计、监控和报警。

场景题 2️⃣:
你在 Google Cloud 团队工作,客户反馈他们希望查看 90 天内所有 ERROR 级别的访问日志,并且需要支持关键字搜索和接口响应时间筛选。请问你的设计方案是什么?

答案:

1️⃣ 数据采集方案

  • 日志通过 Logback + AsyncAppender 异步采集,输出到本地文件并实时推送至 Google Cloud Logging(前身 Stackdriver)。

  • 配置多级日志文件轮转,所有 ERROR 日志单独标记 tag,方便索引。

2️⃣ 存储方案

  • 日志数据进入 Cloud Logging 后,接入 BigQueryElasticsearch,支持大规模存储和高效检索。

  • 保证 90 天数据可查,配置冷热分层存储:前 30 天热数据、后 60 天冷数据。

3️⃣ 检索功能实现

  • 基于 Elasticsearch 提供多条件查询:

    • 日志级别 = ERROR

    • 按接口路径、时间区间、关键字过滤

    • 支持响应时间筛选(比如 responseTime > 1000ms

  • 提供 Web UI(如 Kibana、Cloud Console)和 API 接口,满足可视化与程序化访问。

4️⃣ 性能与安全保障

  • 日志索引采用分片策略,优化高并发检索性能。

  • 对客户敏感数据做脱敏处理(如 IP、账号)。

  • 提供审计功能,记录日志访问操作。

🚩 总结:类似的企业需求在 Google、AWS 都很常见。核心是日志采集、传输、存储、检索 4 个环节要打通,并且必须有强大的日志查询平台支撑高可用检索。

 

 

1.3 日志级别

TRACE, DEBUG, INFO, WARN, ERROR

还有两个特殊的:

 ALL:输出所有日志

 OFF:关闭所有日志

日志级别从小到大的关系:

 TRACE < DEBUG < INFO < WARN < ERROR

 

🧠 理论理解
日志分级的核心目的是分层次、分关注点输出,避免信息泛滥:

  • TRACE:追踪级别,输出非常细节的信息(比如内部循环状态)。

  • DEBUG:调试级别,开发阶段常用。

  • INFO:一般性的信息,比如接口正常响应、服务启动成功等。

  • WARN:警告,不影响业务但存在潜在风险。

  • ERROR:错误信息,通常是程序异常或失败时输出。

ALL 表示全都开;OFF 表示全都关。不同的级别能按实际场景调整,比如线上环境通常不打印 DEBUG,以减少日志量。

🏢 企业实战理解

  • 字节跳动、腾讯、阿里等公司都有严格的“日志输出规范”。比如线上只允许 INFO 及以上日志输出,DEBUG 级别必须关闭,以避免泄露敏感数据或日志过载。

  • 在 Google 的微服务体系中,日志不仅要打“级别”,还要打“模块标签”(如 auth、payment、push),方便后期筛选。

  • 大厂常见的“安全审计”日志也是利用日志级别管理的,所有涉及到安全(登录、权限变更)操作必须打日志,并标记为高优先级收集。

3️⃣ 问题:Logback 的日志轮转策略是怎么做的?请举例说明大文件如何拆分归档?

答案:
Logback 提供多种轮转策略,最常用的是 SizeAndTimeBasedRollingPolicy,结合“文件大小 + 时间”控制轮转:

🔨 主要策略参数:

  • fileNamePattern:拆分后的文件名模板,支持日期 %d 和序号 %i

  • maxFileSize:每个文件的最大体积(如 1MB)。

  • maxHistory:保留历史文件数量。

举例

<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <fileNamePattern>/logs/app-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
    <maxFileSize>100MB</maxFileSize>
    <maxHistory>30</maxHistory>
</rollingPolicy>

解释:

  • 每天新建一个日志文件(按日期命名)。

  • 当当天日志超过 100MB 时,自动编号切割为 app-2025-05-05.1.log.gzapp-2025-05-05.2.log.gz ...

  • 历史日志最多保留 30 天,超过会自动删除。

🚩 大厂场景:

  • 字节跳动在其日志平台上要求:单文件不得超过 200MB,单服务每日归档不少于 7 天,重要服务归档至少 30 天。

 

1.4 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        CONSOLE :表示当前的日志信息是可以输出到控制台的。
    -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--输出流对象 默认 System.out 改为 System.err-->
        <target>System.out</target>
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
                %msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level]  %c [%thread] : %msg%n</pattern>
        </encoder>
    </appender>

    <!-- File是输出的方向通向文件的 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!--日志输出路径-->
        <file>C:/code/itheima-data.log</file>
        <!--指定日志文件拆分和压缩规则-->
        <rollingPolicy
                       class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--通过指定压缩文件名称,来确定分割文件方式-->
            <fileNamePattern>C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.gz</fileNamePattern>
            <!--文件拆分大小-->
            <maxFileSize>1MB</maxFileSize>
        </rollingPolicy>
    </appender>

    <!--

    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
   , 默认debug
    <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
    -->
    <root level="info">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE" />
    </root>
</configuration>

🧠 理论理解
配置文件是日志库的“控制中心”,决定了日志:
1️⃣ 输出位置:比如控制台、文件、远程服务器等。
2️⃣ 格式:通过 pattern 定义日期、线程、类名、消息等的展示形式。
3️⃣ 文件轮转机制:比如设置 1MB 自动拆分/压缩,避免单个文件过大。
4️⃣ 输出级别:决定什么级别的日志会输出。

日志库(如 Logback)的配置文件一般用 XML 编写,也支持动态热更新,修改配置无需重启。

🏢 企业实战理解

  • 企业内部通常会预置一份“统一日志配置模板”,项目接入时直接复用。

  • 比如字节跳动的日志配置,会自动按机器 IP、业务 ID 分目录存储,保证跨服务查询时一目了然。

  • 大型集群会通过远程日志收集器(如阿里云 SLS、ELK)结合配置文件,实现“本地输出 + 异步推送”,既满足开发调试,也方便全局运维追踪。

  • 有些大厂还会在配置文件中加“报警配置”,比如 ERROR 日志量超过阈值就触发钉钉/飞书报警。

 

4️⃣ 问题:Spring Boot 为什么默认选择 Logback?你知道它和 Log4j2 的差异吗?

答案:

  • Spring Boot 默认 Logback,原因:

    • Logback 是 SLF4J 作者出的“亲儿子”,天然和 SLF4J 完美结合。

    • 功能全面,支持高性能异步日志、动态调整日志级别、丰富的配置能力。

    • 相比 Log4j(旧版)更安全,Logback 从设计上规避了早期 Log4j 的线程安全问题。

  • Logback vs Log4j2:

    • 性能:Log4j2 异步日志采用 LMAX Disruptor 模型,在高并发下性能优于 Logback。

    • 灵活性:Log4j2 支持 YAML/JSON/XML 多种配置格式,Logback 主要用 XML。

    • 动态热加载:两者都支持,但 Log4j2 更强大,比如可在配置变更时动态刷新不重启。

🚩 大厂实践:

  • 字节跳动在大数据服务中采用 Log4j2 + KafkaAppender,实现日志异步采集 + 实时入库。

  • 美团 & 阿里云的 Java 平台则普遍仍用 Logback + ELK 组合。


 

5️⃣ 问题:线上日志暴增怎么办?怎么预防日志写入对业务性能的影响?

答案:

🔍 排查:
1️⃣ 检查是否误开 DEBUG/TRACE 级别。
2️⃣ 查看是否有异常循环或日志爆炸点(如死循环输出)。
3️⃣ 检查日志异步队列积压、I/O 堵塞问题。

🛡 预防措施:

  • ✅ 使用异步日志(Logback AsyncAppender、Log4j2 AsyncLogger),减少业务线程阻塞。

  • ✅ 对热点接口加日志采样/限流,比如只记录 1% 的请求。

  • ✅ 严格区分日志级别,线上禁用 DEBUG。

  • ✅ 设置日志轮转与自动归档策略,防止磁盘打爆。

🚩 企业案例:

  • 在字节跳动,曾因一处 DEBUG 级别日志忘关,导致线上服务一天打出 600G 日志,直接打满磁盘,引发大面积故障。后续字节推行“日志级别审批机制”,要求线上发布前必须审核日志配置。

场景题 3️⃣:
你参与阿里巴巴“双11”项目,如何确保日志系统在高并发场景下既稳定又不会丢失关键日志?说说你的设计策略。

答案:

1️⃣ 高并发写入保障

  • 全面采用 异步日志(Logback AsyncAppender + Disruptor 队列)。

  • 设置大容量日志缓冲池,避免生产速度快于消费速度时丢日志。

  • 重要日志(如交易日志)双写:一份到文件,一份实时推送到 Kafka/Flume。

2️⃣ 高可用架构

  • 日志系统独立部署,集群化设计,采用主从复制和负载均衡机制。

  • 日志文件按机器自动分区 + 多副本备份,保证节点异常时不丢日志。

3️⃣ 实时监控 + 报警

  • 接入 Prometheus/Grafana,监控日志采集速率、错误率、I/O 使用率。

  • 设置日志丢失/积压阈值,一旦触发立即报警(钉钉、飞书)。

4️⃣ 优化轮转与清理

  • 配置文件轮转策略,避免单文件过大;自动归档并压缩历史文件。

  • 动态调级:高峰期只打必要的 INFO/WARN/ERROR 日志,降低系统负载。

5️⃣ 应急预案

  • 提前设计“降级机制”:日志采集节点异常时,服务仍然可用但开启最小日志输出。

  • 关键业务链路打埋点,必要时通过埋点还原交易过程。

🚩 总结:阿里巴巴“双11”背后的日志系统是“隐形基建”。设计重点是:异步高性能、集群化容错、实时监控、应急预案。日志既是排障工具,也是风控保障的一部分。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值