logstash-codec-protobuf 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 43ef1232f802b173bf7fee33f894c31145e5032e
4
- data.tar.gz: f0d955aeee52c1bbb6f72abe016603c6eac8994e
3
+ metadata.gz: 826cf27e43ea66cbabc39b226b229d179fd275d6
4
+ data.tar.gz: 0e2888f0622344cc8dddf20b03b9c89974d0613f
5
5
  SHA512:
6
- metadata.gz: fb9a3a3b646935acd74d986e3defd67a79ccb14bad91bbd9abe4240bf938ef001a709a8ec05efa243410c25d08e3577a1c3a53e1614bccda55d0a6f07837e719
7
- data.tar.gz: ad7d0690b3169ab22623db7b5e8dfd5a17d2cb1e082d54c39da86fef8239dd3576a1d1ed5894dcd27f3fe332f1538d8a71a960cb41a7ee85ab7f5f05c32dc4ef
6
+ metadata.gz: 8f49b8820a8a70a686a42c7561621946a426e74f839f18476c84a1e59dc06e2b71cbb2045c8281fb36d6cd432ee22ea896900dbbacf01686b46530b8008a8726
7
+ data.tar.gz: a162df9db2fed47938ef1cdd2901c28230a6f127351f464288582561b2d0fd5baef1fa59da91af503e2cd1b36e598932af827f0492e8becd5b9e122c19494828
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
+ ## 1.0.1
2
+ - Speed improvement, better exception handling and code refactoring
3
+
1
4
  ## 1.0.0
2
5
  - Update to v5.0 API
3
6
 
4
- ## 0.1.2
5
- - First version of this plugin
7
+ ## 0.1.2
8
+ - First version of this plugin
data/Gemfile CHANGED
@@ -1,3 +1,11 @@
1
1
  source 'https://rubygems.org'
