Ruby Logstash-csv输出标题
我正在尝试使用请求数据库,并返回带有标题的csv输出文件 我花了很多时间在日志存储文档上,但我仍然遗漏了一点 使用下面的logstash配置,结果会给我一个文件,每行都有标题。我找不到一种方法来仅为logstash配置中的第一行添加标题 非常感谢你的帮助 输出文件 文件:simple-out.confRuby Logstash-csv输出标题,ruby,csv,logstash,Ruby,Csv,Logstash,我正在尝试使用请求数据库,并返回带有标题的csv输出文件 我花了很多时间在日志存储文档上,但我仍然遗漏了一点 使用下面的logstash配置,结果会给我一个文件,每行都有标题。我找不到一种方法来仅为logstash配置中的第一行添加标题 非常感谢你的帮助 输出文件 文件:simple-out.conf 感谢您在输出中获得多个标题的原因是Logstash没有事件之间的全局/共享状态的概念,每个项目都是独立处理的,因此每次CSV输出插件运行时,它的行为都与第一个一样并写入标题 我也遇到了同样的问题,
感谢您在输出中获得多个标题的原因是Logstash没有事件之间的全局/共享状态的概念,每个项目都是独立处理的,因此每次CSV输出插件运行时,它的行为都与第一个一样并写入标题 我也遇到了同样的问题,并找到了一个解决方案,使用ruby过滤器的选项在logstash启动时执行一些代码 下面是一个logstash配置示例:
# csv-headers.conf
input {
stdin {}
}
filter {
ruby {
init => "
begin
@@csv_file = 'output.csv'
@@csv_headers = ['A','B','C']
if File.zero?(@@csv_file) || !File.exist?(@@csv_file)
CSV.open(@@csv_file, 'w') do |csv|
csv << @@csv_headers
end
end
end
"
code => "
begin
event['@metadata']['csv_file'] = @@csv_file
event['@metadata']['csv_headers'] = @@csv_headers
end
"
}
csv {
columns => ["a", "b", "c"]
}
}
output {
csv {
fields => ["a", "b", "c"]
path => "%{[@metadata][csv_file]}"
}
stdout {
codec => rubydebug {
metadata => true
}
}
}
您将获得包含以下内容的output.csv
文件:
A,B,C
1,2,3
4,5,6
7,8,9
这也是线程安全的,因为它只在启动时运行代码,所以您可以使用多个工作线程
希望有帮助 我使用的动态文件名利用了事件日期(index-yyy-MM-DD.csv),因此在管道开始时写入标题对我来说不是一个可行的选择 相反,我允许写入重复的头,并设置一个cron作业,每隔几分钟运行一次,删除所有重复的行,然后将结果写回同一个文件
#!/bin/bash -xe
for filename in /tmp/logstash/*.csv; do awk '!v[$1]++' $filename > $filename.tmp && mv -f $filename.tmp $filename; done
注意:这仅在我提取数百MB数据的实例上进行测试-如果您的数据管道每分钟摄取GB,这可能不是一个可行的选项。如果将write_头设置为false,会发生什么情况?我想这通常是不可能的,因为logstash需要非关系数据集,其中每行的列可能不同。无论您是否担心字段是相同的,我都会使用旧的good
Array#uniq
作为结果。后者将以10个代码符号的形式为您提供所需的内容。@JLB如果我设置了write_头,我的输出文件将不会返回任何头,甚至在第一行也不会返回任何头。@mudasobwa感谢您的建议,但我希望在以后的步骤中尽可能使用Logstash逻辑来包含不同的输入。如果不可能,我宁愿在处理输出文件之前使用脚本添加标题。谢谢。如果你a)关闭标题,b)将第一行数据设置为你想要的列名,那该怎么办?你让我开心了!非常感谢@xmarcos。。你的例子真的很有帮助。
echo "1,2,3\n4,5,6\n7,8,9" | ./bin/logstash -f csv-headers.conf
A,B,C
1,2,3
4,5,6
7,8,9
#!/bin/bash -xe
for filename in /tmp/logstash/*.csv; do awk '!v[$1]++' $filename > $filename.tmp && mv -f $filename.tmp $filename; done