4. Splunk 数据输入基础:类型与配置

说到 Splunk,核心就一件事:把数据搞进来。要是数据进不来,后面分析再花哨也没用。今天咱们就聊聊 Splunk 的三种主要输入方式,以及背后那个关键的配置文件 — inputs.conf。

我个人习惯把数据输入比作“水龙头”。你想想看,Splunk 本身就像一个蓄水池,你得先接好管子让水能流进来。那么,管子有哪几种?怎么接?这就得看具体的场景了。

4.1 三种输入类型:文件、网络、脚本

Splunk 支持的数据输入方式非常灵活,但常用的就三种:文件监控、网络监听 和 脚本定时拉取。咱们挨个儿过一遍。

核心要点:选择哪种输入方式,取决于数据源的位置和传输协议。文件监控适合本地日志文件;网络监听适合 syslog、TCP/UDP 推送;脚本输入适合从 API 或数据库等定制化抓取。

4.1.1 文件监控(monitor)

这是最常用的方式。你只要告诉 Splunk:“帮我盯着这个文件,有新内容就读取”。Splunk 通过轮询和文件系统 Watchdog 机制来检测文件变化。在 inputs.conf 里对应的是 [monitor:///path/to/file] 段。

举个例子,采集 /var/log/secure 的审计日志:

[monitor:///var/log/secure]
sourcetype = linux_secure
index = main
host = my-server
crcSalt = <SOURCE>

这里有几点要注意。第一,crcSalt 是用来避免 Splunk 重复读同一个文件。我遇到过有人把 crcSalt 写成了固定值,结果文件内容改了,Splunk 还以为是同一个文件… 嗯,那是噩梦。第二,如果是日志轮转(logrotate),Splunk 默认会自动跟随 inode 或文件名。

表格对比一下文件监控的几个关键参数:

参数 作用 我的建议
sourcetype 标记数据类型,用于后续解析 一定要设置,否则 Splunk 可能猜错
index 指定数据归哪个索引存储 按业务拆分,方便权限控制
host 标记来源主机 可以用正则自动提取路径名
whitelist / blacklist 正则筛选要监控的文件 常用于通配符目录下的文件过滤
followSymlink 是否跟踪符号链接 默认 true,小心循环链接

4.1.2 网络输入(TCP / UDP)

很多设备(防火墙、路由器、交换机)会把日志通过 syslog 直接推过来。这时候我们就在 Splunk 上开个端口等数据。配置段是 [tcp://:514] 或 [udp://:514]。

[tcp://:514]
sourcetype = syslog
index = main
connection_host = dns

connection_host 可以设为 dns、ip 或 none。我个人习惯用 dns,因为得到的主机名更直观。但注意,DNS 解析会增加延迟。如果服务器量大,建议用 ip 再配合 transform 做解析。

避坑:我曾经在一个项目中配置 UDP 端口 514,结果设备死活发不过来。折腾了半天,发现是云平台的安全组没放行 UDP 流量。嗯,基础检查永远是第一位的。

4.1.3 脚本输入(script)

如果数据源不能直接推送,也没有落盘的文件,那就得靠脚本主动拉取。比如从 Elasticsearch 查询数据,或者从自定义 API 获取指标。配置段是 [script:///usr/local/bin/get_data.sh],加上 interval 参数控制频率。

[script:///usr/local/bin/get_audit_logs.sh]
interval = 300
sourcetype = custom_audit
index = seclogs
disabled = false

这里有个坑:脚本输出必须是标准格式,每一行代表一个事件。如果脚本把多行内容打印在一起,Splunk 就会当成一个事件。我建议在脚本里用 JSON 输出,每行一个 JSON 对象,这样最清晰。

4.2 inputs.conf 深度解析

文件 inputs.conf 位于 $SPLUNK_HOME/etc/system/local/ 或 /opt/splunk/etc/apps/<app>/local/。每个节(stanza)用 [类型://地址] 开头。下面我们看看常见的段和属性。

节名称 说明 常用属性
[monitor://path] 文件/目录监控 disabled, sourcetype, index, host, whitelist, blacklist, followSymlink, crcSalt
[tcp://port] 监听 TCP 端口 disabled, sourcetype, index, connection_host, listenOnIPv6
[udp://port] 监听 UDP 端口 同 TCP,但无 connection_host(UDP 无连接)
[script://path] 定期执行脚本 disabled, interval, sourcetype, index, passAuth, passAuthToken
[default] 全局默认值 可以设置所有输入类型的默认 sourcetype/index,子节可覆盖

4.2.1 全局默认段 [default]

这是个好习惯:在 [default] 里把通用属性设好,后面每个输入只写变化的部分。比如:

[default]
index = main
sourcetype = generic

这样,如果某个 monitor 忘记写 sourcetype,至少有个保底值。不过我还是建议每个输入都显式声明,避免意外——有一次我全局设了 sourcetype=generic,结果几个第三方应用的数据全变成了 generic,后来解析字段全不匹配,排错花了俩小时。

4.2.2 时间戳与多行事件

除了基础属性,inputs.conf 还能控制 Splunk 如何断行、如何识别时间戳。比如 LINE_BREAKER、MUST_BREAK_BEFORE、TIME_PREFIX 等。

举个例子,如果你的日志每行开头都有 ISO 时间: 2025-01-10T12:00:00,Splunk 默认就能识别。但如果遇到无时间戳的连续多行,就需要用 LINE_BREAKER 强制分割。

[monitor:///var/log/app.log]
sourcetype = app_log
LINE_BREAKER = ([\r\n]+)
MUST_BREAK_BEFORE = .

MUST_BREAK_BEFORE = . 表示遇到新的“点”才断行?不是的,这个点是个正则示例,意思是可以定义某种模式作为断行标志。一般来说,保持默认就行,除非日志很特殊。

4.3 实战配置示例:采集 Secrets 审计日志

假设我们有一套秘密管理平台(比如 HashiCorp Vault),它记录的审计日志以 JSON 格式写到 /var/log/vault/audit.json,每行一个事件。我们想把它采集到 Splunk 的 seclogs 索引。

[monitor:///var/log/vault/audit.json]
disabled = false
sourcetype = vault:audit
index = seclogs
host = vault-primary
sourcetype = vault_audit_json
LINE_BREAKER = ([\r\n]+)
TIME_PREFIX = \\"time\\":\\
TIME_FORMAT = %Y-%m-%dT%H:%M:%S.%N%Z

注意:JSON 里的时间字段需要配置 TIME_PREFIX 和 TIME_FORMAT,否则 Splunk 会用事件被读取的时间作为时间戳。不过我的经验是,如果能用 index-time 的选项,也还行;但最好是日志自带时间戳,这样搜索时时间线才准确。

小技巧:编辑器专用 — 写完 inputs.conf 后,在 Splunk 中执行 splunk btool inputs list --debug 可以预览完整的有效配置。我曾经靠这招发现了 app 层配置被 system local 覆盖的问题。

4.4 一张图看懂输入流程

下面这张图梳理了三种输入类型与 inputs.conf 的映射关系。你可以在脑子里过一遍:数据从哪里来,经过哪个输入节,最终进入索引。

Splunk 数据输入架构与 inputs.conf 映射 文件监控 monitor:// 网络流 tcp:// / udp:// 脚本拉取 script:// Splunk 数据管道 解析 → 索引 → 存储 inputs.conf [monitor://...] [tcp://...] [script://...] 常用属性 sourcetype index host disabled interval (script) whitelist (monitor) 三种输入方式通过不同的 stanza 映射到 inputs.conf,公共属性(sourcetype/index/host)是必设项 脚本输入必设 interval,文件监控常用 whitelist 过滤,网络输入注意防火墙规则

4.5 常见踩坑与检查手段

  • 文件路径写错:Splunk 对路径大小写敏感,/var/log 和 /Var/Log 不一样。我习惯先 cat 看文件是否存在。
  • 权限不足:Splunk 进程以 splunk 用户运行,要确保该用户有读取日志文件、执行脚本的权限。我曾被 sudo -u splunk cat /var/log/secure 救过命。
  • 队列积压:如果输入量远大于索引能力,Splunk 会丢数据。监控 indexer_volume 和 inputqueue 能提前发现。
  • 多行事件断裂:有时候脚本输出的多行被 Splunk 当成了多个事件。解决方法是用 LINE_BREAKER 显式定义,或者让脚本输出每行一个完整 JSON。

警告:生产环境禁止直接修改 system/local/inputs.conf,应用应通过自定义 app 的 local 目录部署。否则 Splunk 升级时会覆盖你的配置。