⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 风象南 「风象南」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

在微服务、云原生时代,提到日志收集,大家脑子里跳出来的第一个方案往往是 ELK、EFK、Loki等。这些方案功能强大,但部署复杂、资源消耗也不小。

其实还有一套久经考验的日志收集方案,它诞生于 80 年代,至今仍在各行各业默默工作——它就是 Syslog。

今天聊聊这个”老古董”,为什么它还没被淘汰,以及在什么场景下它可能是你的最佳选择。

什么是 Syslog

Syslog 是一种用于在 IP 网络中转发日志消息的标准协议。最早由 BSD Unix 实现,后来经过多次标准化,目前主流遵循的是 RFC5424 标准(2009年发布)。

一个典型的 Syslog 消息长这样:

<34>1 2023-12-29T10:30:00.123Z server01 sshd 1234 - [meta sessionId="abc123"] Failed password for root from 192.168.1.100

看起来有点复杂,拆解一下就清楚了:

部分 说明 示例值
<PRI> 优先级(设施+级别) <34>
VERSION 协议版本 1
TIMESTAMP 时间戳 2023-12-29T10:30:00.123Z
HOSTNAME 主机名 server01
APP-NAME 应用名称 sshd
PROCID 进程 ID 1234
MSGID 消息 ID -(未设置)
STRUCTURED-DATA 结构化数据 [meta sessionId="abc123"]
MSG 实际消息内容 Failed password for root...

优先级(PRI) 这个字段比较特殊,它由两部分组成:

PRI = Facility * 8 + Severity

设施(Facility) 表示消息来源,常见的有:

  • 0 - kern(内核)
  • 1 - user(用户级应用)
  • 3 - daemon(系统守护进程)
  • 16 - local0 到 23 - local7(本地自定义)

严重级别(Severity) 表示消息严重程度:

  • 0 - Emergency(系统不可用)
  • 4 - Warning(警告)
  • 6 - Informational(信息)
  • 7 - Debug(调试)

比如 <34> 表示:34 = 4*8 + 2,即 Facility=4(auth),Severity=2(Critical)。

Syslog 的特点与优势

第一,它足够简单

Syslog 的核心就是一个 UDP 协议(当然也支持 TCP),发一条消息过去就完事了。客户端实现非常简单,几行代码就能搞定:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class SyslogClient {

public static void sendSyslog(String message, int facility, int severity) throws Exception {
int priority = facility * 8 + severity;
String syslogMsg = "<" + priority + ">" + message;

try (DatagramSocket socket = new DatagramSocket()) {
byte[] data = syslogMsg.getBytes();
InetAddress address = InetAddress.getByName("192.168.1.10");
DatagramPacket packet = new DatagramPacket(data, data.length, address, 514);
socket.send(packet);
}
}

public static void main(String[] args) throws Exception {
sendSyslog("Application started successfully", 1, 6);
}
}

服务器端也不复杂,Linux 系统自带的 rsyslog、syslog-ng 都能直接接收和存储。

第二,标准化程度高

网络设备(路由器、交换机、防火墙)几乎都支持 Syslog。你想收集设备日志?不用装 agent,配置一下 Syslog 服务器地址就行:

# Cisco 设备配置示例
logging host 192.168.1.10
logging trap warnings

这种”开箱即用”的兼容性,是 ELK、Loki 这些方案很难做到的。

第三,整体资源消耗低

客户端轻量:Syslog 客户端实现非常简单,几行代码就能发送日志,对设备资源消耗极小。这使得边缘设备、IoT 设备、嵌入式系统都可以轻松接入。

服务端相对轻量:相比 ELK 需要多台服务器组成的集群,Syslog 服务端(如 rsyslog)资源消耗要低得多。单台 2核4G 的服务器就能处理每秒数千条日志,对于中小规模环境完全够用。

Syslog 的典型适用场景

场景一:网络设备日志集中管理

典型需求:

  • 收集路由器、交换机、防火墙的配置变更日志
  • 监控网络设备的连接状态、流量异常
  • 审计网络访问记录

