logstash-codec-protobuf 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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