3. 日志采集技术:Syslog协议、Rsyslog配置、Logstash基础、Filebeat轻量采集器

好,咱们进入日志采集这个环节。说实话,PIS系统里日志采集做不好,后面所有分析都是空中楼阁。我见过太多项目,日志倒是生成了,但要么丢包,要么格式乱,要么把服务器磁盘撑爆。嗯,今天咱们就把这四种主流技术捋清楚。

3.1 Syslog协议:日志传输的“通用语言”

Syslog协议,说白了就是一套日志传输的标准。它定义了日志从哪来、到哪去、长什么样。PIS系统里,车载主机、车站服务器、广播控制器,几乎都支持Syslog。

它的核心结构其实很简单:

  • 优先级(Priority):由设施代码和严重级别组合而成。比如“用户级消息+错误”就是一个具体数值。
  • 时间戳(Timestamp):记录事件发生的时间。注意,这里的时间格式是固定的,我建议你统一用UTC,避免时区混乱。
  • 主机名(Hostname):发送日志的设备标识。我在项目中遇到过,两台设备用了同一个主机名,结果日志全混了。所以命名一定要唯一。
  • 消息体(Message):具体的事件描述。这部分最自由,但也最容易出问题。

重要提醒:Syslog默认使用UDP 514端口传输。UDP快,但不保证送达。如果你对日志完整性要求高,建议改用TCP或RELP。

3.2 Rsyslog配置:Linux下的日志“集线器”

Rsyslog是Linux系统上最主流的Syslog实现。它比传统的syslogd强太多了——支持多线程、高并发、还能直接往数据库写。我个人习惯把它当作PIS系统的日志汇聚节点。

一个典型的配置长这样:

# 加载模块
module(load="imuxsock")   # 本地系统日志输入
module(load="imudp")      # UDP接收模块
input(type="imudp" port="514")

# 定义模板,让日志格式更规整
template(name="PISLogFormat" type="string"
         string="%TIMESTAMP% %HOSTNAME% %syslogtag% %msg%\n")

# 接收远程PIS设备日志,按主机名分类存储
if $fromhost-ip startswith '192.168.1.' then {
    action(type="omfile"
           dirCreateMode="0755"
           file="/var/log/pis/%fromhost-ip%/messages.log"
           template="PISLogFormat")
    stop
}

# 把所有日志也转发一份到中央日志服务器
action(type="omfwd"
       target="192.168.100.100"
       port="514"
       protocol="tcp")

你看,这个配置做了三件事:接收、分类、转发。我曾经在一条地铁线上部署过,每天处理上千万条日志,Rsyslog扛得住,关键是别让磁盘写满。

我的经验:配置里一定要加 stop 语句,否则日志会重复处理。还有,生产环境建议把 omfwd 的协议改成TCP,虽然慢一点,但不会丢日志。

3.3 Logstash基础:日志的“数据管道”

Logstash是ELK栈里的“搬运工”。它能把各种格式的日志吃进来,洗一洗,再吐出去。PIS系统的日志格式五花八门,有的用逗号分隔,有的用JSON,有的干脆是自由文本。Logstash就是用来统一这些格式的。

它的工作流程就三步:输入 → 过滤 → 输出。

一个处理PIS日志的简单例子:

input {
  syslog {
    port => 5514
    type => "pis_syslog"
  }
}

filter {
  # 如果日志包含"ERROR",打上标签
  if "ERROR" in [message] {
    mutate {
      add_tag => ["critical"]
    }
  }

  # 解析PIS特定的日志格式
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:log_time} %{DATA:device_id} %{GREEDYDATA:log_content}" }
  }

  # 把时间戳转成标准格式
  date {
    match => ["log_time", "ISO8601"]
    target => "@timestamp"
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "pis-logs-%{+YYYY.MM.dd}"
  }
}

这里我重点说一下 grok 插件。它就像一把万能钥匙,能把非结构化的文本拆成结构化字段。你想想看,如果日志里混着设备ID、时间、错误码,用grok一步就能拆干净。

注意:Logstash吃内存很厉害。我曾经在4G内存的机器上跑,结果OOM了。建议至少8G内存,并且配置 pipeline.workers 参数控制并发数。

3.4 Filebeat轻量采集器:边缘节点的“哨兵”

Filebeat是Elastic公司出的轻量级日志采集器。它跟Logstash最大的区别是:Filebeat只负责“采集和发送”,不负责“处理和转换”。所以它特别轻,CPU和内存占用都很低。

PIS系统里,我通常把Filebeat部署在每台车站服务器或车载主机上。它监控日志文件的变化,一行一行地读,然后发给中央的Logstash或Elasticsearch。

配置起来也很简单:

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/pis/*.log
  fields:
    service_type: pis
    station_id: "station_03"
  fields_under_root: true

output.logstash:
  hosts: ["192.168.100.100:5044"]

# 加个监控,看看有没有丢数据
monitoring.enabled: true

你看,它只关心“读什么文件”和“发给谁”。至于日志里写了什么,它不管。这种设计有个好处——如果Logstash挂了,Filebeat会自己缓存日志,等恢复后再发。不会丢数据。

避坑指南:我曾经遇到过Filebeat重复发送日志的问题。原因是日志文件被轮转(logrotate)时,Filebeat没识别出来。解决办法是配置 close_inactiveclean_inactive 参数,让Filebeat知道文件已经“退役”了。

3.5 四种技术怎么选?一张表说清楚

技术 核心定位 资源消耗 适用场景
Syslog协议 传输标准 极低 所有支持Syslog的设备(如广播控制器、PIS控制器)
Rsyslog 日志汇聚与转发 Linux服务器上的日志集中管理
Logstash 日志解析与转换 需要复杂过滤、格式统一的中央处理节点
Filebeat 轻量采集与发送 极低 边缘节点、嵌入式设备、日志文件采集

我个人建议的架构是:边缘用Filebeat采集,中间用Rsyslog做汇聚,中央用Logstash做解析,最后存到Elasticsearch。这样每一层各司其职,出了问题也好排查。

嗯,日志采集这块就讲这么多。下一章咱们聊聊日志存储和索引,那又是另一番天地了。