Sha256: 7435ccc13aeee790e2d0a1411a02537313674c38f5270b207ba56fa44750ba4d

Contents?: true

Size: 1.19 KB

Versions: 1

Compression:

Stored size: 1.19 KB

Contents

require "parslet"

module Logfmt
  class Parser < Parslet::Parser
    rule(:ident_byte) { match("[^ \t\r\n\f\"=]") }
    rule(:string_byte) { match("[^\"\\\\]") }
    rule(:garbage) { match("[ \t\r\n\f\"=]").repeat }
    rule(:ident) { ident_byte >> ident_byte.repeat }
    rule(:key) { ident }
    rule(:value) {
      (ident.as(:value) | (str('"') >> (string_byte | str('\\') >> 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_sym, val.to_s)
    }
    rule(:pair => { :key => simple(:key) }) {
      Pair.new(key.to_sym, 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.1 lib/logfmt/parser.rb