惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
Cloudbric
Cloudbric
P
Palo Alto Networks Blog
T
Threatpost
T
Tor Project blog
T
Tenable Blog
AWS News Blog
AWS News Blog
Project Zero
Project Zero
L
LangChain Blog
Cyberwarzone
Cyberwarzone
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
C
CERT Recently Published Vulnerability Notes
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Security Latest
Security Latest
云风的 BLOG
云风的 BLOG
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Proofpoint News Feed
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
V
Vulnerabilities – Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
MongoDB | Blog
MongoDB | Blog
aimingoo的专栏
aimingoo的专栏
K
Kaspersky official blog
Jina AI
Jina AI
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
D
DataBreaches.Net
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Secure Thoughts
TaoSecurity Blog
TaoSecurity Blog
P
Privacy & Cybersecurity Law Blog
P
Proofpoint News Feed
MyScale Blog
MyScale Blog
IT之家
IT之家
Forbes - Security
Forbes - Security
The Hacker News
The Hacker News
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
Y
Y Combinator Blog

游牧血液

2026 年春节江西之旅 让 AI 写代码,它派了支咨询团队来 在 AI 时代,应该选择什么编程语言? 在 AI 时代,博客该怎么写? 深入理解 ISO 8601 时间间隔表示法 在 CentOS 7 上,使用 Let's Encrypt 安装免费的 HTTPS 证书 可组合数据系统之路:对过去 15 年和未来的思考 交换友情链接 MacOS 下解决 Edge 浏览器侧边栏无法关闭的问题 你使用什么作为数据库的 ID? HTTP API 的错误响应标准 只需要一个文件,在本机跑起 ChatGPT 聊一聊 Node 技术栈 个人网站迁移到 Astro 静态网站生成器 Gridsome 介绍 编程命名规范 升级到 iOS 14.2 后,Google Authenticator 挂了 SaaS 数据库架构选择 GitHub 宣布私有仓库支持无限协作者,核心功能全部免费 新一代通信协议:RSocket Let’s Encrypt 撤销 300 万个证书,检查你的证书是否在其中 使用 BFG Repo-Cleaner 修改 Git 提交历史 | 游牧血液 我编程 20 年的指导原则 | 游牧血液 如何做 HTTP 接口的访问控制 | 游牧血液 什么是移动原生业务软件(MNBA:Mobile Native Business Applications) | 游牧血液 JDK 的另一个选择:OpenJDK with Eclipse OpenJ9 分享开发多个线上项目后总结的 HTTP 接口设计方案 Flutter 集成友盟统计 Hugo 简明教程 Flutter 开发时,idevice_id 不能执行问题的解决 另一个静态网站生成器:Hugo
为 HTTP API 接口增加统一请求日志 | 游牧血液
2020-03-12 · via 游牧血液
Cover

目录

展开目录

概述

增加请求日志,便于在开发阶段,追查错误,在将来上线后,进行线上问题的排查。

统一请求日志要完成以下功能:

  • 记录时间、请求体和响应体;
  • 记录应用特有的一些信息,如当前用户,客户端版本,请求处理时间等;
  • 对于敏感信息,如登录密码,不做记录;
  • 在开发阶段,日志打印到控制台,在服务器上运行阶段,将日志保存到文件;
  • 保存在服务器的日志文件,按日切换文件,并将切出的旧文件压缩保存,并只保留指定一段时间的日志。

配置

应用配置文件

代码:

config/application-staging.yml

spring:
  application:
    name: http-api-demo
  profiles:
    active: staging

logging:
  file: /kt/log/http-api-demo/http-api-demo.log

在应用配置文件里,配置日志文件保存目录,注意这里 spring.profiles.active 配置的是 staging 环境。

Logback 配置文件

代码:

src/main/resources/logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
    <springProfile name="default,dev">
        <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
        <logger name="org.springframework.jdbc.core" additivity="false" level="DEBUG" >
            <appender-ref ref="CONSOLE" />
        </logger>
    </springProfile>
    <springProfile name="staging,prod">
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <encoder>
                <pattern>${FILE_LOG_PATTERN}</pattern>
                <charset>UTF-8</charset>
            </encoder>
            <file>${LOG_FILE}</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOG_FILE}.a/%d{yyyyMMdd}.%i.log.gz</fileNamePattern>
                <maxHistory>180</maxHistory>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>100MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
        </appender>
        <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
            <appender-ref ref="FILE" />
        </appender>
        <root level="INFO">
            <appender-ref ref="ASYNC"/>
        </root>
    </springProfile>