2
- gem 'logstash-docgen', :path => "/Users/suyog/ws/elastic/logstash/tools/logstash-docgen"
3
- gemspec
2
+
3
+ gemspec
4
+
5
+ logstash_path = ENV["LOGSTASH_PATH"] || "../../logstash"
6
+ use_logstash_source = ENV["LOGSTASH_SOURCE"] && ENV["LOGSTASH_SOURCE"].to_s == "1"
7
+
8
+ if Dir.exist?(logstash_path) && use_logstash_source
9
+ gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
10
+ gem 'logstash-core-plugin-api', :path => "#{logstash_path}/logstash-core-plugin-api"
11
+ end
@@ -0,0 +1,106 @@
1
+ :plugin: protobuf
2
+ :type: codec
3
+
4
+ ///////////////////////////////////////////
5
+ START - GENERATED VARIABLES, DO NOT EDIT!
6
+ ///////////////////////////////////////////
7
+ :version: %VERSION%
8
+ :release_date: %RELEASE_DATE%
9
+ :changelog_url: %CHANGELOG_URL%
10
+ :include_path: ../../../../logstash/docs/include
11
+ ///////////////////////////////////////////
12
+ END - GENERATED VARIABLES, DO NOT EDIT!
13
+ ///////////////////////////////////////////
14
+
15
+ [id="plugins-{type}-{plugin}"]
16
+
17
+ === Protobuf codec plugin
18
+
19
+ include::{include_path}/plugin_header.asciidoc[]
20
+
21
+ ==== Description
22
+
23
+ This codec converts protobuf encoded messages into logstash events and vice versa.
24
+
25
+ Requires the protobuf definitions as ruby files. You can create those using the [ruby-protoc compiler](https://github.com/codekitchen/ruby-protocol-buffers).
26
+
27
+ The following shows a usage example for decoding events from a kafka stream:
28
+ [source,ruby]
29
+ kafka
30
+ {
31
+ zk_connect => "127.0.0.1"
32
+ topic_id => "your_topic_goes_here"
33
+ codec => protobuf
34
+ {
35
+ class_name => "Animal::Unicorn"
36
+ include_path => ['/path/to/protobuf/definitions/UnicornProtobuf.pb.rb']
37
+ }
38
+ }
39
+
40
+
41
+ [id="plugins-{type}s-{plugin}-options"]
42
+ ==== Protobuf Codec Configuration Options
43
+
44
+ [cols="<,<,<",options="header",]
45
+ |=======================================================================
46
+ |Setting |Input type|Required
47
+ | <<plugins-{type}s-{plugin}-class_name>> |<<string,string>>|Yes
48
+ | <<plugins-{type}s-{plugin}-include_path>> |<<array,array>>|Yes
49
+ |=======================================================================
50
+
51
+ &nbsp;
52
+
53
+ [id="plugins-{type}s-{plugin}-class_name"]
54
+ ===== `class_name`
55
+
56
+ * This is a required setting.
57
+ * Value type is <<string,string>>
58
+ * There is no default value for this setting.
59
+
60
+ Name of the class to decode.
61
+ If your protobuf definition contains modules, prepend them to the class name with double colons like so:
62
+ [source,ruby]
63
+ class_name => "Foods::Dairy::Cheese"
64
+
65
+ This corresponds to a protobuf definition starting as follows:
66
+ [source,ruby]
67
+ module Foods
68
+ module Dairy
69
+ class Cheese
70
+ # here are your field definitions.
71
+
72
+ If your class references other definitions: you only have to add the main class here.
73
+
74
+ [id="plugins-{type}s-{plugin}-include_path"]
75
+ ===== `include_path`
76
+
77
+ * This is a required setting.
78
+ * Value type is <<array,array>>
79
+ * There is no default value for this setting.
80
+
81
+ List of absolute pathes to files with protobuf definitions.
82
+ 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
83
+ refered to by another.
84
+
85
+ Example: a class _Cheese_ referencing another protobuf class _Milk_
86
+ [source,ruby]
87
+ module Foods
88
+ module Dairy
89
+ class Cheese
90
+ set_fully_qualified_name "Foods.Dairy.Cheese"
91
+ optional ::Foods::Cheese::Milk, :milk, 1
92
+ optional :int64, :unique_id, 2
93
+ # here be more field definitions
94
+
95
+ would be configured as
96
+ [source,ruby]
97
+ include_path => ['/path/to/protobuf/definitions/Milk.pb.rb','/path/to/protobuf/definitions/Cheese.pb.rb']
98
+
99
+ When using the codec in an output plugin:
100
+ * make sure to include all the desired fields in the protobuf definition, including timestamp.
101
+ Remove fields that are not part of the protobuf definition from the event by using the mutate filter.
102
+ * the @ symbol is currently not supported in field names when loading the protobuf definitions for encoding. Make sure to call the timestamp field "timestamp"
103
+ instead of "@timestamp" in the protobuf file. Logstash event fields will be stripped of the leading @ before conversion.
104
+
105
+
106
+
@@ -66,32 +66,23 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
66
66
  config :include_path, :validate => :array, :required => true
67
67
 
68
68
 
69
-
70
-
71
-
72
69
  def register
73
70
  @pb_metainfo = {}
74
71
  include_path.each { |path| require_pb_path(path) }
75
72
  @obj = create_object_from_name(class_name)
76
73
  @logger.debug("Protobuf files successfully loaded.")
77
-
78
74
  end
79
75
 
80
- def decode(data)
81
- decoded = @obj.parse(data.to_s)
82
- results = keys2strings(decoded.to_hash)
83
- yield LogStash::Event.new(results) if block_given?
84
- end # def decode
85
76
 
86
- def keys2strings(data)
87
- if data.is_a?(::Hash)
88
- new_hash = Hash.new
89
- data.each{|k,v| new_hash[k.to_s] = keys2strings(v)}
90
- new_hash
91
- else
92
- data
77
+ def decode(data)
78
+ begin
79
+ decoded = @obj.parse(data.to_s)
80
+ yield LogStash::Event.new(decoded.to_hash) if block_given?
81
+ rescue => e
82
+ @logger.warn("Couldn't decode protobuf: #{e.inspect}.")
83
+ # raise e
93
84
  end
94
- end
85
+ end # def decode
95
86
 
96
87
 
97
88
  def encode(event)
@@ -99,68 +90,53 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
99
90
  @on_event.call(event, protobytes)
100
91
  end # def encode
101
92
 
93
+
102
94
  private
103
- def generate_protobuf(event)
104
- meth = self.method("encoder_strategy_1")
105
- data = meth.call(event, @class_name)
95
+ def generate_protobuf(event)
106
96
  begin
97
+ data = _encode(event, @class_name)
107
98
  msg = @obj.new(data)
108
99
  msg.serialize_to_string
109
100
  rescue NoMethodError
110
101
  @logger.debug("error 2: NoMethodError. Maybe mismatching protobuf definition. Required fields are: " + event.to_hash.keys.join(", "))
102
+ rescue => e
103
+ @logger.debug("Couldn't generate protobuf: ${e}")
111
104
  end
112
105
  end
113
106
 
114
- def encoder_strategy_1(event, class_name)
115
- _encoder_strategy_1(event.to_hash, class_name)
116
107
 
117
- end
118
-
119
- def _encoder_strategy_1(datahash, class_name)
120
- fields = clean_hash_keys(datahash)
121
- fields = flatten_hash_values(fields) # TODO we could merge this and the above method back into one to save one iteration, but how are we going to name it?
108
+ def _encode(datahash, class_name)
109
+ fields = prepare_for_encoding(datahash)
122
110
  meta = get_complex_types(class_name) # returns a hash with member names and their protobuf class names
123
111
  meta.map do | (k,typeinfo) |
124
112
  if fields.include?(k)
125
113
  original_value = fields[k]
126
114
  proto_obj = create_object_from_name(typeinfo)
127
115
  fields[k] =
128
- if original_value.is_a?(::Array)
129
- ecs1_list_helper(original_value, proto_obj, typeinfo)
130
-
116
+ if original_value.is_a?(::Array)
117
+ # make this field an array/list of protobuf objects
118
+ # value is a list of hashed complex objects, each of which needs to be protobuffed and
119
+ # put back into the list.
120
+ original_value.map { |x| _encode(x, typeinfo) }
121
+ original_value
131
122
  else
132
- recursive_fix = _encoder_strategy_1(original_value, class_name)
123
+ recursive_fix = _encode(original_value, class_name)
133
124
  proto_obj.new(recursive_fix)
134
125
  end # if is array
135
126
  end
136
-
137
- end
138
-
127
+ end
139
128
  fields
140
129
  end
141
130
 
142
- def ecs1_list_helper(value, proto_obj, class_name)
143
- # make this field an array/list of protobuf objects
144
- # value is a list of hashed complex objects, each of which needs to be protobuffed and
145
- # put back into the list.
146
- next unless value.is_a?(::Array)
147
- value.map { |x| _encoder_strategy_1(x, class_name) }
148
- value
149
- end
150
131
 
151
- def flatten_hash_values(datahash)
132
+ def prepare_for_encoding(datahash)
133
+ # the data cannot be encoded until certain criteria are met:
134
+ # 1) remove @ signs from keys
152
135
  # 2) convert timestamps and other objects to strings
153
- next unless datahash.is_a?(::Hash)
154
-
155
- ::Hash[datahash.map{|(k,v)| [k, (convert_to_string?(v) ? v.to_s : v)] }]
136
+ next unless datahash.is_a?(::Hash)
137
+ ::Hash[datahash.map{|(k,v)| [remove_atchar(k.to_s), (convert_to_string?(v) ? v.to_s : v)] }]
156
138
  end
157
139
 
158
- def clean_hash_keys(datahash)
159
- # 1) remove @ signs from keys
160
- next unless datahash.is_a?(::Hash)
161
-
162
- ::Hash[datahash.map{|(k,v)| [remove_atchar(k.to_s), v] }]
163
- end #clean_hash_keys
164
140
 
165
141
  def convert_to_string?(v)
166
142
  !(v.is_a?(Fixnum) || v.is_a?(::Hash) || v.is_a?(::Array) || [true, false].include?(v))
@@ -171,7 +147,7 @@ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
171
147
  key.dup.gsub(/@/,'')
172
148
  end
173
149
 
174
- private
150
+
175
151
  def create_object_from_name(name)
176
152
  begin
177
153
  @logger.debug("Creating instance of " + name)
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-codec-protobuf'
4
- s.version = '1.0.0'
4
+ s.version = '1.0.2'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "This codec may be used to decode (via inputs) and encode (via outputs) protobuf messages"
7
7
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.require_paths = ["lib"]
11
11
 
12
12
  # Files
13
- s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
13
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
14
14
 
15
15
  # Tests
16
16
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-codec-protobuf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inga Feick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-04 00:00:00.000000000 Z
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -71,6 +71,7 @@ files:
71
71
  - LICENSE
72
72
  - NOTICE.TXT
73
73
  - README.md
74
+ - docs/index.asciidoc
74
75
  - lib/logstash/codecs/protobuf.rb
75
76
  - logstash-codec-protobuf.gemspec
76
77
  - spec/codecs/protobuf_spec.rb