Sha256: fb5cd68195ba28b933f389405a06765fd2bd6d1916867f6e5501fc243c497a53

Contents?: true

Size: 1.27 KB

Versions: 1

Compression:

Stored size: 1.27 KB

Contents

require "parslet"

module Logfmt
  class Parser < Parslet::Parser
    rule(:ident_byte) { match['^\s"='] }
    rule(:string_byte) { match['^\\\\"'] }
    rule(:garbage) { match['\s"='].repeat }
    rule(:ident) { ident_byte >> ident_byte.repeat }
    rule(:key) { ident }
    rule(:value) {
      ident.as(:value) |
      str('"') >> (string_byte | str('\"')).repeat.as(:value) >> str('"')
    }
    rule(:pair) {
      (key.as(:key) >> str('=') >> value) |
      (key.as(:key) >> str('=')) |
      key.as(:key)
    }
    rule(:message) {
      (garbage >> pair.as(:pair)).repeat.as(:message) >> garbage
    }
    root(:message)
  end

  class Transformer < Parslet::Transform
    class Pair < Struct.new(:key, :val); end

    rule(:message => subtree(:ob)) {
      (ob.is_a?(Array) ? ob : [ ob ]).inject({}) { |h, p| h[p.key] = p.val; h }
    }
    rule(:pair => { :key => simple(:key), :value => simple(:val) }) {
      Pair.new(key.to_s, val.to_s)
    }
    rule(:pair => { :key => simple(:key), :value => sequence(:val) }) {
      Pair.new(key.to_s, "")
    }
    rule(:pair => { :key => simple(:key) }) {
      Pair.new(key.to_s, true)
    }
  end

  def self.parse(logs)
    parser = Parser.new
    transformer = Transformer.new

    tree = parser.parse(logs)
    transformer.apply(tree)
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
logfmt-0.0.3 lib/logfmt/parser.rb