logstash-codec-protobuf 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +4 -0
- data/CONTRIBUTORS +17 -0
- data/DEVELOPER.md +2 -0
- data/Gemfile +2 -0
- data/LICENSE +13 -0
- data/NOTICE.TXT +5 -0
- data/README.md +65 -0
- data/lib/logstash/codecs/protobuf.rb +111 -0
- data/logstash-codec-protobuf.gemspec +25 -0
- data/spec/codecs/protobuf_spec.rb +30 -0
- data/spec/helpers/unicorn.pb.rb +18 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -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
|
data/CHANGELOG.md
ADDED
data/CONTRIBUTORS
ADDED
@@ -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.
|
data/DEVELOPER.md
ADDED
data/Gemfile
ADDED
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.
|
data/NOTICE.TXT
ADDED
data/README.md
ADDED
@@ -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
|