为什么选 Syslog:

  • 网络设备原生支持,无需部署 agent
  • 设备数量通常几十到几百台,Syslog 足够应对
  • 日志格式相对固定,不需要复杂的解析逻辑

实践建议: 按设备类型分类存储

/var/log/remote/routers/          # 路由器日志
/var/log/remote/switches/ # 交换机日志
/var/log/remote/firewalls/ # 防火墙日志

场景二:合规审计与长期日志留存

典型需求:

  • 金融、政务等行业要求日志长期留存
  • 需要记录用户敏感操作:登录、数据修改、权限变更等
  • 多系统、多应用的日志需要统一收集和存储
  • 合规检查时需要能快速调取历史日志

为什么选 Syslog:

  • 文本格式便于归档到冷存储(如 NAS、对象存储)
  • 可以按系统/业务线分别存储,便于审计调取
  • 日志格式简单、可读性强,审计人员可以直接查看

实践建议:

  1. 按业务线或系统分类存储
/var/log/remote/trading-system/      # 交易系统日志
/var/log/remote/user-center/ # 用户中心日志
/var/log/remote/payment-gateway/ # 支付网关日志
  1. 在日志中增加审计关键字段
log.info("AUDIT | userId:{} | action:{} | resource:{} | result:{}",
userId, "UPDATE_ORDER", "order-12345", "SUCCESS");

场景三:边缘计算与 IoT 设备

典型需求:

  • 分布在各地的边缘网关、IoT 设备需要上报日志
  • 网络环境不稳定,需要可靠的传输机制
  • 设备资源有限(CPU、内存、存储)

为什么选 Syslog:

  • 协议简单,对设备资源消耗极小
  • 支持 TCP/RELP 保证传输可靠性
  • 中心服务器资源要求低

场景四:传统应用系统改造

典型需求:

  • 老旧应用(如单体应用、C/S 架构)需要接入日志系统
  • 应用代码改动成本要低
  • 不能引入复杂的依赖

为什么选 Syslog:

  • 改动最小,只需要替换日志框架的 appender
  • 不需要应用本身安装任何组件
  • 对应用性能影响几乎可以忽略

为什么选 Syslog:

  • Syslog 单向通信,只需开放一个端口(通常 514)
  • 可以在各云环境部署轻量级转发器
  • 中心服务器可以部署在任意位置

实战:搭建一个 Syslog 服务器

以 Ubuntu 为例,使用 rsyslog 搭建日志服务器:

# 安装 rsyslog(通常系统已预装)
sudo apt install rsyslog

# 编辑配置文件
sudo vim /etc/rsyslog.conf

取消以下行的注释(启用 UDP 和 TCP 接收):

# 提供 UDP 接收
module(load="imudp")
input(type="imudp" port="514")

# 提供 TCP 接收
module(load="imtcp")
input(type="imtcp" port="514")

配置日志存储规则:

# 根据主机名分别存储
$template DynamicFile,"/var/log/remote/%HOSTNAME%/%$YEAR%-%$MONTH%-%$DAY%.log"

*.* ?DynamicFile

重启服务:

sudo systemctl restart rsyslog

现在,客户端就可以向这台服务器发送日志了:

# 使用 logger 命令测试
logger -n 192.168.1.10 -P 514 "Hello from client"

日志会保存到 /var/log/remote/client-hostname/2023-12-29.log。

如何分析和使用

实际上,日志收集只是第一步,后续的分析和使用才是关键。

方式一:命令行快速分析(最适合运维人员)

Syslog 日志是纯文本,Linux 原生工具完全够用。

1. grep 快速检索

# 查找错误日志
grep -i "error" /var/log/remote/*/*.log

# 查找特定时间段的日志
grep "2023-12-29T10:" /var/log/remote/*/*.log

