Skip to content

Instantly share code, notes, and snippets.

@til
Created January 15, 2014 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save til/8435371 to your computer and use it in GitHub Desktop.
Save til/8435371 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
# Reads input given in key=value log format and outputs it as CSV.
# Specify the keys as arguments in the order that they should be
# output. Without arguments, it outputs all values.
#
# E.g.
# cat /tmp/production.log | keyvalue2csv time controller action
# 2014-01-14 13:02:04 +0100,products,index,195.87
# 2014-01-14 13:02:04 +0100,products,index,25.82
# 2014-01-14 13:02:04 +0100,products,index,23.38
#
# Or pipe it into psql:
# cat /tmp/production.log | keyvalue2csv time controller action |\
# psql some_database -c "\copy logs (time, controller, action) FROM STDIN CSV"
require 'csv'
slicer = if ARGV.any?
-> (h) { ARGV.map { |key| h.fetch(key) } }
else
-> (h) { h.values }
end
csv = CSV.new(STDOUT)
KEY_RE = '[a-z_]+?='
STDIN.each_line do |line|
pairs = line.scan(/
(?<=^|\s) # must be preceeded by start or space
#{KEY_RE}.*? # the key=value pair
(?=\s#{KEY_RE}|$) # must be followed by another pair or end
/x)
next if pairs.empty?
csv << slicer.call(Hash[*pairs.map { |pair| pair.split('=', 2) }.flatten])
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment