logstash-codec-mtrraw 0.1.0
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 +7 -0
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTORS +10 -0
- data/Gemfile +3 -0
- data/LICENSE +11 -0
- data/README.md +88 -0
- data/lib/logstash/codecs/mtrraw.rb +132 -0
- data/logstash-codec-mtrraw.gemspec +24 -0
- data/spec/codecs/mtrraw_spec.rb +3 -0
- data/spec/spec_helper.rb +2 -0
- metadata +100 -0
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
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
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
|
data/spec/spec_helper.rb
ADDED
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:
|