# 查找特定 IP 的访问记录
grep "192.168.1.100" /var/log/remote/firewalls/*.log

2. awk 提取关键字段

# 提取所有登录失败记录
awk /Failed password/ {print $1, $2, $NF}' /var/log/remote/*.log

# 统计每种错误类型的出现次数
awk -F'ERROR: ' '{print $2}' /var/log/remote/*.log | sort | uniq -c | sort -rn

3. sed 批量处理

# 去除重复日志
sort /var/log/remote/app.log | uniq > app-unique.log

# 提取 JSON 格式的结构化数据
sed -n 's/.*User action: \(.*\)/\1/p' /var/log/remote/app.log | jq .

4. 实时监控(类似 tail -f)

# 实时监控所有主机的 error 日志
tail -f /var/log/remote/*/*.log | grep --line-buffered -i error

# 使用 multitail 同时监控多个文件
multitail /var/log/remote/server01/*.log /var/log/remote/server02/*.log

方式二:使用 Syslog 可视化工具

1. Graylog

Graylog 是一个开源的日志管理平台,支持通过 syslog 协议收集、解析和分析日志数据,专注于日志收集和分析。

# 安装 Graylog(MongoDB + Elasticsearch + Graylog Server)
docker run --name mongo -d mongo:4
docker run --name elasticsearch -d elasticsearch:7
docker run --link mongo --link elasticsearch -p 9000:9000 -d graylog/graylog

配置 Syslog 输入后,就可以在 Web 界面进行:

  • 全文搜索
  • 字段过滤
  • 仪表盘可视化
  • 告警规则配置

2. 已有 ELK?Filebeat Syslog 模块

如果你已经在用 ELK,可以直接用 Filebeat 的 Syslog 模块,无需额外部署:

# filebeat.yml
filebeat.inputs:
- type: syslog
protocol.udp:
host: "0.0.0.0:514"
max_message_size: 10MiB

output.elasticsearch:
hosts: ["localhost:9200"]

方式三:搭建轻量级日志查询平台

如果你不想引入重型组件,可以自己搭建一个简单的查询平台。

lnav 是一个命令行工具,但提供了类似 IDE 的日志浏览体验:

# 安装
apt install lnav

# 使用:自动解析日志格式,支持时间线、过滤、高亮
lnav /var/log/remote/*/*.log

功能包括:

  • 自动着色和高亮
  • 时间轴视图
  • SQL 查询支持
  • 日志格式自动识别

Spring Boot 应用如何集成 Syslog

Java 应用集成 Syslog 也很简单,最常用的是 logback-syslog 或者 log4j-syslog-appender。

以 Logback 为例,添加依赖:

<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.4</version>
</dependency>

配置 logback-spring.xml:

<configuration>
<appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
<syslogHost>192.168.1.10</syslogHost>
<port>514</port>
<facility>LOCAL1</facility>
<suffixPattern>%app [%thread] %logger %msg</suffixPattern>
</appender>

<root level="INFO">
<appender-ref ref="SYSLOG" />
<consoleAppender />
</root>
</configuration>

代码里照常使用 Logger:

@Slf4j
@RestController
public class UserController {

@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
log.info("Fetching user by id: {}", id);
return userService.getById(id);
}
}

所有日志都会自动发送到 Syslog 服务器,不需要任何特殊处理。

Syslog vs ELK/Loki:如何选择

选择Syslog的场景

1. 网络设备日志收集:路由器、交换机、防火墙等设备原生支持
2. 合规审计场景:金融、政务行业要求日志长期保存,Syslog 简单可靠
3. 资源受限环境:边缘计算、嵌入式设备、老旧服务器
4. 简单固定需求:只需要收集和存储,不需要太复杂的检索分析
5. 低成本优先:预算有限,需要轻量化的收集方案

选择 ELK/Loki等方案的场景

1. 需要全文搜索:运维人员要快速定位问题
2. 需要可视化分析:仪表盘、趋势图、异常检测
3. 大规模微服务:日志量大,需要分布式存储和处理
4. 需要日志关联:跨服务的 trace ID 关联分析
5. 实时分析需求:需要实时监控和告警

