logstash-codec-protobuf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae5fff64bbdc72cfc6f1dbbeecd0857481bd1a93
4
+ data.tar.gz: 5ff0987575c066dd83443a3a4fe1eefc9149f9ea
5
+ SHA512:
6
+ metadata.gz: 8875e1c022bc8a7155469838c312a0076a296c99d506bb37f18cbe4ea77b080e034b46a76ec6e0084f07f60e5aad88feafe3157b72408c3213746d1a39dac79c
7
+ data.tar.gz: e3eb525c75ed899a003767855ed03201dcab2338f1fd33d8a6328045be4b8dad776acd422375155ddc7455ef6a3ab8cb710bc3211b1c483def8126bb25545040
@@ -0,0 +1,4 @@
1
+ * 1.1.0
2
+ - Handle scalar types (string/number) and be more defensive about crashable errors
3
+ * 1.0.1
4
+ - Handle JSON arrays at source root by emitting multiple events
@@ -0,0 +1,17 @@
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash along its way.
3
+
4
+ Contributors:
5
+ * Colin Surprenant (colinsurprenant)
6
+ * Jordan Sissel (jordansissel)
7
+ * João Duarte (jsvd)
8
+ * Kurt Hurtado (kurtado)
9
+ * Nick Ethier (nickethier)
10
+ * Pier-Hugues Pellerin (ph)
11
+ * Richard Pijnenburg (electrical)
12
+ * Tal Levy (talevy)
13
+
14
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
15
+ Logstash, and you aren't on the list above and want to be, please let us know
16
+ and we'll make sure you're here. Contributions from folks like you are what make
17
+ open source awesome.
@@ -0,0 +1,2 @@
1
+ # logstash-codec-example
2
+ Example codec plugin. This should help bootstrap your effort to write your own codec plugin!
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012–2015 Elasticsearch <http://www.elastic.co>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,5 @@
1
+ Elasticsearch
2
+ Copyright 2012-2015 Elasticsearch
3
+
4
+ This product includes software developed by The Apache Software
5
+ Foundation (http://www.apache.org/).
@@ -0,0 +1,65 @@
1
+ # Logstash protobuf codec
2
+
3
+ This is a codec plugin for [Logstash](https://github.com/elastic/logstash) to parse protobuf messages.
4
+
5
+ # Prerequisites
6
+
7
+ * prepare your ruby versions of the protobuf definitions, for example using the ruby-protoc compiler from https://github.com/codekitchen/ruby-protocol-buffers
8
+ * download the logstash-codec-protobuf-$VERSION.gem to your computer.
9
+ * Install the plugin. From within your logstash directory, do
10
+ bin/plugin install /path/to/logstash-codec-protobuf-$VERSION.gem
11
+ * use the codec in your logstash config file. See details below.
12
+
13
+ # Usage
14
+
15
+ Use this as a codec in any logstash input. Just provide the name of the class that your incoming objects will be encoded in, and specify the path to the compiled definition.
16
+ Here's an example for a kafka input:
17
+
18
+ kafka
19
+ {
20
+ zk_connect => "127.0.0.1"
21
+ topic_id => "unicorns_protobuffed"
22
+ codec => protobuf
23
+ {
24
+ class_name => "Unicorn"
25
+ include_path => ['/my/path/to/compiled/protobuf/definitions/UnicornProtobuf.pb.rb']
26
+ }
27
+ }
28
+
29
+ ### Example with referenced definitions
30
+
31
+ Imagine you have the following protobuf relationship: class Cheese lives in namespace Foods::Dairy and uses another class Milk.
32
+
33
+ module Foods
34
+ module Dairy
35
+ class Cheese
36
+ set_fully_qualified_name "Foods.Dairy.Cheese"
37
+ optional ::Foods::Cheese::Milk, :milk, 1
38
+ optional :int64, :unique_id, 2
39
+ # here be more field definitions
40
+
41
+ Make sure to put the referenced Milk class first in the include_path:
42
+
43
+ include_path => ['/path/to/protobuf/definitions/Milk.pb.rb','/path/to/protobuf/definitions/Cheese.pb.rb']
44
+
45
+ Set the class name to the parent class:
46
+
47
+ class_name => "Foods::Dairy::Cheese"
48
+
49
+ # Configuration
50
+
51
+ include_path (required): an array of strings with filenames or directory names where logstash can find your protobuf definitions. Please provide absolute paths. For directories it will only try to import files ending on .rb
52
+
53
+ class_name (required): the name of the protobuf class that is to be decoded.
54
+
55
+
56
+ # Troubleshooting
57
+
58
+ ## "uninitialized constant SOME_CLASS_NAME"
59
+
60
+ If you include more than one definition class, consider the order of inclusion. This is especially relevant if you include whole directories. A definition might refer to another definition that is not loaded yet. In this case, please specify the files in the include_path variable in reverse order of reference. See 'Example with referenced definitions' above.
61
+
62
+
63
+ # Roapmap
64
+
65
+ Currently the plugin supports the decode functionality only. Maybe we'll add the encoding part also.
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+ require "logstash/codecs/base"
3
+ require "logstash/util/charset"
4
+ require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffers
5
+
6
+ class LogStash::Codecs::Protobuf < LogStash::Codecs::Base
7
+ config_name "protobuf"
8
+
9
+ # Required: list of strings containing directories or files with protobuf definitions
10
+ config :include_path, :validate => :array, :required => true
11
+
12
+ # Name of the class to decode
13
+ config :class_name, :validate => :string, :required => true
14
+
15
+ # remove 'set_fields' field
16
+ config :remove_set_fields, :validate => :boolean, :default => true # TODO add documentation
17
+
18
+
19
+ public
20
+ def register
21
+ @include_path.each{|path| require_pb_path(path) }
22
+ @obj = create_object_from_name(@class_name)
23
+
24
+ end
25
+
26
+
27
+ private
28
+ def create_object_from_name(name)
29
+ begin
30
+ c = name.split("::").inject(Object) { |n,c| n.const_get c }
31
+ return c
32
+ end
33
+ end
34
+
35
+ private
36
+ def debug(message)
37
+ begin
38
+ if @debug
39
+ @logger.debug(message)
40
+ end
41
+ end
42
+ end
43
+
44
+ private
45
+ def require_pb_path(dir_or_file)
46
+ f = dir_or_file.end_with? (".rb")
47
+ begin
48
+ if f
49
+ require dir_or_file
50
+ else
51
+ Dir[ dir_or_file + "/*.rb"].each { |file|
52
+ require file
53
+ }
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+ def extract_variables(decoded_object)
60
+ begin
61
+ result_hash = {}
62
+ if decoded_object.nil?
63
+ return result_hash
64
+ end
65
+ decoded_object.instance_variables.map do |ivar|
66
+ varname = ivar.to_s
67
+ key = varname.gsub("@","")
68
+ value = decoded_object.instance_variable_get("#{ivar}")
69
+ recurse = value.is_a? (::ProtocolBuffers::Message) # object is not a primitive scalar
70
+ is_iterable |= value.is_a? Enumerable # value.respond_to? :each # object is an array
71
+ if recurse
72
+ result_hash[key] = extract_variables(value)
73
+ elsif is_iterable
74
+ tmp = []
75
+ value.each do | nested |
76
+ tmp.push(nested)
77
+ end
78
+ result_hash[key] = tmp
79
+ else
80
+ result_hash[key] = value
81
+ end
82
+ end
83
+ if remove_set_fields
84
+ return result_hash.except("set_fields") # todo try to do this before the object is handed to this method
85
+ else
86
+ return result_hash
87
+ end
88
+ end
89
+ end
90
+
91
+
92
+
93
+
94
+
95
+ public
96
+ def decode(data)
97
+ decoded = @obj.parse(data.to_s)
98
+ results = extract_variables(decoded)
99
+ event = LogStash::Event.new(results)
100
+ yield event
101
+
102
+ end # def decode
103
+
104
+ public
105
+ def encode(event)
106
+ raise "Encoder function not implemented yet for protobuf codec. Sorry!"
107
+ # @on_event.call(event, event.to_s)
108
+ # TODO integrate
109
+ end # def encode
110
+
111
+ end # class LogStash::Codecs::Protobuf
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |s|
2
+
3
+ s.name = 'logstash-codec-protobuf'
4
+ s.version = '0.1.0'
5
+ s.licenses = ['Apache License (2.0)']
6
+ s.summary = "This codec may be used to decode (via inputs) and encode (via outputs) protobuf messages"
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"
8
+ s.authors = ["trivago"]
9
+ s.require_paths = ["lib"]
10
+
11
+ # Files
12
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
13
+
14
+ # Tests
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+
17
+ # Special flag to let us know this is actually a logstash plugin
18
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "codec" }
19
+
20
+ # Gem dependencies
21
+ s.add_runtime_dependency 'logstash-core', '>= 1.4.0', '< 3.0.0'
22
+ s.add_runtime_dependency 'ruby-protocol-buffers' # used by the compiled version of our protobuf definition.
23
+ s.add_development_dependency 'logstash-devutils'
24
+ end
25
+
@@ -0,0 +1,30 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/codecs/protobuf"
3
+ require "logstash/event"
4
+ require 'protocol_buffers' # https://github.com/codekitchen/ruby-protocol-buffers
5
+ require "insist"
6
+
7
+ describe LogStash::Codecs::Protobuf do
8
+
9
+ context "#decode" do
10
+
11
+ let(:plugin) { LogStash::Codecs::Protobuf.new("class_name" => "Animal::Unicorn", "include_path" => ['spec/helpers/unicorn.pb.rb']) }
12
+ before do
13
+ plugin.register
14
+ end
15
+
16
+ it "should return an event from protobuf encoded data" do
17
+
18
+ data = {:colour => 'rainbow', :horn_length => 18, :last_seen => 1420081471}
19
+ unicorn = Animal::Unicorn.new(data)
20
+
21
+ plugin.decode(unicorn.serialize_to_string) do |event|
22
+ insist { event.is_a? LogStash::Event }
23
+ insist { event["colour"] } == data[:colour]
24
+ insist { event["horn_length"] } == data[:horn_length]
25
+ insist { event["last_seen"] } == data[:last_seen]
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+
4
+ require 'protocol_buffers'
5
+
6
+ module Animal
7
+ # forward declarations
8
+ class Unicorn < ::ProtocolBuffers::Message; end
9
+
10
+ class Unicorn < ::ProtocolBuffers::Message
11
+ set_fully_qualified_name "animal.Unicorn"
12
+
13
+ optional :string, :colour, 1
14
+ optional :int32, :horn_length, 2
15
+ optional :int32, :last_seen, 3
16
+ end
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-codec-protobuf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - trivago
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash-core
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.0
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: 3.0.0
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: 1.4.0
28
+ - - <
29
+ - !ruby/object:Gem::Version
30
+ version: 3.0.0
31
+ prerelease: false
32
+ type: :runtime
33
+ - !ruby/object:Gem::Dependency
34
+ name: ruby-protocol-buffers
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ prerelease: false
46
+ type: :runtime
47
+ - !ruby/object:Gem::Dependency
48
+ name: logstash-devutils
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ prerelease: false
60
+ type: :development
61
+ 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
62
+ email:
63
+ executables: []
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - CHANGELOG.md
68
+ - CONTRIBUTORS
69
+ - DEVELOPER.md
70
+ - Gemfile
71
+ - LICENSE
72
+ - NOTICE.TXT
73
+ - README.md
74
+ - lib/logstash/codecs/protobuf.rb
75
+ - logstash-codec-protobuf.gemspec
76
+ - spec/codecs/protobuf_spec.rb
77
+ - spec/helpers/unicorn.pb.rb
78
+ homepage:
79
+ licenses:
80
+ - Apache License (2.0)
81
+ metadata:
82
+ logstash_plugin: 'true'
83
+ logstash_group: codec
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.4.5
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: This codec may be used to decode (via inputs) and encode (via outputs) protobuf messages
104
+ test_files:
105
+ - spec/codecs/protobuf_spec.rb
106
+ - spec/helpers/unicorn.pb.rb