除了 ELK、Loki,你还应该知道的日志收集方式:Syslog

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

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

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

什么是 Syslog

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

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

csharp 复制代码
<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) 这个字段比较特殊,它由两部分组成:

ini 复制代码
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),发一条消息过去就完事了。客户端实现非常简单,几行代码就能搞定:

java 复制代码
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 系统自带的 rsyslogsyslog-ng 都能直接接收和存储。

第二,标准化程度高

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

bash 复制代码
# Cisco 设备配置示例
logging host 192.168.1.10
logging trap warnings

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

第三,整体资源消耗低

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

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

Syslog 的典型适用场景

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

典型需求:

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

为什么选 Syslog:

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

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

bash 复制代码
/var/log/remote/routers/          # 路由器日志
/var/log/remote/switches/         # 交换机日志
/var/log/remote/firewalls/        # 防火墙日志

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

典型需求:

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

为什么选 Syslog:

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

实践建议:

  1. 按业务线或系统分类存储
bash 复制代码
/var/log/remote/trading-system/      # 交易系统日志
/var/log/remote/user-center/         # 用户中心日志
/var/log/remote/payment-gateway/     # 支付网关日志
  1. 在日志中增加审计关键字段
java 复制代码
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 搭建日志服务器:

bash 复制代码
# 安装 rsyslog(通常系统已预装)
sudo apt install rsyslog

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

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

ini 复制代码
# 提供 UDP 接收
module(load="imudp")
input(type="imudp" port="514")

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

配置日志存储规则:

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

*.* ?DynamicFile

重启服务:

bash 复制代码
sudo systemctl restart rsyslog

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

bash 复制代码
# 使用 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 快速检索

bash 复制代码
# 查找错误日志
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 提取关键字段

bash 复制代码
# 提取所有登录失败记录
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 批量处理

bash 复制代码
# 去除重复日志
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)

bash 复制代码
# 实时监控所有主机的 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 协议收集、解析和分析日志数据,专注于日志收集和分析。

bash 复制代码
# 安装 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 模块,无需额外部署:

yaml 复制代码
# 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 的日志浏览体验:

bash 复制代码
# 安装
apt install lnav

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

功能包括:

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

Spring Boot 应用如何集成 Syslog

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

以 Logback 为例,添加依赖:

xml 复制代码
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.4</version>
</dependency>

配置 logback-spring.xml

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:

java 复制代码
@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):

xml 复制代码
<!-- 使用 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

bash 复制代码
/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 字段里:

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

5. 做好日志分级

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

java 复制代码
// 只发送 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:

bash 复制代码
# 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 也列入考虑范围。

相关推荐
IT_陈寒2 小时前
Java 21新特性实战:5个必学的性能优化技巧让你的应用提速40%
前端·人工智能·后端
JaguarJack2 小时前
如何使用 PHP 的 for、while 和 foreach 循环实现极致性能与零 Bug 代码
后端·php
BingoGo2 小时前
如何使用 PHP 的 for、while 和 foreach 循环实现极致性能与零 Bug 代码
后端·php
程序员三明治4 小时前
【重学计网】TCP如何保证可靠传输?怎么保证可靠性?可靠传输的原理?
java·网络·后端·网络协议·tcp/ip·tcp·可靠传输
上进小菜猪11 小时前
基于 YOLOv8 的驾驶员疲劳状态识别系统实战(含完整源码与可视化界面)
后端
上进小菜猪11 小时前
基于 YOLOv8 的交通标识与设施识别系统(含完整源码)
后端
程序员-周李斌12 小时前
Java 死锁
java·开发语言·后端
布列瑟农的星空12 小时前
还在手动翻译国际化词条?AST解析+AI翻译实现一键替换
前端·后端·ai编程
武子康12 小时前
大数据-197 K折交叉验证实战:sklearn 看均值/方差,选更稳的 KNN 超参
大数据·后端·机器学习