1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
require "rubygems"
require "ffi"
class Grok < FFI::Struct
module CGrok
extend FFI::Library
ffi_lib "libgrok"
attach_function :grok_new, [], :pointer
attach_function :grok_compilen, [:pointer, :pointer, :int], :int
attach_function :grok_pattern_add,
[:pointer, :pointer, :int, :pointer, :int], :int
attach_function :grok_patterns_import_from_file, [:pointer, :pointer], :int
attach_function :grok_execn, [:pointer, :pointer, :int, :pointer], :int
end
include CGrok
layout :pattern, :string,
:pattern_len, :int,
:full_pattern, :string,
:full_pattern_len, :int,
:__patterns, :pointer, # TCTREE*, technically
:__re, :pointer, # pcre*
:__pcre_capture_vector, :pointer, # int*
:__pcre_num_captures, :int,
:__captures_by_id, :pointer, # TCTREE*
:__captures_by_name, :pointer, # TCTREE*
:__captures_by_subname, :pointer, # TCTREE*
:__captures_by_capture_number, :pointer, # TCTREE*
:__max_capture_num, :int,
:pcre_errptr, :string,
:pcre_erroffset, :int,
:pcre_errno, :int,
:logmask, :uint,
:logdepth, :uint,
:errstr, :string
GROK_OK = 0
GROK_ERROR_FILE_NOT_ACCESSIBLE = 1
GROK_ERROR_PATTERN_NOT_FOUND = 2
GROK_ERROR_UNEXPECTED_READ_SIZE = 3
GROK_ERROR_COMPILE_FAILED = 4
GROK_ERROR_UNINITIALIZED = 5
GROK_ERROR_PCRE_ERROR = 6
GROK_ERROR_NOMATCH = 7
public
def initialize
super(grok_new)
end
public
def add_pattern(name, pattern)
name_c = FFI::MemoryPointer.from_string(name)
pattern_c = FFI::MemoryPointer.from_string(pattern)
grok_pattern_add(self, name_c, name.length, pattern_c, pattern.length)
return nil
end
public
def add_patterns_from_file(path)
path_c = FFI::MemoryPointer.from_string(path)
ret = grok_patterns_import_from_file(self, path_c)
if ret != GROK_OK
raise ArgumentError, "Failed to add patterns from file #{path}"
end
return nil
end
public
def pattern
return self[:pattern]
end
public
def expanded_pattern
return self[:full_pattern]
end
public
def compile(pattern)
pattern_c = FFI::MemoryPointer.from_string(pattern)
ret = grok_compilen(self, pattern_c, pattern.length)
if ret != GROK_OK
raise ArgumentError, "Compile failed: #{self[:errstr]})"
end
return ret
end
public
def match(text)
match = Grok::Match.new
text_c = FFI::MemoryPointer.from_string(text)
rc = grok_execn(self, text_c, text.size, match)
case rc
when GROK_OK
# Give the Grok::Match object a reference to the 'text_c'
# object which is also Grok::Match#subject string;
# this will prevent Ruby from garbage collecting it until
# the match object is garbage collectd.
#
# If we don't do this, then 'text_c' will fall out of
# scope at the end of this function and become a candidate
# for garbage collection, causing Grok::Match#subject to become
# corrupt and any captures to point to those corrupt portions.
# http://code.google.com/p/logstash/issues/detail?id=47
match.subject_memorypointer = text_c
return match
when GROK_ERROR_NOMATCH
return false
end
raise ValueError, "unknown return from grok_execn: #{rc}"
end
public
def discover(input)
init_discover if @discover == nil
return @discover.discover(input)
end
private
def init_discover
@discover = GrokDiscover.new(self)
@discover.logmask = logmask
end
end # Grok
require "grok/match"
require "grok/pile"
|