logstash-codec-mtrraw 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d88e82a64b32f90104a3e416cec993d4a72335b4
4
+ data.tar.gz: 99542d614c33bedbe63b114c1163f7bdd2ae1d1f
5
+ SHA512:
6
+ metadata.gz: 21b9f69b4dcc2dc982b2ea9b4fa30a684992776294210c5ed5bbb7f82a6484507dc05342db5e50cb960ab5db2c0347ab9c59973106e559e7959cb46e5f8b3cfc
7
+ data.tar.gz: cb1badb8fc189389e7a68552de80e970477107cbad5a3bec6635738b31a60f98cf52552ba356479dbccf0882ce563caada82b07305896a4b5efe0b6f9a0ef7f3
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ - Plugin created with the logstash plugin generator
data/CONTRIBUTORS ADDED
@@ -0,0 +1,10 @@
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
+ * svdasein - daveparker01@gmail.com
6
+
7
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
8
+ Logstash, and you aren't on the list above and want to be, please let us know
9
+ and we'll make sure you're here. Contributions from folks like you are what make
10
+ open source awesome.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Licensed under the Apache License, Version 2.0 (the "License");
2
+ you may not use this file except in compliance with the License.
3
+ You may obtain a copy of the License at
4
+
5
+ http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software
8
+ distributed under the License is distributed on an "AS IS" BASIS,
9
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ See the License for the specific language governing permissions and
11
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Logstash Plugin
2
+
3
+ This is a plugin for [Logstash](https://github.com/elastic/logstash).
4
+
5
+ It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
6
+
7
+ ## Documentation
8
+
9
+ The logstash mtrraw codec wraps together a bunch of logic that makes it easy to use mtr --raw output in your ELK infrastructure.
10
+
11
+ ### Installation
12
+
13
+ ```
14
+ bin/logstash-plugin install logstash-codec-mtrraw
15
+ ```
16
+ ### Configuration
17
+
18
+ ```
19
+ input {
20
+ tcp {
21
+ port => 4327
22
+ codec => "mtrraw"
23
+ }
24
+ }
25
+ ```
26
+
27
+ ### Sending MTR trace data
28
+ Feed it with something that's functionally equivalent to this:
29
+
30
+ ```
31
+ while true ; do (echo "s 0 GOOGDNS 1";mtr --raw --no-dns -c 1 8.8.8.8 ) | awk '{printf $0";"}' | nc localhost 4327 ; done
32
+ ```
33
+
34
+ Put the above in a script, make the script executable, and run it in the background. It'll continuously feed mtr trace data to
35
+ the codec.
36
+
37
+ Explanation:
38
+
39
+ There's an infinite loop around the traces without a pause. A pause isn't really needed to keep load down as the trace is i/o bound
40
+ on the network all the time anyway.
41
+
42
+ The `(echo ...;mtr)` construct allows us to overload the frontend of the trace a little bit and have the whole thing treated as a single
43
+ stream. The front of the trace has a line that looks like this:
44
+
45
+ ```
46
+ s 0 <targetname> <pingcount>
47
+
48
+ ```
49
+
50
+ * <targetname> is whatever name you want to give the trace
51
+ * <pingcount> is the number of pings you're going to be doing to each node in the trace. This must match the -c parameter to mtr (see below).
52
+
53
+ Modify the echo statement accordingly.
54
+
55
+ The MTR execution part requires the following:
56
+
57
+ * You must use the `--raw` output format
58
+ * You must specify the `-c` (count) option to state how many pings you want to do. This number must also be in the start line (above)
59
+
60
+ Any other options are optional :)
61
+
62
+ The `| awk '{printf $0";"}` construct takes all the --raw output lines and puts them together in one line delimited by semicolons. This
63
+ in turn is sent to your logstash instance at the port you defined when you configured it using a tcp connection via the netcat (nc) command.
64
+
65
+ ### What you'll get
66
+
67
+ The codec generates two kinds of documents:
68
+
69
+ #### wholepath
70
+
71
+ Whole path documents are identified by the "wholepath" tag. These documents describe the entire path taken and assign a signature to the path you can
72
+ use to identify it among paths taken. This allows you to e.g. do route flap detection, rtt & loss analysis, etc.
73
+
74
+ #### hop
75
+
76
+ Hop documents are identified by the "hop" tag. These documents describe a single hop on a path (where the path is identified by the same identifier
77
+ that the wholepath document contains). You can use these with the excellent [Network visualization plugin](https://github.com/dlumbrer/kbn_network) to visualize routes in kibana.
78
+
79
+
80
+ ## Contributing
81
+
82
+ All contributions are welcome: ideas, patches, documentation, bug reports, complaints, and even something you drew up on a napkin.
83
+
84
+ Programming is not a required skill. Whatever you've seen about open source and maintainers or community members saying "send patches or die" - you will not see that here.
85
+
86
+ It is more important to the community that you are able to contribute.
87
+
88
+ For more information about contributing, see the [CONTRIBUTING](https://github.com/elastic/logstash/blob/master/CONTRIBUTING.md) file.
@@ -0,0 +1,132 @@
1
+ # encoding: utf-8
2
+ require "logstash/codecs/base"
3
+ require "logstash/codecs/line"
4
+ require "logstash/namespace"
5
+ require "securerandom"
6
+ require "digest"
7
+
8
+
9
+ # This codec presumes you've somehow sent in the equivalent of this
10
+ # bash one-liner:
11
+ # (echo "S MYTARGET" ; mtr --raw -c <samplecount> 8.8.8.8) | awk '{printf $1";"}'
12
+ # You can get that into logstash any way you want, e.g. netcat will
13
+ # work if you set up a tcp input:
14
+ # (echo "S MYTARGET" ; mtr --raw -c <samplecount> 8.8.8.8) | awk '{printf $1";"}' | nc <myserver> <myport>
15
+ #
16
+
17
+ class MtrRec
18
+ attr_accessor :type,:id,:data
19
+ def initialize(line)
20
+ parts = line.split(/\s+/,3)
21
+ @type = parts[0]
22
+ @id = parts[1]
23
+ @data = parts[2]
24
+ end
25
+ end
26
+
27
+ class MtrHost
28
+ attr_accessor :hostid,:addr,:pings,:dns,:recs,:totalreplies
29
+ def initialize(rec,pingcount,recs)
30
+ @hostid = rec.id
31
+ @addr = rec.data
32
+ @recs = recs
33
+ @pings = recs.select{|each| each.type == 'p'}.collect {|each|each.data}
34
+ @pingloss = (100.to_f - (100.to_f * (@pings.size.to_f / pingcount.to_f))).to_i if pingcount.to_i > 0
35
+ @avgrtt = (@pings.inject(0.0) {|counter,each| counter += (each.to_f/1000)} / @pings.size).to_i
36
+ @dns = recs.select{|each| each.type =='d'}.collect {|each|each.data}.pop
37
+ end
38
+ def to_event_struct
39
+ {:hostid => @hostid, :addr => @addr , :pings => @pings ,:dns => @dns,:pingloss => @pingloss,:avgrtt => @avgrtt}
40
+ end
41
+ end
42
+
43
+ class LogStash::Codecs::Mtrraw < LogStash::Codecs::Base
44
+
45
+ # The codec name
46
+ config_name "mtrraw"
47
+
48
+ # Append a string to the message
49
+ # config :append, :validate => :string, :default => ', Hello World!'
50
+
51
+ def register
52
+ end # def register
53
+
54
+ def decode(data)
55
+ mtrlines = data.split(';')
56
+ mtrrecs = mtrlines.collect {|each| MtrRec.new(each) }
57
+ if mtrrecs[0].type == 's'
58
+ target = mtrrecs.shift.data
59
+ pingcount = 0
60
+ if target =~ /(\w+) (\d+)/
61
+ target = $1
62
+ pingcount = $2
63
+ end
64
+ end
65
+ id = SecureRandom.uuid
66
+ hops = Array.new
67
+ mtrrecs.each { |rec|
68
+ if rec.type == 'h'
69
+ hop = MtrHost.new(rec,pingcount,mtrrecs.select{|each| each.id == rec.id }).to_event_struct
70
+ if hops.size > 1
71
+ if (hops[hops.size - 1][:addr] != hop[:addr])
72
+ hops.push(hop)
73
+ else
74
+ # It's a duplicate of the last hop - drop it
75
+ end
76
+ else
77
+ hops.push(hop)
78
+ end
79
+ end
80
+ }
81
+ path = hops.collect {|each|each[:addr]}
82
+ pathsig = Digest::MD5.hexdigest(path.join('-'))
83
+ avgloss = hops.inject(0) {|loss,each| loss += each[:pingloss]} / path.size
84
+ avgrtt = hops.inject(0.0) {|rtt,each| rtt += each[:avgrtt]} / path.size
85
+ tracedata = { "id" => id,
86
+ "target" => target,
87
+ "message" => data ,
88
+ "hops" => hops,
89
+ "path" => path ,
90
+ "pathsig" => pathsig,
91
+ "pingcount"=>pingcount,
92
+ "avgloss"=>avgloss,
93
+ "avgrtt" => avgrtt,
94
+ "tags" => ["wholepath"]
95
+ }
96
+ yield LogStash::Event.new(tracedata)
97
+ # Construct a starting point for trace to target
98
+ yield LogStash::Event.new({
99
+ "id" => id,
100
+ "target" => target,
101
+ "tags" => ["hop"],
102
+ "seq" => -1,
103
+ "pathsig" => pathsig,
104
+ "A_node" => "TO:#{target}",
105
+ "Z_node" => hops[0][:addr],
106
+ "dns" => "startingpoint",
107
+ "avgrtt" => 0,
108
+ "avgloss" => 0
109
+ })
110
+ 0.upto(path.size - 2) {
111
+ |index|
112
+ yield LogStash::Event.new({ "id" => id,
113
+ "target" => target,
114
+ "tags" => ["hop"],
115
+ "pathsig" => pathsig,
116
+ "seq" => index,
117
+ "A_node" => hops[index][:addr],
118
+ "Z_node" => hops[index + 1][:addr],
119
+ "dns" => hops[index + 1][:dns],
120
+ "avgrtt" => hops[index + 1][:avgrtt],
121
+ "avgloss" => hops[index + 1][:avgloss]
122
+ })
123
+ }
124
+ end # def decode
125
+
126
+ # Encode a single event, this returns the raw data to be returned as a String
127
+ def encode_sync(event)
128
+ # Nothing to do.
129
+ @on_event.call(event, event)
130
+ end # def encode_sync
131
+
132
+ end # class LogStash::Codecs::Mtrraw
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-codec-mtrraw'
3
+ s.version = '0.1.0'
4
+ s.licenses = ['Apache License (2.0)']
5
+ s.summary = 'Converts optionally overloaded mtr --raw data to an event'
6
+ s.description = 'Turn mtr --raw events with optional overloading into logstash events. see docs'
7
+ s.homepage = 'https://github.com/svdasein/logstash-codec-mtrraw'
8
+ s.authors = ['svdasein']
9
+ s.email = 'daveparker01@gmail.com'
10
+ s.require_paths = ['lib']
11
+
12
+ # Files
13
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
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-plugin-api', "~> 2.0"
22
+ s.add_runtime_dependency 'logstash-codec-line'
23
+ s.add_development_dependency 'logstash-devutils'
24
+ end
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+ require_relative '../spec_helper'
3
+ require "logstash/codecs/mtrraw"
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-codec-mtrraw
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - svdasein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash-core-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: logstash-codec-line
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: logstash-devutils
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Turn mtr --raw events with optional overloading into logstash events. see
56
+ docs
57
+ email: daveparker01@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - CHANGELOG.md
63
+ - CONTRIBUTORS
64
+ - Gemfile
65
+ - LICENSE
66
+ - README.md
67
+ - lib/logstash/codecs/mtrraw.rb
68
+ - logstash-codec-mtrraw.gemspec
69
+ - spec/codecs/mtrraw_spec.rb
70
+ - spec/spec_helper.rb
71
+ homepage: https://github.com/svdasein/logstash-codec-mtrraw
72
+ licenses:
73
+ - Apache License (2.0)
74
+ metadata:
75
+ logstash_plugin: 'true'
76
+ logstash_group: codec
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.5.1
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Converts optionally overloaded mtr --raw data to an event
97
+ test_files:
98
+ - spec/codecs/mtrraw_spec.rb
99
+ - spec/spec_helper.rb
100
+ has_rdoc: