fluent-plugin-collectd-unroll 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog ADDED
@@ -0,0 +1,3 @@
1
+ Release 0.1.0 - 2014/10/10
2
+
3
+ * First release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Output filter plugin to rewrite Collectd JSON output to unroll into a flat json
2
+
3
+ Rewrites the message coming from Collectd to store as a flat json. Can be used in Elasticsearch to display metrics.
4
+
5
+ ## Installation
6
+
7
+ Use RubyGems:
8
+
9
+ gem install fluent-plugin-collectd-unroll
10
+
11
+ ## Configuration
12
+
13
+ <match pattern>
14
+ type collectd_unroll
15
+ </match>
16
+
17
+ If following record is passed:
18
+
19
+ ```js
20
+ [{"time" => 1000, "host" => 'host_v', "interval" => 5, "plugin" => 'plugin_v', "plugin_instance" => 'plugin_instance_v', "type" => 'type_v', "type_instance" => 'type_instance_v', "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']}]
21
+ ```
22
+
23
+ then you got new record like below:
24
+
25
+ ```js
26
+ [{"n1"=>"v1", "n2"=>"v2"}]
27
+ ```
28
+
29
+ and the record tag will be changed to
30
+
31
+ ```js
32
+ host_v.plugin_v.plugin_instance_v.type_v.type_instance_v
33
+ ```
34
+
35
+ Empty values in "plugin", "plugin_instance", "type" or "type_instance" will not be copied into the new tag name
36
+
37
+
38
+ ## WARNING
39
+
40
+ * This plugin was written to deal with a specific use-case, might not be the best fit for everyone. If you need more configurability/features, create a PR
41
+
42
+
43
+ ## Copyright
44
+
45
+ <table>
46
+ <tr>
47
+ <td>Author</td><td>Manoj Sharma <vigyanik@gmail.com></td>
48
+ </tr>
49
+ <tr>
50
+ <td>License</td><td>MIT License</td>
51
+ </tr>
52
+ </table>
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.test_files = FileList['test/*.rb']
9
+ test.verbose = true
10
+ end
11
+
12
+ task :default => [:build]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-collectd-unroll"
6
+ gem.description = "Output filter plugin to rewrite Collectd JSON output to flat json"
7
+ gem.homepage = "https://github.com/giannello/fluent-plugin-collectd-unroll"
8
+ gem.summary = gem.description
9
+ gem.version = File.read("VERSION").strip
10
+ gem.authors = ["Manoj Sharma"]
11
+ gem.email = "vigyanik@gmail.com"
12
+ gem.has_rdoc = false
13
+ #gem.platform = Gem::Platform::RUBY
14
+ gem.license = 'MIT'
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency "fluentd", "~> 0.10.17"
21
+ gem.add_development_dependency "rake", ">= 0.9.2"
22
+ end
@@ -0,0 +1,57 @@
1
+ module Fluent
2
+ class CollectdUnrollOutput < Output
3
+ Fluent::Plugin.register_output('collectd_unroll', self)
4
+
5
+ config_param :remove_tag_prefix, :string, :default => nil
6
+ config_param :add_tag_prefix, :string, :default => nil
7
+
8
+
9
+ def emit(tag, es, chain)
10
+ tag = update_tag(tag)
11
+ es.each { |time, record|
12
+ Engine.emit(tag, time, normalize_record(record))
13
+ }
14
+
15
+ chain.next
16
+ end
17
+
18
+
19
+ def update_tag(tag)
20
+ if remove_tag_prefix
21
+ if remove_tag_prefix == tag
22
+ tag = ''
23
+ elsif tag.to_s.start_with?(remove_tag_prefix+'.')
24
+ tag = tag[remove_tag_prefix.length+1 .. -1]
25
+ end
26
+ end
27
+ if add_tag_prefix
28
+ tag = tag && tag.length > 0 ? "#{add_tag_prefix}.#{tag}" : add_tag_prefix
29
+ end
30
+ return tag
31
+ end
32
+
33
+ private
34
+
35
+ def normalize_record(record)
36
+ if record.nil?
37
+ return record
38
+ end
39
+ if !(record.has_key?('values')) || !(record.has_key?('dsnames')) || !(record.has_key?('dstypes')) || !(record.has_key?('host')) || !(record.has_key?('plugin')) || !(record.has_key?('plugin_instance')) || !(record.has_key?('type')) || !(record.has_key?('type_instance'))
40
+ return record
41
+ end
42
+
43
+ record['values'].each_with_index { |value, index|
44
+ @tags = [record['host'].gsub(".","/"), record['plugin'], record['plugin_instance'], record['type'], record['type_instance'], record['dsnames'][index]]
45
+ tag = @tags.join(".").squeeze(".").gsub(/\.$/, '')
46
+ record[tag] = value
47
+ record[record['dsnames'][index]] = value
48
+ record['dstype_' + record['dsnames'][index]] = record['dstypes'][index]
49
+ record['dstype'] = record['dstypes'][index]
50
+ }
51
+ record.delete('dstypes')
52
+ record.delete('dsnames')
53
+ record.delete('values')
54
+ record
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,69 @@
1
+ ## match tag=debug.** and dump to console
2
+ <match debug.**>
3
+ type stdout
4
+ </match>
5
+
6
+ ####
7
+ ## Source descriptions:
8
+ ##
9
+
10
+ ## built-in TCP input
11
+ ## @see http://docs.fluentd.org/articles/in_forward
12
+ <source>
13
+ type forward
14
+ </source>
15
+
16
+
17
+ # HTTP input
18
+ # POST http://localhost:8888/<tag>?json=<json>
19
+ # POST http://localhost:8888/td.myapp.login?json={"user"%3A"me"}
20
+ # @see http://docs.fluentd.org/articles/in_http
21
+ # receives collectd input
22
+ <source>
23
+ type http
24
+ port 8888
25
+ </source>
26
+
27
+ ## live debugging agent
28
+ <source>
29
+ type debug_agent
30
+ bind 127.0.0.1
31
+ port 24230
32
+ </source>
33
+ <match collectd>
34
+ type collectd_unroll
35
+ add_tag_prefix metrics_unrolled
36
+ </match>
37
+
38
+ <match metrics_unrolled.**>
39
+ type record_reformer
40
+ tag logs.collectd.zeushack085-2f586ba2
41
+ <record>
42
+ @timestamp ${time}
43
+ </record>
44
+ </match>
45
+
46
+ <source>
47
+ type syslog
48
+ port 42185
49
+ tag syslog
50
+ </source>
51
+
52
+ <match syslog.**>
53
+ type record_reformer
54
+ tag logs.${tag}.zeushack085-2f586ba2
55
+ <record>
56
+ @timestamp ${time}
57
+ </record>
58
+ </match>
59
+
60
+ <match logs.**>
61
+ type secure_forward
62
+ shared_key cisco_zeus_log_metric_pipline
63
+ self_hostname fluentd-client1.ciscozeus.io
64
+ secure false
65
+ keepalive 10
66
+ <server>
67
+ host data01.ciscozeus.io
68
+ </server>
69
+ </match>
@@ -0,0 +1,100 @@
1
+ require 'fluent/test'
2
+ require 'fluent/plugin/out_collectd_unroll'
3
+
4
+
5
+ class CollectdUnrollOutputTest < Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ CONFIG = %[
11
+ type collectd_unroll
12
+ tag foo.filtered
13
+ ]
14
+
15
+ def create_driver(conf = CONFIG)
16
+ Fluent::Test::OutputTestDriver.new(Fluent::CollectdUnrollOutput, tag='test_tag').configure(conf)
17
+ end
18
+
19
+ def test_rewrite_tag
20
+ d = create_driver %[
21
+ type collectd_unroll
22
+ ]
23
+
24
+ d.run do
25
+ d.emit([{
26
+ "time" => 1000, "host" => 'host', "interval" => 5,
27
+ "plugin" => 'plugin', "plugin_instance" => 'plugin_instance',
28
+ "type" => 'type', "type_instance" => 'type_instance',
29
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
30
+ }])
31
+ d.emit([{
32
+ "time" => 1000, "host" => 'host', "interval" => 5,
33
+ "plugin" => 'plugin', "plugin_instance" => '',
34
+ "type" => 'type', "type_instance" => 'type_instance',
35
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
36
+ }])
37
+ d.emit([{
38
+ "time" => 1000, "host" => 'host', "interval" => 5,
39
+ "plugin" => 'plugin', "plugin_instance" => 'plugin_instance',
40
+ "type" => '', "type_instance" => 'type_instance',
41
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
42
+ }])
43
+ d.emit([{
44
+ "time" => 1000, "host" => 'host', "interval" => 5,
45
+ "plugin" => 'plugin', "plugin_instance" => 'plugin_instance',
46
+ "type" => 'type', "type_instance" => '',
47
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
48
+ }])
49
+ end
50
+
51
+ assert_equal 4, d.emits.length
52
+ assert_equal "test_tag.host.plugin.plugin_instance.type.type_instance", d.emits[0][0]
53
+ assert_equal "test_tag.host.plugin.type.type_instance", d.emits[1][0]
54
+ assert_equal "test_tag.host.plugin.plugin_instance.type_instance", d.emits[2][0]
55
+ assert_equal "test_tag.host.plugin.plugin_instance.type", d.emits[3][0]
56
+ end
57
+
58
+ def test_use_timestamp
59
+ d = create_driver %[
60
+ type collectd_unroll
61
+ ]
62
+
63
+ d.run do
64
+ d.emit([{
65
+ "time" => 1000, "host" => 'host', "interval" => 5,
66
+ "plugin" => 'plugin', "plugin_instance" => 'plugin_instance',
67
+ "type" => 'type', "type_instance" => 'type_instance',
68
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
69
+ }])
70
+ d.emit([{
71
+ "time" => 9999, "host" => 'host', "interval" => 5,
72
+ "plugin" => 'plugin', "plugin_instance" => '',
73
+ "type" => 'type', "type_instance" => 'type_instance',
74
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
75
+ }])
76
+ end
77
+
78
+ assert_equal 2, d.emits.length
79
+ assert_equal 1000, d.emits[0][1]
80
+ assert_equal 9999, d.emits[1][1]
81
+ end
82
+
83
+ def test_normalize_record
84
+ d = create_driver %[
85
+ type collectd_unroll
86
+ ]
87
+
88
+ d.run do
89
+ d.emit([{
90
+ "time" => 1000, "host" => 'v', "interval" => 5,
91
+ "plugin" => 'v', "plugin_instance" => 'v',
92
+ "type" => 'v', "type_instance" => 'v',
93
+ "values" => ['v1', 'v2'], "dsnames" => ['n1', 'n2'], "dstypes" => ['t1', 't2']
94
+ }])
95
+ end
96
+
97
+ assert_equal ({'n1'=>'v1','n2'=>'v2'} - d.records[0]).empty?, true
98
+ end
99
+
100
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-collectd-unroll
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Manoj Sharma
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-10-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fluentd
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.10.17
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.10.17
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.9.2
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.9.2
46
+ description: Output filter plugin to rewrite Collectd JSON output to flat json
47
+ email: vigyanik@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - ChangeLog
53
+ - Gemfile
54
+ - README.md
55
+ - Rakefile
56
+ - VERSION
57
+ - fluent-plugin-collectd-unroll.gemspec
58
+ - lib/fluent/plugin/out_collectd_unroll.rb
59
+ - sample-zeus-config/td-agent.conf
60
+ - test/out_collectd_unroll.rb
61
+ homepage: https://github.com/giannello/fluent-plugin-collectd-unroll
62
+ licenses:
63
+ - MIT
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.23
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Output filter plugin to rewrite Collectd JSON output to flat json
86
+ test_files: []