Logstash问题:Kinesis转S3 CSV时JSON冒号被替换为箭头
问题描述
从Kinesis读取数据并将CSV文件上传至S3时,生成的CSV文件中JSON数据里的冒号(:)被替换成了箭头(=>),以下是Logstash配置文件:
input { kinesis { application_name => "logstash" kinesis_stream_name => "events" type => "kinesis" region => "us-east-1" profile => "default" metrics => "cloudwatch" codec => "json" } } filter { grok { match => { "[data][ti]" => "%{YEAR:event_year}-%{MONTHNUM2:event_month}-%{MONTHDAY:event_day}" } } } output { s3 { bucket => "test-logstash" region => "us-east-1" prefix => "%{event_year}/%{event_month}/%{event_day}/%{[data][brandid]}/%{[data][event_name]}" encoding => "none" codec => csv { separator => "␁" } size_file => 200000000 time_file => 60 } }
解决方案
这个问题是因为Logstash的CSV codec处理哈希类型字段时,会默认调用Ruby的inspect方法将其转为字符串,导致JSON结构里的:被替换成Ruby哈希格式的=>。可以通过两种方式解决:
方法1:将嵌套JSON字段序列化为标准JSON字符串
在filter阶段添加mutate插件,把嵌套的哈希字段转成JSON字符串,这样CSV输出时就是正常的JSON格式:
filter { grok { match => { "[data][ti]" => "%{YEAR:event_year}-%{MONTHNUM2:event_month}-%{MONTHDAY:event_day}" } } # 将data字段序列化为标准JSON字符串 mutate { json_encode => "[data]" } }
方法2:明确指定CSV输出的字段
如果不需要输出整个嵌套的JSON结构,而是需要其中的具体子字段,可以在CSV codec里指定fields参数,直接输出单个字段值,避免处理哈希结构:
output { s3 { bucket => "test-logstash" region => "us-east-1" prefix => "%{event_year}/%{event_month}/%{event_day}/%{[data][brandid]}/%{[data][event_name]}" encoding => "none" codec => csv { separator => "␁" # 列出需要输出的字段,比如时间字段、data下的具体子字段 fields => ["event_year", "event_month", "event_day", "[data][brandid]", "[data][event_name]"] } size_file => 200000000 time_file => 60 } }
内容的提问来源于stack exchange,提问作者Nishant Dixit
相关产品推荐
相关产品推荐

