-
VictoriaLogs 和 Vector 的使用分享
victoriaLogs 是什么
VictoriaLogs 是 VictoriaMetrics 体系里的日志数据库,目标是把“写入吞吐、存储成本、查询效率、运维复杂度”这四个维度做到更均衡:一个服务就能跑起来,HTTP 端口默认 9428,常见的采集侧(Vector / FluentBit / Filebeat 等)可以直接对接它的写入 API。
核心数据模型
-
消息字段:
_msg -
时间字段:
_time -
流字段(stream fields) :决定日志如何被分组与存储(类似 Loki 的 labels,但语义更贴近“分流/分桶”)
并且在写入时,你可以通过 query 参数/headers 显式指定:
-
_msg_field:哪一个字段是日志正文 -
_time_field:哪一个字段是时间戳 -
_stream_fields:哪些字段作为 stream fields
stream fields 不要高基数
stream fields 必须“稳定、低基数” ,比如
host / instance / pod / container / service / env 这种。把trace_id / user_id / ip之类高基数放进去,会制造海量 streams,显著增加资源消耗与查询成本。这点后面会直接影响我们怎么设计
labels/fields(尤其是filepath)。什么时候更适合用 victoriaLogs?
-
vs Elasticsearch / OpenSearch
-
ES 强在生态与全文检索、聚合分析,但运维与成本通常更重(集群、shard、mapping、冷热分层、性能调优)。
-
VictoriaLogs 更像“把日志存起来并快速检索/聚合”,强调更简单的落地与更好的性价比(尤其是规模上来之后)。
-
-
vs Grafana Loki
-
Loki 是 label + chunk,label 设计同样要避免高基数。
-
VictoriaLogs 的 stream fields 也怕高基数,但它把“message/time/stream”的概念讲得更清晰,且写入 API 的兼容面(如 ES bulk / jsonline)让你更容易接入。
-
VictoriaLogs 的搭建
Docker 方式启动
mkdir -p ./victoria-logs-data docker run --rm -it \ -p 9428:9428 \ -v ./victoria-logs-data:/victoria-logs-data \ docker.io/victoriametrics/victoria-logs:latest \ -storageDataPath=victoria-logs-data
-
-storageDataPath:数据目录(默认victoria-logs-data) -
-httpListenAddr:默认:9428 -
-retentionPeriod:日志保留期,默认1w(按需改)
验证查询(LogsQL)
起服务后,可以用
/select/logsql/query直接查:curl http://localhost:9428/select/logsql/query \ -d 'query=error' -d 'limit=10'
这会返回包含
error的最新 10 条。你后续常用的 LogsQL 习惯是:
-
时间范围:
_time:5m / _time:1h / _time:1d -
排除词:
-kubernetes -
排序:
| sort by (_time) -
取最新 N 条:
| first 10 by (_time desc)
Vector 介绍与对比
Vector 是什么
Vector 是一个高性能的可观测数据管道:把 logs/metrics/traces 从各种 source 收进来,经过 transform(核心是 VRL),再发往各种 sink。它本质是一个单一可执行文件,部署和运维路径很“平台友好”。
我们本文会用到:
-
sources
-
journald:从 systemd journal 读日志(需要权限) -
file:tail 文件日志(带 checkpoint)
-
-
transform
-
remap:用 VRL 做字段清洗/补齐/路由(但也是坑最多的部分)
-
-
sink
-
elasticsearch:发往 VictoriaLogs 的/insert/elasticsearch/(官方推荐路径之一)
-
Vector vs Fluent Bit / Fluentd / Logstash / OTel Collector
-
vs Fluent Bit
-
Fluent Bit 更“采集器”,轻量、插件多,但复杂变换要么写 Lua,要么链路拆很多 filter。
-
Vector 的强项是 VRL:写得好非常强,写得不好非常痛苦。
-
-
vs Fluentd / Logstash
-
Fluentd/Logstash 生态成熟,但运行时更重(Ruby/JVM)。
-
Vector 更偏“一个 Rust binary 的工程化组件”。
-
-
vs OpenTelemetry Collector
-
OTel Collector 适合统一 traces/metrics/logs,但日志处理表达力与生态取舍和 Vector 不同。
-
你可以理解为:Vector 更像“日志/可观测数据路由器 + 可编程 transform” 。
-
Vector 的搭建
安装(Linux 常见方式)
官方提供安装脚本/包管理方式(不同发行版略有差异)。
安装后默认配置路径通常是:
-
/etc/vector/vector.yaml
基础运维命令
-
校验配置:
vector validate /etc/vector/vector.yaml
(强烈建议每次改配置先跑它)
-
systemd 管理(包安装通常自带 service):
systemctl enable --now vector systemctl restart vector journalctl -u vector -f
Vector 也支持通过信号触发 reload 的方式(具体以你的部署方式为准)。
Vector 的注意事项
fail-safe + fallible
VRL 是 fail-safe 的——只要存在潜在运行时错误没被处理,编译期就不让你过。这在日志这种“脏数据”有优势,但会显著抬高配置难度。
建议把 VRL 流程固定成下面 3 种:
-
能不用 fallible 函数就不用:优先用
exists() /is_nullish()这类 infallible 的逻辑兜底。 -
本地 REPL:
vector vrl可以进交互 REPL,先把片段跑通再放进配置。 -
Playground:VRL Playground 适合分享/对照输入输出。
可选加速:打开 API 后用
vector tap抽样观察某个组件的事件流,定位字段长什么样。journald 的 include_units / exclude_units
-
journald source 默认要能执行journalctl,且运行用户通常需要在systemd-journal组里。 -
include_units 的规则里,“没带点号的 unit 会自动补.service”。
labels / stream fields 设计——尤其是 filepath
这里要区分两个概念:
-
Vector 里你随便加字段(比如
filepath),这是为了后续查询过滤更方便。 -
VictoriaLogs 的
_stream_fields 是“用来分组存储的关键字段”,不能高基数。
建议
-
filepath:只做普通字段,不要进 _stream_fields(k8s/nomad 场景会爆炸式增长)。 -
额外做一个低基数的
file_group(或app/component):-
例如把
/var/log/nginx/access.log、/var/log/nginx/error.log 归到file_group=nginx -
把
/var/log/myapp/*.log 归到file_group=myapp
-
-
_stream_fields 推荐起步:host,service,env,source,file_group(再按场景微调)
Vector 部署到 Linux
配置步骤
下面介绍 Vector 部署到 Linux,并发送 journald + file 日志到 VictoriaLogs
前置:确保 Vector 能读 journald
# 常见做法:把 vector 用户加入 systemd-journal 组 sudo usermod -aG systemd-journal vector sudo systemctl restart vector
/etc/vector/vector.yaml(journald + file → vlogs)
你只需要改两块: 1)file include 路径 2)VictoriaLogs 地址(
endpoints)# /etc/vector/vector.yaml data_dir/var/lib/vector # 可选:开启 API,方便 vector tap 调试 api enabledtrue address127.0.0.18686 sources s_journald typejournald # 默认 current_boot_only: true(只读本次开机后的日志) # 建议:先不写 include_units,跑通后再收敛 exclude_matches _TRANSPORT kernel s_file typefile include /var/log/nginx/*.log /var/log/myapp/*.log transforms t_normalize typeremap inputs"s_journald" "s_file" # drop_on_abort 默认 true;这里显式写出来更直观 drop_on_aborttrue source- # 固定环境标识(也可以改成从环境变量注入) .env = "prod" # 来源类型:journald / file .source = .source_type # 文件路径:只做普通字段,不进入 stream_fields if .source_type == "file" .filepath = .file # service 归一化:journald 优先取 unit / identifier if .source_type == "journald" if !is_nullish(._SYSTEMD_UNIT) .service = ._SYSTEMD_UNIT else if !is_nullish(.SYSLOG_IDENTIFIER) .service = .SYSLOG_IDENTIFIER else if !is_nullish(._COMM) .service = ._COMM else .service = "unknown" # file_group:把高基数 filepath 收敛成低基数分组(用于 stream_fields) if .source_type == "file" if starts_with(.file "/var/log/nginx/") .service = "nginx" .file_group = "nginx" else if starts_with(.file "/var/log/myapp/") .service = "myapp" .file_group = "myapp" else .service = "file" .file_group = "other" # 防御:空 message 直接丢弃(避免写入侧出现“missing _msg field”类噪音) if is_nullish(.message) abort sinks vlogs typeelasticsearch inputs"t_normalize" endpoints "http://YOUR_VLOGS_HOST:9428/insert/elasticsearch/" api_versionv8 compressiongzip healthcheck enabledfalse query _msg_fieldmessage _time_fieldtimestamp _stream_fieldshost,service,env,source,file_group # 初次联调建议打开,确认字段与 stream_fields 是否符合预期 # debug: "1"
这份 sink 的写法是 VictoriaLogs 官方“Vector → VictoriaLogs(Elasticsearch 协议)”推荐配置的同款思路:
-
写入地址:
/insert/elasticsearch/ -
_msg_field=message、_time_field=timestamp、_stream_fields=...
也可以用 HTTP jsonline 的方式写入(
/insert/jsonline + newline_delimited),官方也给了模板。启动与验证
-
校验配置:
vector validate /etc/vector/vector.yaml -
重启 Vector:
systemctl restart vector journalctl -u vector -f
-
制造两种日志:
-
journald:
logger -t demo "hello from journald" -
file:
echo "hello from file" >> /var/log/myapp/app.log
-
在 VictoriaLogs 查:
curl http://YOUR_VLOGS_HOST:9428/select/logsql/query \ -d 'query=hello _time:1h' -d 'limit=20'
LogsQL 里
_time:1h、limit这类用法是最常用的排障入口。
常见问题
-
写入侧出现 “missing _msg field”
-
先确认 sink 里
_msg_field 指向的字段确实存在(本文用message) -
如果你在 remap 里改过字段名,确保最后还有
message -
VictoriaLogs 对
_msg/_time/_stream的概念解释在 Key Concepts 里,值得快速扫一遍。
-
-
stream 爆炸、写入变慢、查询变慢
-
99% 是
_stream_fields 里塞了高基数字段(最常见就是filepath /trace_id /user_id) -
回到“低基数、稳定”的原则:
host/service/env/source/(container/pod)这类。
-
-
VRL 写不动
-
用
vector vrlREPL / Playground 先把局部片段跑通再粘贴进配置。
-
-