</configuration>

这个配置文件是 Spring 框架对 Logback 配置文件的扩展,可以将多个 profile 的配置写到一个文件。

可以看到,如果是 default 或者 dev profile,输出到 CONSOLE;如果是 staging 或者 prod profile,输出到文件 ${LOG_FILE},这个 LOG_FILE 是个变量,就是我们之前在 application-staging.yml 中配置的 logging.file

历史日志文件将保留 180 天,每个文件最大 100M,压缩后的文件名是 ${LOG_FILE}.a/%d{yyyyMMdd}.%i.log.gz,这里复用了 LOG_FILE 变量.

这相当于当前日志文件名是 /kt/log/http-api-demo/http-api-demo.log,历史文件保存在 /kt/log/http-api-demo/http-api-demo.log.a 目录里,文件名是 日期.序号.log.gz

代码

日志相关代码不贴出来了,都在这里:

src/main/java/tech/jitao/httpapidemo/config/logging

有几个要点:

  • 日志记录使用的一些数据是 AuthInterceptor 保存的,比如用户信息等;
  • 为了实现跳过某些接口,在接口上标记 @NoLogging,并且可设定忽略请求或者响应,在 LoggingInterceptor 检测到需要忽略日志的请求,设置变量,在 LoggingFilter 中检测到忽略变量,进行忽略。因为标记是在 Controller 上,Filter 检测不到,所以要多加一个 Interceptor 进行标记检测。

运行

如果想测试的效果,需要:

  • 创建 /kt/log/http-api-demo 目录,或修改成自己的,注意要路径;
  • 运行时,要指定配置文件路径。
sudo mkdir -p /kt/log/http-api-demo
build/libs/http-api-demo-1.2.0.jar --spring.config.location=file:${项目目录全路径}/config/application-staging.yml

日志排查

记录的日志格式如下:

yyyy-MM-dd HH:mm:SS.sss  INFO 43746 --- [0.1-8080-exec-1] t.j.h.config.logging.LoggingFilter       : POST /app/account/login 200
<<<<<<<<<<
o= null
v= null
n= null
u= null
q= << omit >>
t= 4 ms
r= {"code":"OK","data":{"id":"6372534490252289024","name":"唐伯虎","avatar":"https://www.jitao.tech/static/flutter-logo.png","username":"tang","birthday":"2020-03-12","balance":"102.4","admin":"N","status":1,"lastLoginTime":"2020-03-12 14:22:09","createTime":"2020-03-12 14:22:09","updateTime":"2020-03-12 14:22:09","accessToken":"D8d8lKFtXdQ15Y5VoZm2UHQI8UZGGk17kArOFR7I"}}
>>>>>>>>>>

各字段意义:

  • o,操作系统,来自 HTTP Header X-App-Os
  • v,客户端版本,来自 HTTP Header X-App-Version
  • n,客户端网络,来自 HTTP Header X-App-Network
  • u,用户 ID
  • q,请求体
  • t,处理时间,毫秒
  • r,响应体

使用 Linuxawk cat grep head less sort tail wc 等命令配合管道进行日志排查。

简单举两个例子 🙋🌰🌰:

  • 检查 ID 为 9527 的用户的登录日志
cat http-api-demo.log | grep -A 10 "POST /app/account/login" | grep -A 4 -B 6 "^u= 9527" | less
  • 获取最慢的几个请求的处理时间,单位是毫秒:
cat http-api-demo.log | grep "^t=" | awk '{print $2}' | sort | tail

更多 Linux 命令,可以发动搜索引擎,一个参考文章:

你需要熟练运用的 12 个命令行工具

总结

这种日志模式是针对小型应用的一个简单配置,如果是复杂的系统,日志一般会传到 ELK 之类的日志平台,属于高级用法,请自己搜索。