一、先搞懂啥是Vector,为啥要跟老日志工具搭伙
先给没接触过Vector的朋友说清楚:它是个专门干“数据搬运+简单加工”的工具,主要针对日志、指标、链路追踪这些数据。简单说就是“数据的快递员”——把数据从A地运到B地,路上还能给数据贴标签、拆包装、去杂质。
那为啥要跟传统日志采集工具搭伙?比如公司用了好几年的Logstash、Flume、Filebeat,甚至自己写的Python日志脚本,突然要换Vector,全换成本太高、风险大,所以得先让新旧工具一起干活,慢慢过渡。
二、Vector跟传统日志工具集成的常见难题
2.1 难题一:数据格式不兼容,老工具不认Vector的“快递盒”
传统日志工具(比如Logstash)有自己的“标准快递盒”,比如Logstash要求每条日志必须是带@timestamp、message、level这些固定字段的JSON格式。但Vector运过来的日志可能是纯文本、半结构化,或者字段名跟Logstash要求的不一样,老工具拿到手根本拆不开。
举个真实场景:公司老的Logstash流水线要求每条日志必须有@timestamp(时间戳,格式必须是ISO 8601,比如2024-05-20T12:34:56Z)、message(日志内容)、level(日志级别)。但Vector从Nginx采集的日志是纯文本的,格式是[20/May/2024:12:34:56 +0000] "GET /api/user HTTP/1.1" 200 1234,直接给Logstash的话,Logstash根本识别不了,会报错。
2.2 难题二:数据丢包,新旧工具“对接缝隙”漏数据
新旧工具之间的对接就像两个水龙头接水管,中间的缝隙如果没封好,水就漏了。Vector和传统工具的对接缝隙主要是“连接不稳定”“缓冲区太小”“超时设置不合理”。
比如用Flume采集应用日志,Flume的默认连接超时是5秒,Vector的发送超时是10秒,两边超时不匹配的话,当网络波动时,Vector发的日志Flume还没来得及处理,Flume就断开连接了,Vector再发就会丢数据。还有Flume的缓冲区默认只有1024条日志,当日志量突然变大(比如双11),缓冲区满了之后,新的日志就会被丢弃。
2.3 难题三:性能拖垮,老工具扛不住Vector的“快递量”
Vector的性能比传统工具强很多,比如Vector每秒能处理10万条日志,而老的Logstash流水线可能每秒只能处理1万条。如果Vector直接把10万条日志一股脑塞给Logstash,Logstash会被压垮,出现延迟、丢包,甚至直接崩溃。
比如某公司用Vector采集K8s集群的日志,每秒产生8万条,直接发给老的Logstash流水线,结果Logstash的CPU占用率瞬间飙到100%,日志延迟从原来的10秒变成了1小时,很多业务日志根本没法及时查看。
2.4 难题四:监控告警断链,不知道对接出问题
新旧工具集成后,原来的监控告警只盯着老工具,比如只监控Logstash的运行状态、日志吞吐量,但Vector这边出问题(比如采集不到日志、发送失败),原来的监控根本发现不了,导致问题发生很久后才被发现。
比如Vector的Nginx采集组件突然宕机,不再采集日志,但原来的监控只看Logstash的吞吐量,Logstash没日志进来,监控以为是业务没产生日志,根本不会告警,直到运维检查业务时才发现日志断了。
三、对应难题的解决方案,附完整示例
3.1 方案一:给Vector装“格式转换器”,让数据适配老工具
核心思路:在Vector这边加一个“加工环节”,把数据转换成老工具能识别的格式。Vector自带了很多加工组件,比如remap(重映射)、parse(解析)、format(格式化),专门干这个活。
示例:Vector把Nginx日志转换成Logstash要求的格式
技术栈:Vector、Logstash 首先写Vector的配置文件,步骤是:采集Nginx日志→解析纯文本日志→重命名字段→调整时间格式→发送给Logstash。
# Vector配置文件:nginx_to_logstash.yaml
api:
enabled: true
address: "0.0.0.0:8686"
# 1. 采集Nginx的访问日志
sources:
nginx_access_logs:
type: "file" # 采集文件类型的日志
include: ["/var/log/nginx/access.log"] # Nginx日志的路径
start_at_beginning: false # 只采集新产生的日志,不采集历史的
# 2. 加工环节:把纯文本日志转成Logstash要求的格式
transforms:
parse_nginx_log:
type: "parse" # 解析组件
inputs: ["nginx_access_logs"] # 输入是采集到的Nginx日志
parse:
type: "regex" # 用正则解析纯文本
# 正则规则:匹配Nginx日志的各个部分,给每个部分起名字
regex: '^\[(?P<time>[^\]]+)\] "(?P<request>[^"]+)" (?P<status>\d+) (?P<size>\d+)$'
format_for_logstash:
type: "remap" # 重映射组件,用来调整字段和格式
inputs: ["parse_nginx_log"] # 输入是解析后的Nginx日志
remap:
# 1. 把原来的时间格式(20/May/2024:12:34:56 +0000)转成ISO 8601格式
# 先把时间字符串转成时间戳,再转成ISO格式
.@timestamp = to_timestamp!(.time, "%d/%b/%Y:%H:%M:%S %z")
# 2. 把原来的request字段改名为message(Logstash要求的字段名)
.message = .request
# 3. 把原来的status字段转成数字,再映射成level(Logstash要求的字段名)
# 比如200是INFO,404是WARN,500是ERROR
status_num = to_int!(.status)
.level = if status_num >= 500 { "ERROR" } else if status_num >= 400 { "WARN" } else { "INFO" }
# 4. 把原来的size字段改名为size(保留这个字段)
.size = to_int!(.size)
# 5. 删除不需要的字段(原来的time、request、status)
del(.time, .request, .status)
# 3. 发送环节:把加工好的日志发给Logstash
sinks:
logstash_output:
type: "tcp" # 用TCP协议发送,Logstash的输入组件支持TCP
inputs: ["format_for_logstash"] # 输入是加工好的日志
address: "logstash-host:5044" # Logstash的地址和端口(Logstash的输入组件要监听这个端口)
encoding:
codec: "json" # 用JSON格式发送,Logstash能识别
然后写Logstash的配置文件,让Logstash监听Vector发过来的日志:
# Logstash配置文件:vector_input.conf
input {
tcp {
port => 5044 # 监听Vector发过来的端口
codec => json # 用JSON格式解析,和Vector的编码对应
}
}
# 中间的过滤环节(原来的老流水线,不用改)
filter {
# 比如原来的过滤规则:把日志按业务分类
if [message] =~ /\/api\/user/ {
add_tag => "业务A"
}
}
# 输出环节(原来的老流水线,不用改)
output {
elasticsearch {
hosts => ["http://es-host:9200"]
index => "logstash-%{+YYYY.MM.dd}"
}
}
最后启动Vector和Logstash:
# 启动Vector,用刚才写的配置文件
vector --config nginx_to_logstash.yaml
# 启动Logstash,用刚才写的配置文件
logstash -f vector_input.conf
3.2 方案二:给对接处加“缓冲垫”,避免丢数据
核心思路:在Vector和传统工具之间加一个中间缓冲层,或者调整两边的连接参数,让两边的“节奏”匹配。中间缓冲层可以用Kafka、Redis、甚至Vector自己的磁盘缓冲区。
示例:用Vector的磁盘缓冲区解决Flume丢数据的问题
技术栈:Vector、Flume Flume的默认缓冲区太小,连接超时不合理,所以在Vector这边加一个磁盘缓冲区,让Vector先把日志存在本地磁盘,再慢慢发给Flume,即使Flume暂时连不上,日志也不会丢。
Vector的配置文件里,在发送给Flume的环节加磁盘缓冲区:
# Vector配置文件:vector_to_flume.yaml
api:
enabled: true
address: "0.0.0.0:8686"
sources:
app_logs:
type: "file"
include: ["/var/log/app/*.log"]
start_at_beginning: false
sinks:
flume_output:
type: "tcp"
inputs: ["app_logs"]
address: "flume-host:41414" # Flume的监听端口
encoding:
codec: "json"
# 加磁盘缓冲区配置
buffer:
type: "disk" # 用磁盘缓冲区,数据存在本地磁盘,不会因为Vector重启丢数据
max_size: "10GB" # 缓冲区最大占10GB磁盘空间
when_full: "drop_oldest" # 缓冲区满了之后,丢弃最旧的日志(根据业务需求调整,也可以设为block,让Vector暂停采集)
# 调整发送参数,和Flume的超时匹配
send_timeout: "5s" # 发送超时设为5秒,和Flume的超时一致
connection_timeout: "10s" # 连接超时设为10秒
然后调整Flume的配置,让Flume的缓冲区和Vector匹配:
# Flume配置文件:flume_vector.conf
a1.sources = r1
a1.channels = c1
a1.sinks = k1
# Flume的输入:监听Vector发过来的TCP连接
a1.sources.r1.type = netcat
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 41414
a1.sources.r1.channels = c1
# Flume的通道(缓冲区):调大缓冲区大小,和Vector的节奏匹配
a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000 # 缓冲区最大1万条日志,比原来的1024大很多
a1.channels.c1.transactionCapacity = 1000 # 每次处理1000条日志
# Flume的输出(原来的老流水线,不用改)
a1.sinks.k1.type = logger
a1.sinks.k1.channel = c1
启动Vector和Flume:
# 启动Vector
vector --config vector_to_flume.yaml
# 启动Flume
flume-ng agent -c conf -f flume_vector.conf -n a1
3.3 方案三:给Vector加“限速阀”,不让老工具被压垮
核心思路:在Vector这边加一个“限速组件”,控制Vector每秒发给老工具的日志量,让老工具能扛得住。Vector自带了throttle(限速)组件,专门干这个活。
示例:Vector限速发送给老Logstash流水线
技术栈:Vector、Logstash 老Logstash每秒最多能处理1万条日志,所以在Vector的加工环节加一个限速组件,把每秒发送的日志量限制在1万条以内。
Vector的配置文件:
# Vector配置文件:vector_throttle_logstash.yaml
api:
enabled: true
address: "0.0.0.0:8686"
sources:
k8s_logs:
type: "kubernetes_logs" # 采集K8s集群的日志
namespace: "default" # 只采集default命名空间的日志
transforms:
# 1. 限速组件:把每秒的日志量限制在1万条以内
throttle_logs:
type: "throttle"
inputs: ["k8s_logs"]
# 限速规则:每秒最多处理1万条日志
rate: 10000
unit: "second"
# 当日志量超过限速时,丢弃超出的部分(根据业务需求调整,也可以设为暂停采集)
mode: "drop"
sinks:
logstash_output:
type: "tcp"
inputs: ["throttle_logs"] # 输入是限速后的日志
address: "logstash-host:5044"
encoding:
codec: "json"
3.4 方案四:给对接处加“监控探针”,及时发现问题
核心思路:在Vector这边加监控组件,同时把Vector的监控数据和老工具的监控数据整合到一起,形成一个完整的监控链。Vector自带了internal_metrics(内部指标)组件,能采集自己的运行状态,比如采集到的日志量、发送失败的日志量、缓冲区的使用情况等。
示例:Vector把自己的监控数据发给Prometheus,和老工具的监控整合
技术栈:Vector、Prometheus、Logstash 首先写Vector的配置文件,让Vector把自己的监控数据暴露给Prometheus:
# Vector配置文件:vector_monitor.yaml
api:
enabled: true
address: "0.0.0.0:8686"
# 1. 采集Vector自己的内部指标
sources:
vector_metrics:
type: "internal_metrics" # 采集Vector内部的运行指标
interval: "1s" # 每秒采集一次
# 2. 加工指标:只保留需要的指标
transforms:
filter_metrics:
type: "remap"
inputs: ["vector_metrics"]
remap:
# 只保留采集量、发送失败量、缓冲区使用量这三个指标
if .name in ["vector_events_received_total", "vector_events_sent_failed_total", "vector_buffer_used_bytes"] {
. = . # 保留这个指标
} else {
abort() # 丢弃其他指标
}
# 3. 把加工好的指标发给Prometheus
sinks:
prometheus_output:
type: "prometheus_exporter" # 把指标暴露给Prometheus的组件
inputs: ["filter_metrics"]
address: "0.0.0.0:9090" # Prometheus的抓取地址
# 同时保留原来的日志采集和发送(原来的配置)
sources:
app_logs:
type: "file"
include: ["/var/log/app/*.log"]
start_at_beginning: false
sinks:
logstash_output:
type: "tcp"
inputs: ["app_logs"]
address: "logstash-host:5044"
encoding:
codec: "json"
然后配置Prometheus,让Prometheus同时抓取Vector的指标和Logstash的指标:
# Prometheus配置文件:prometheus.yml
scrape_configs:
# 抓取Vector的指标
- job_name: "vector"
static_configs:
- targets: ["vector-host:9090"]
# 抓取Logstash的指标(原来的配置)
- job_name: "logstash"
static_configs:
- targets: ["logstash-host:9600"]
最后在Grafana里做一个仪表盘,同时展示Vector的指标和Logstash的指标,比如:
- 当Vector的
vector_events_received_total停止增长,说明Vector采集不到日志了; - 当Vector的
vector_events_sent_failed_total开始增长,说明Vector发日志给Logstash失败了; - 当Logstash的日志吞吐量停止增长,说明Logstash收不到日志了。
四、应用场景、优缺点、注意事项
4.1 应用场景
- 新旧工具过渡:公司要把老的日志采集系统换成Vector,但不能全换,先让Vector和老工具一起干活,慢慢替换。
- 局部升级:公司只有一部分业务用新的日志采集需求,其他业务还是用老的,所以让Vector只采集新业务的日志,发给老的流水线。
- 性能提升:老的日志流水线性能不够,用Vector采集日志,加工后发给老流水线,提升整体性能。
4.2 技术优缺点
- 优点:
- 成本低:不用全换老工具,减少了替换成本和风险;
- 风险小:新旧工具一起干活,即使Vector出问题,老工具还能继续运行;
- 灵活:可以慢慢调整,比如先让Vector采集一部分业务的日志,再慢慢扩大范围。
- 缺点:
- 复杂度高:新旧工具一起干活,配置和监控都比单独用一个工具复杂;
- 性能瓶颈:老工具的性能还是会限制整体的性能;
- 维护成本高:要同时维护新旧两个工具,增加了维护的工作量。
4.3 注意事项
- 提前测试:在生产环境上线之前,一定要在测试环境测试对接的兼容性、性能、稳定性,避免上线后出问题。
- 监控告警:一定要同时监控新旧工具的运行状态,形成完整的监控链,及时发现问题。
- 慢慢过渡:不要一下子把所有业务的日志都换成Vector采集,先从一个业务开始,测试没问题再扩大范围。
- 备份数据:在过渡期间,一定要做好数据备份,避免因为对接问题丢数据。
五、文章总结
Vector和传统日志采集工具集成,主要要解决四个问题:数据格式不兼容、数据丢包、性能拖垮、监控告警断链。对应的解决方案是:在Vector这边加格式转换、加缓冲垫、加限速阀、加监控探针。
集成的核心思路是“让新旧工具的节奏匹配”,不管是格式、速度、连接参数,都要让两边能互相适配。同时,一定要做好测试、监控、备份,确保集成的稳定性和安全性。
最后,集成只是过渡阶段的选择,最终的目标还是慢慢替换老工具,全用Vector,这样能减少复杂度,提升整体的性能和维护效率。
评论
围绕“Vector与传统日志采集工具集成的常见难题及解决方案”参与讨论