logstash-codec-protobuf 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +15 -2
- data/docs/index.asciidoc +8 -0
- data/lib/logstash/codecs/protobuf.rb +154 -58
- data/logstash-codec-protobuf.gemspec +1 -2
- data/spec/codecs/protobuf3_spec.rb +143 -48
- data/spec/codecs/protobuf_spec.rb +69 -41
- data/spec/helpers/pb2/event.pb.rb +19 -0
- data/spec/helpers/pb2/event.proto +12 -0
- data/spec/helpers/pb2/header/header.pb.rb +16 -0
- data/spec/helpers/pb2/header/header.proto +8 -0
- data/spec/helpers/pb3/header/header.proto3 +7 -0
- data/spec/helpers/pb3/header/header_pb.rb +12 -0
- data/spec/helpers/pb3/messageA.proto3 +12 -0
- data/spec/helpers/pb3/messageA_pb.rb +16 -0
- data/spec/helpers/pb3/messageB.proto3 +12 -0
- data/spec/helpers/pb3/messageB_pb.rb +16 -0
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4812c43d851064eacffc5c6fba4719eed4691702
|
4
|
+
data.tar.gz: 88436b13daa031ffb714a0f3b1c9611e4130133a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9e6b75105a06e434fdf6f968e80842ac874bbeb7cf1bd72b7339ce3434e43dd4cdc20e992add4b24e811302f2d4366ee8548426b8813042649ea73617cd14ca
|
7
|
+
data.tar.gz: 53d72f5bdb6b5eac6fb88b4d092dba366c820043a709a0d433cf0ef30e7a52f468a48e46cd8a9e728a2fb9c2775c31fee305fb11e5e4f1d7ac0f7d491389a4dc
|
data/README.md
CHANGED
@@ -27,6 +27,9 @@ Here's an example for a kafka input with protobuf 2:
|
|
27
27
|
{
|
28
28
|
zk_connect => "127.0.0.1"
|
29
29
|
topic_id => "unicorns_protobuffed"
|
30
|
+
key_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
31
|
+
value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
32
|
+
|
30
33
|
codec => protobuf
|
31
34
|
{
|
32
35
|
class_name => "Animals::Unicorn"
|
@@ -40,13 +43,23 @@ Example for protobuf 3:
|
|
40
43
|
{
|
41
44
|
zk_connect => "127.0.0.1"
|
42
45
|
topic_id => "unicorns_protobuffed"
|
46
|
+
key_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
47
|
+
value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
43
48
|
codec => protobuf
|
44
49
|
{
|
45
|
-
|
50
|
+
class_name => "Animals.Unicorn"
|
46
51
|
include_path => ['/path/to/pb_definitions/Animal_pb.rb', '/path/to/pb_definitions/Unicorn_pb.rb']
|
47
52
|
protobuf_version => 3
|
48
53
|
}
|
49
|
-
}
|
54
|
+
}
|
55
|
+
|
56
|
+
For version 3 class names check the bottom of the generated protobuf ruby file. It contains lines like this:
|
57
|
+
|
58
|
+
Animals.Unicorn = Google::Protobuf::DescriptorPool.generated_pool.lookup("Animals.Unicorn").msgclass
|
59
|
+
|
60
|
+
Use the parameter for the lookup call as the class_name for the codec config.
|
61
|
+
|
62
|
+
If you're using a kafka input please also set the deserializer classes as shown above.
|
50
63
|
|
51
64
|
### Class loading order
|
52
65
|
|
data/docs/index.asciidoc
CHANGED
@@ -30,6 +30,8 @@ kafka
|
|
30
30
|
{
|
31
31
|
zk_connect => "127.0.0.1"
|
32
32
|
topic_id => "your_topic_goes_here"
|
33
|
+
key_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
34
|
+
value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
33
35
|
codec => protobuf
|
34
36
|
{
|
35
37
|
class_name => "Animal::Unicorn"
|
@@ -37,6 +39,7 @@ kafka
|
|
37
39
|
}
|
38
40
|
}
|
39
41
|
|
42
|
+
Specifically for the kafka input: please set the deserializer classes as shown above.
|
40
43
|
|
41
44
|
[id="plugins-{type}s-{plugin}-options"]
|
42
45
|
==== Protobuf Codec Configuration Options
|
@@ -70,6 +73,11 @@ module Foods
|
|
70
73
|
# here are your field definitions.
|
71
74
|
|
72
75
|
If your class references other definitions: you only have to add the main class here.
|
76
|
+
For version 3 class names check the bottom of the generated protobuf ruby file. It contains lines like this:
|
77
|
+
|
78
|
+
Animals.Unicorn = Google::Protobuf::DescriptorPool.generated_pool.lookup("Animals.Unicorn").msgclass
|
79
|
+
|
80
|
+
Use the parameter for the lookup call as the class_name for the codec config.
|
73
81
|
|
74
82
|
[id="plugins-{type}s-{plugin}-include_path"]
|
75
83
|
===== `include_path`
|
@@ -4,17 +4,36 @@ require 'logstash/util/charset'
|
|
4
4
|
require 'google/protobuf' # for protobuf3
|
5
5
|
require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffers, for protobuf2
|
6
6
|
|
7
|
-
#
|
7
|
+
# Monkey-patch the `Google::Protobuf::DescriptorPool` with a mutex for exclusive
|
8
|
+
# access.
|
9
|
+
#
|
10
|
+
# The DescriptorPool instance is not thread-safe when loading protobuf
|
11
|
+
# definitions. This can cause unrecoverable errors when registering multiple
|
12
|
+
# concurrent pipelines that try to register the same dependency. The
|
13
|
+
# DescriptorPool instance is global to the JVM and shared among all pipelines.
|
14
|
+
class << Google::Protobuf::DescriptorPool
|
15
|
+
def with_lock
|
16
|
+
if !@mutex
|
17
|
+
@mutex = Mutex.new
|
18
|
+
end
|
19
|
+
|
20
|
+
return @mutex
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# This codec converts protobuf encoded messages into logstash events and vice versa.
|
8
25
|
#
|
9
26
|
# Requires the protobuf definitions as ruby files. You can create those using the [ruby-protoc compiler](https://github.com/codekitchen/ruby-protocol-buffers).
|
10
|
-
#
|
27
|
+
#
|
11
28
|
# The following shows a usage example for decoding protobuf 2 encoded events from a kafka stream:
|
12
29
|
# [source,ruby]
|
13
|
-
# kafka
|
30
|
+
# kafka
|
14
31
|
# {
|
15
32
|
# zk_connect => "127.0.0.1"
|
16
33
|
# topic_id => "your_topic_goes_here"
|
17
|
-
#
|
34
|
+
# key_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
35
|
+
# value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
36
|
+
# codec => protobuf
|
18
37
|
# {
|
19
38
|
# class_name => "Animal::Unicorn"
|
20
39
|
# include_path => ['/path/to/protobuf/definitions/UnicornProtobuf.pb.rb']
|
@@ -23,11 +42,13 @@ require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffer
|
|
23
42
|
#
|
24
43
|
# Same example for protobuf 3:
|
25
44
|
# [source,ruby]
|
26
|
-
# kafka
|
45
|
+
# kafka
|
27
46
|
# {
|
28
47
|
# zk_connect => "127.0.0.1"
|
29
48
|
# topic_id => "your_topic_goes_here"
|
30
|
-
#
|
49
|
+
# key_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
50
|
+
# value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
|
51
|
+
# codec => protobuf
|
31
52
|
# {
|
32
53
|
# class_name => "Animal.Unicorn"
|
33
54
|
# include_path => ['/path/to/protobuf/definitions/UnicornProtobuf_pb.rb']
|
@@ -35,6 +56,7 @@ require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffer
|
|
35
56
|
# }
|
36
57
|
# }
|
37
58
|
#
|
59
|
+
# Specifically for the kafka input: please set the deserializer classes as shown above.
|
38
60
|
|
39
61
|
class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
40
62
|
config_name 'protobuf'
|
@@ -43,7 +65,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
43
65
|
# If your protobuf 2 definition contains modules, prepend them to the class name with double colons like so:
|
44
66
|
# [source,ruby]
|
45
67
|
# class_name => "Animal::Horse::Unicorn"
|
46
|
-
#
|
68
|
+
#
|
47
69
|
# This corresponds to a protobuf definition starting as follows:
|
48
70
|
# [source,ruby]
|
49
71
|
# module Animal
|
@@ -54,14 +76,44 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
54
76
|
# For protobuf 3 separate the modules with single dots.
|
55
77
|
# [source,ruby]
|
56
78
|
# class_name => "Animal.Horse.Unicorn"
|
57
|
-
#
|
79
|
+
# Check the bottom of the generated protobuf ruby file. It contains lines like this:
|
80
|
+
# [source,ruby]
|
81
|
+
# Animals.Unicorn = Google::Protobuf::DescriptorPool.generated_pool.lookup("Animals.Unicorn").msgclass
|
82
|
+
# Use the parameter for the lookup call as the class_name for the codec config.
|
83
|
+
#
|
58
84
|
# If your class references other definitions: you only have to add the main class here.
|
59
85
|
config :class_name, :validate => :string, :required => true
|
60
86
|
|
61
|
-
#
|
62
|
-
#
|
87
|
+
# Relative path to the ruby file that contains class_name
|
88
|
+
#
|
89
|
+
# Relative path (from `protobuf_root_directory`) that holds the definition of the class specified in
|
90
|
+
# `class_name`.
|
91
|
+
#
|
92
|
+
# `class_file` and `include_path` cannot be used at the same time.
|
93
|
+
config :class_file, :validate => :string, :default => '', :required => false
|
94
|
+
|
95
|
+
# Absolute path to the directory that contains all compiled protobuf files.
|
96
|
+
#
|
97
|
+
# Absolute path to the root directory that contains all referenced/used dependencies
|
98
|
+
# of the main class (`class_name`) or any of its dependencies.
|
99
|
+
#
|
100
|
+
# For instance:
|
101
|
+
#
|
102
|
+
# pb3
|
103
|
+
# ├── header
|
104
|
+
# │ └── header_pb.rb
|
105
|
+
# ├── messageA_pb.rb
|
106
|
+
#
|
107
|
+
# In this case `messageA_pb.rb` has an embedded message from `header/header_pb.rb`.
|
108
|
+
# If `class_file` is set to `messageA_pb.rb`, and `class_name` to
|
109
|
+
# `MessageA`, `protobuf_root_directory` must be set to `/path/to/pb3`. Which includes
|
110
|
+
# both definitions.
|
111
|
+
config :protobuf_root_directory, :validate => :string, :required => false
|
112
|
+
|
113
|
+
# List of absolute pathes to files with protobuf definitions.
|
114
|
+
# When using more than one file, make sure to arrange the files in reverse order of dependency so that each class is loaded before it is
|
63
115
|
# refered to by another.
|
64
|
-
#
|
116
|
+
#
|
65
117
|
# Example: a class _Unicorn_ referencing another protobuf class _Wings_
|
66
118
|
# [source,ruby]
|
67
119
|
# module Animal
|
@@ -76,15 +128,16 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
76
128
|
# [source,ruby]
|
77
129
|
# include_path => ['/path/to/protobuf/definitions/Wings.pb.rb','/path/to/protobuf/definitions/Unicorn.pb.rb']
|
78
130
|
#
|
79
|
-
# When using the codec in an output plugin:
|
80
|
-
# * make sure to include all the desired fields in the protobuf definition, including timestamp.
|
131
|
+
# When using the codec in an output plugin:
|
132
|
+
# * make sure to include all the desired fields in the protobuf definition, including timestamp.
|
81
133
|
# Remove fields that are not part of the protobuf definition from the event by using the mutate filter.
|
82
|
-
# * the @ symbol is currently not supported in field names when loading the protobuf definitions for encoding. Make sure to call the timestamp field "timestamp"
|
134
|
+
# * the @ symbol is currently not supported in field names when loading the protobuf definitions for encoding. Make sure to call the timestamp field "timestamp"
|
83
135
|
# instead of "@timestamp" in the protobuf file. Logstash event fields will be stripped of the leading @ before conversion.
|
84
|
-
#
|
85
|
-
|
136
|
+
#
|
137
|
+
# `class_file` and `include_path` cannot be used at the same time.
|
138
|
+
config :include_path, :validate => :array, :default => [], :required => false
|
86
139
|
|
87
|
-
# Protocol buffer version switch. Defaults to version 2. Please note that the behaviour for enums varies between the versions.
|
140
|
+
# Protocol buffer version switch. Defaults to version 2. Please note that the behaviour for enums varies between the versions.
|
88
141
|
# For protobuf 2 you will get integer representations for enums, for protobuf 3 you'll get string representations due to a different converter library.
|
89
142
|
# Recommendation: use the translate plugin to restore previous behaviour when upgrading.
|
90
143
|
config :protobuf_version, :validate => [2,3], :default => 2, :required => true
|
@@ -92,18 +145,61 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
92
145
|
# To tolerate faulty messages that cannot be decoded, set this to false. Otherwise the pipeline will stop upon encountering a non decipherable message.
|
93
146
|
config :stop_on_error, :validate => :boolean, :default => false, :required => false
|
94
147
|
|
148
|
+
attr_reader :execution_context
|
149
|
+
|
150
|
+
# id of the pipeline whose events you want to read from.
|
151
|
+
def pipeline_id
|
152
|
+
respond_to?(:execution_context) && !execution_context.nil? ? execution_context.pipeline_id : "main"
|
153
|
+
end
|
154
|
+
|
95
155
|
def register
|
96
156
|
@metainfo_messageclasses = {}
|
97
157
|
@metainfo_enumclasses = {}
|
98
158
|
@metainfo_pb2_enumlist = []
|
99
|
-
|
100
|
-
if @
|
101
|
-
|
102
|
-
|
103
|
-
|
159
|
+
|
160
|
+
if @include_path.length > 0 and not class_file.strip.empty?
|
161
|
+
raise LogStash::ConfigurationError, "Cannot use `include_path` and `class_file` at the same time"
|
162
|
+
end
|
163
|
+
|
164
|
+
if @include_path.length == 0 and class_file.strip.empty?
|
165
|
+
raise LogStash::ConfigurationError, "Need to specify `include_path` or `class_file`"
|
166
|
+
end
|
167
|
+
|
168
|
+
should_register = Google::Protobuf::DescriptorPool.generated_pool.lookup(class_name).nil?
|
169
|
+
|
170
|
+
unless @protobuf_root_directory.nil? or @protobuf_root_directory.strip.empty?
|
171
|
+
if !$LOAD_PATH.include? @protobuf_root_directory and should_register
|
172
|
+
$LOAD_PATH.unshift(@protobuf_root_directory)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
@class_file = "#{@protobuf_root_directory}/#{@class_file}" unless (Pathname.new @class_file).absolute? or @class_file.empty?
|
177
|
+
|
178
|
+
# exclusive access while loading protobuf definitions
|
179
|
+
Google::Protobuf::DescriptorPool.with_lock.synchronize do
|
180
|
+
# load from `class_file`
|
181
|
+
load_protobuf_definition(@class_file) if should_register and !@class_file.empty?
|
182
|
+
# load from `include_path`
|
183
|
+
include_path.each { |path| load_protobuf_definition(path) } if include_path.length > 0 and should_register
|
184
|
+
|
185
|
+
if @protobuf_version == 3
|
186
|
+
@pb_builder = Google::Protobuf::DescriptorPool.generated_pool.lookup(class_name).msgclass
|
187
|
+
else
|
188
|
+
@pb_builder = pb2_create_instance(class_name)
|
189
|
+
end
|
104
190
|
end
|
105
191
|
end
|
106
192
|
|
193
|
+
# Pipelines using this plugin cannot be reloaded.
|
194
|
+
# https://github.com/elastic/logstash/pull/6499
|
195
|
+
#
|
196
|
+
# The DescriptorPool instance registers the protobuf classes (and
|
197
|
+
# dependencies) as global objects. This makes it very difficult to reload a
|
198
|
+
# pipeline, because `class_name` and all of its dependencies are already
|
199
|
+
# registered.
|
200
|
+
def reloadable?
|
201
|
+
return false
|
202
|
+
end
|
107
203
|
|
108
204
|
def decode(data)
|
109
205
|
if @protobuf_version == 3
|
@@ -111,7 +207,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
111
207
|
h = pb3_deep_to_hash(decoded)
|
112
208
|
else
|
113
209
|
decoded = @pb_builder.parse(data.to_s)
|
114
|
-
h = decoded.to_hash
|
210
|
+
h = decoded.to_hash
|
115
211
|
end
|
116
212
|
yield LogStash::Event.new(h) if block_given?
|
117
213
|
rescue => e
|
@@ -126,7 +222,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
126
222
|
if @protobuf_version == 3
|
127
223
|
protobytes = pb3_encode_wrapper(event)
|
128
224
|
else
|
129
|
-
protobytes = pb2_encode_wrapper(event)
|
225
|
+
protobytes = pb2_encode_wrapper(event)
|
130
226
|
end
|
131
227
|
@on_event.call(event, protobytes)
|
132
228
|
end # def encode
|
@@ -139,7 +235,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
139
235
|
result = Hash.new
|
140
236
|
input.to_hash.each {|key, value|
|
141
237
|
result[key] = pb3_deep_to_hash(value) # the key is required for the class lookup of enums.
|
142
|
-
}
|
238
|
+
}
|
143
239
|
when ::Array
|
144
240
|
result = []
|
145
241
|
input.each {|value|
|
@@ -174,32 +270,32 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
174
270
|
|
175
271
|
def pb3_encode(datahash, class_name)
|
176
272
|
if datahash.is_a?(::Hash)
|
177
|
-
|
178
|
-
|
273
|
+
|
274
|
+
|
179
275
|
|
180
276
|
# Preparation: the data cannot be encoded until certain criteria are met:
|
181
277
|
# 1) remove @ signs from keys.
|
182
278
|
# 2) convert timestamps and other objects to strings
|
183
279
|
datahash = datahash.inject({}){|x,(k,v)| x[k.gsub(/@/,'').to_sym] = (should_convert_to_string?(v) ? v.to_s : v); x}
|
184
|
-
|
280
|
+
|
185
281
|
# Check if any of the fields in this hash are protobuf classes and if so, create a builder for them.
|
186
282
|
meta = @metainfo_messageclasses[class_name]
|
187
283
|
if meta
|
188
284
|
meta.map do | (field_name,class_name) |
|
189
285
|
key = field_name.to_sym
|
190
286
|
if datahash.include?(key)
|
191
|
-
original_value = datahash[key]
|
192
|
-
datahash[key] =
|
287
|
+
original_value = datahash[key]
|
288
|
+
datahash[key] =
|
193
289
|
if original_value.is_a?(::Array)
|
194
290
|
# make this field an array/list of protobuf objects
|
195
291
|
# value is a list of hashed complex objects, each of which needs to be protobuffed and
|
196
292
|
# put back into the list.
|
197
|
-
original_value.map { |x| pb3_encode(x, class_name) }
|
293
|
+
original_value.map { |x| pb3_encode(x, class_name) }
|
198
294
|
original_value
|
199
|
-
else
|
295
|
+
else
|
200
296
|
r = pb3_encode(original_value, class_name)
|
201
297
|
builder = Google::Protobuf::DescriptorPool.generated_pool.lookup(class_name).msgclass
|
202
|
-
builder.new(r)
|
298
|
+
builder.new(r)
|
203
299
|
end # if is array
|
204
300
|
end # if datahash_include
|
205
301
|
end # do
|
@@ -214,7 +310,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
214
310
|
original_value = datahash[key]
|
215
311
|
datahash[key] = case original_value
|
216
312
|
when ::Array
|
217
|
-
original_value.map { |x| pb3_encode(x, class_name) }
|
313
|
+
original_value.map { |x| pb3_encode(x, class_name) }
|
218
314
|
original_value
|
219
315
|
when Fixnum
|
220
316
|
original_value # integers will be automatically converted into enum
|
@@ -229,8 +325,8 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
229
325
|
# rescue => e
|
230
326
|
# @logger.debug("Encoding error 3: could not translate #{original_value} into enum. #{e}")
|
231
327
|
# raise e
|
232
|
-
# end
|
233
|
-
end
|
328
|
+
# end
|
329
|
+
end
|
234
330
|
end # if datahash_include
|
235
331
|
end # do
|
236
332
|
end # if meta
|
@@ -252,27 +348,27 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
252
348
|
|
253
349
|
|
254
350
|
|
255
|
-
def pb2_encode(datahash, class_name)
|
351
|
+
def pb2_encode(datahash, class_name)
|
256
352
|
if datahash.is_a?(::Hash)
|
257
353
|
# Preparation: the data cannot be encoded until certain criteria are met:
|
258
354
|
# 1) remove @ signs from keys.
|
259
355
|
# 2) convert timestamps and other objects to strings
|
260
356
|
datahash = ::Hash[datahash.map{|(k,v)| [k.to_s.dup.gsub(/@/,''), (should_convert_to_string?(v) ? v.to_s : v)] }]
|
261
|
-
|
357
|
+
|
262
358
|
# Check if any of the fields in this hash are protobuf classes and if so, create a builder for them.
|
263
359
|
meta = @metainfo_messageclasses[class_name]
|
264
360
|
if meta
|
265
361
|
meta.map do | (k,c) |
|
266
362
|
if datahash.include?(k)
|
267
|
-
original_value = datahash[k]
|
268
|
-
datahash[k] =
|
363
|
+
original_value = datahash[k]
|
364
|
+
datahash[k] =
|
269
365
|
if original_value.is_a?(::Array)
|
270
366
|
# make this field an array/list of protobuf objects
|
271
367
|
# value is a list of hashed complex objects, each of which needs to be protobuffed and
|
272
368
|
# put back into the list.
|
273
|
-
original_value.map { |x| pb2_encode(x, c) }
|
369
|
+
original_value.map { |x| pb2_encode(x, c) }
|
274
370
|
original_value
|
275
|
-
else
|
371
|
+
else
|
276
372
|
proto_obj = pb2_create_instance(c)
|
277
373
|
proto_obj.new(pb2_encode(original_value, c)) # this line is reached in the colourtest for an enum. Enums should not be instantiated. Should enums even be in the messageclasses? I dont think so! TODO bug
|
278
374
|
end # if is array
|
@@ -288,7 +384,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
288
384
|
!(v.is_a?(Fixnum) || v.is_a?(::Hash) || v.is_a?(::Array) || [true, false].include?(v))
|
289
385
|
end
|
290
386
|
|
291
|
-
|
387
|
+
|
292
388
|
def pb2_create_instance(name)
|
293
389
|
@logger.debug("Creating instance of " + name)
|
294
390
|
name.split('::').inject(Object) { |n,c| n.const_get c }
|
@@ -302,7 +398,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
302
398
|
type = ""
|
303
399
|
field_name = ""
|
304
400
|
File.readlines(filename).each do |line|
|
305
|
-
if ! (line =~ regex_class_name).nil?
|
401
|
+
if ! (line =~ regex_class_name).nil?
|
306
402
|
class_name = $1
|
307
403
|
@metainfo_messageclasses[class_name] = {}
|
308
404
|
@metainfo_enumclasses[class_name] = {}
|
@@ -326,7 +422,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
326
422
|
@logger.warn("Error 3: unable to read pb definition from file " + filename+ ". Reason: #{e.inspect}. Last settings were: class #{class_name} field #{field_name} type #{type}. Backtrace: " + e.backtrace.inspect.to_s)
|
327
423
|
raise e
|
328
424
|
end
|
329
|
-
|
425
|
+
|
330
426
|
|
331
427
|
|
332
428
|
def pb2_metadata_analyis(filename)
|
@@ -359,13 +455,13 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
359
455
|
if type =~ /::/
|
360
456
|
clean_type = type.gsub(/^:/,"")
|
361
457
|
e = @metainfo_pb2_enumlist.include? clean_type.downcase
|
362
|
-
|
458
|
+
|
363
459
|
if e
|
364
460
|
if not @metainfo_enumclasses.key? class_name
|
365
461
|
@metainfo_enumclasses[class_name] = {}
|
366
462
|
end
|
367
463
|
@metainfo_enumclasses[class_name][field_name] = clean_type
|
368
|
-
else
|
464
|
+
else
|
369
465
|
if not @metainfo_messageclasses.key? class_name
|
370
466
|
@metainfo_messageclasses[class_name] = {}
|
371
467
|
end
|
@@ -381,32 +477,32 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
|
|
381
477
|
rescue LoadError => e
|
382
478
|
raise ArgumentError.new("Could not load file: " + filename + ". Please try to use absolute pathes. Current working dir: " + Dir.pwd + ", loadpath: " + $LOAD_PATH.join(" "))
|
383
479
|
rescue => e
|
384
|
-
|
480
|
+
|
385
481
|
@logger.warn("Error 3: unable to read pb definition from file " + filename+ ". Reason: #{e.inspect}. Last settings were: class #{class_name} field #{field_name} type #{type}. Backtrace: " + e.backtrace.inspect.to_s)
|
386
482
|
raise e
|
387
483
|
end
|
388
|
-
|
484
|
+
|
389
485
|
|
390
486
|
def load_protobuf_definition(filename)
|
391
487
|
if filename.end_with? ('.rb')
|
488
|
+
# Add to the loading path of the protobuf definitions
|
392
489
|
if (Pathname.new filename).absolute?
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
490
|
+
begin
|
491
|
+
require filename
|
492
|
+
rescue Exception => e
|
493
|
+
@logger.error("Unable to load file: #{filename}. Reason: #{e.inspect}")
|
494
|
+
end
|
398
495
|
end
|
399
|
-
|
496
|
+
|
400
497
|
if @protobuf_version == 3
|
401
498
|
pb3_metadata_analyis(filename)
|
402
499
|
else
|
403
500
|
pb2_metadata_analyis(filename)
|
404
501
|
end
|
405
|
-
|
406
|
-
else
|
502
|
+
|
503
|
+
else
|
407
504
|
@logger.warn("Not a ruby file: " + filename)
|
408
505
|
end
|
409
506
|
end
|
410
507
|
|
411
|
-
|
412
508
|
end # class LogStash::Codecs::Protobuf
|