其实两者可以结合使用。比如用 Syslog 收集设备日志和审计日志(需要长期保存),同时用 Loki 收集应用日志(需要快速检索)。

一些实用建议

1. 使用 TCP

UDP 虽然快,但不保证送达。网络拥塞时可能丢日志,如需要保证日志发送的可靠性,可使用 TCP 或者 RELP(Reliable Event Logging Protocol):

<!-- 使用 TCP 的配置示例 -->
<appender name="SYSLOG_TCP" class="ch.qos.logback.classic.net.SyslogAppender">
<syslogHost>192.168.1.10</syslogHost>
<port>514</port>
<facility>LOCAL1</facility>
<suffixPattern>%app [%thread] %logger %msg</suffixPattern>
<useExactLine>true</useExactLine>
</appender>

2. 做好日志轮转

Syslog 日志会无限增长,记得配置 logrotate:

/var/log/remote/*/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 syslog syslog
}

3. 注意时区问题

Syslog 协议本身不包含时区信息,RFC5424 要求使用 UTC 时间。如果你的应用部署在不同时区,记得统一时间标准。

4. 结构化数据可以用 JSON

RFC5424 支持结构化数据(STRUCTURED-DATA),但格式比较复杂。更实用的做法是直接把 JSON 放在 MSG 字段里:

log.info("User action: {}", objectMapper.writeValueAsString(Map.of(
"userId", 12345,
"action", "login",
"ip", "192.168.1.100"
)));

5. 做好日志分级

不是所有日志都需要发送到 Syslog 服务器:

// 只发送 INFO 及以上级别
<root level="INFO">
<appender-ref ref="SYSLOG" />
</root>

// DEBUG 日志只输出到本地文件
<logger name="com.example" level="DEBUG" additivity="false">
<appender-ref ref="FILE" />
</logger>

6. 考虑日志加密

Syslog 本身不加密,敏感场景需要使用 TLS:

# rsyslog TLS 配置
module(load="gtls")

# 服务器端
input(type="imtcp" port="6514")
action(name="tls-input" type="omrelp"
target="server.example.com" port="6514"
tls="on"
tls.authMode="x509/name")

总结

Syslog 不是什么高大上的技术,但它胜在简单、稳定、兼容性好。如果你的日志需求不复杂,或者需要对接各类网络设备,Syslog 依然是非常实用的选择。

工具没有银弹,适合的才是最好的。下次做日志方案选型时,不妨把 Syslog 也列入考虑范围。

文章目录
  1. 1. 什么是 Syslog
  2. 2. Syslog 的特点与优势
    1. 2.0.1. 第一,它足够简单
    2. 2.0.2. 第二,标准化程度高
    3. 2.0.3. 第三,整体资源消耗低
  • 3. Syslog 的典型适用场景
    1. 3.0.1. 场景一:网络设备日志集中管理
    2. 3.0.2. 场景二:合规审计与长期日志留存
    3. 3.0.3. 场景三:边缘计算与 IoT 设备
    4. 3.0.4. 场景四:传统应用系统改造
  • 4. 实战:搭建一个 Syslog 服务器
  • 5. 如何分析和使用
    1. 5.0.1. 方式一:命令行快速分析(最适合运维人员)
    2. 5.0.2. 方式二:使用 Syslog 可视化工具
    3. 5.0.3. 方式三:搭建轻量级日志查询平台
  • 6. Spring Boot 应用如何集成 Syslog
  • 7. Syslog vs ELK/Loki:如何选择
    1. 7.0.1. 选择Syslog的场景
    2. 7.0.2. 选择 ELK/Loki等方案的场景
  • 8. 一些实用建议
    1. 8.0.1. 1. 使用 TCP
    2. 8.0.2. 2. 做好日志轮转
    3. 8.0.3. 3. 注意时区问题
    4. 8.0.4. 4. 结构化数据可以用 JSON
    5. 8.0.5. 5. 做好日志分级
    6. 8.0.6. 6. 考虑日志加密
  • 9. 总结