fluent-plugin-ec2-metadata 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5908f29a5f627257434a2f2bc851ce60bd1471a1
4
+ data.tar.gz: 4e47bd06fe4857a6a53f15e27ce302d3d43ef342
5
+ SHA512:
6
+ metadata.gz: 0a89c1f3f296b57e23e459dc592884870fda770f3d1814840953b6f188e003710cf3242a891784adb7654dab9533fc97731c62d5f4a956a8d47775cd7dc55e9d
7
+ data.tar.gz: 80acb1d9eaa4e32bfd1adc418c53877d53e4341e983ff213ba1f41732d2ee7cd16fa88c421d4f04227aa057d9412e466711e3c010cd1f7de2bdff9a701497064
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor/bundle
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-ec2-metadata.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2014- SAKAMOTO Takumi
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/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # fluent-plugin-ec2-metadata
2
+
3
+ Fluentd plugin to add ec2 metadata fields to a event record
4
+
5
+ ## Installation
6
+ Use RubyGems:
7
+
8
+ gem install fluent-plugin-ec2-metadata
9
+
10
+ ## Configuration
11
+
12
+ Example:
13
+
14
+ <match foo.**>
15
+ type ec2-metadata
16
+ output_tag ${instance_id}.${tag}
17
+
18
+ <record>
19
+ hostname ${instance_id}
20
+ </record>
21
+ </match>
22
+
23
+ Assume following input is coming:
24
+
25
+ ```js
26
+ foo.bar {"message":"hello ec2!"}
27
+ ```
28
+
29
+ then output becomes as below (indented):
30
+
31
+ ```js
32
+ i-28b5ee77.foo.bar {
33
+ "hostname" : "i-28b5ee77",
34
+ "message" : "hello ec2!"
35
+ }
36
+ ```
37
+
38
+ ### Placeholders
39
+
40
+ The following placeholders are available:
41
+
42
+ * ${instance_id} instance id
43
+ * ${tag} input tag
44
+ * ${tag_parts} input tag splitted by '.'. you can use it like `${tag_parts[0]}` or `${tag_parts[-1]}`
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-ec2-metadata"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["SAKAMOTO Takumi"]
9
+ spec.email = ["takumi.saka@gmail.com"]
10
+ spec.description = %q{Output plugin to add ec2 metadata into messages}
11
+ spec.summary = %q{Output plugin to add ec2 metadata into messages}
12
+ spec.homepage = "https://github.com/takus/fluent-plugin-ec2-metadata"
13
+ spec.license = "APLv2"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "rake"
21
+ spec.add_runtime_dependency "fluentd"
22
+ end
@@ -0,0 +1,94 @@
1
+ module Fluent
2
+ class EC2MetadataOutput < Output
3
+ Fluent::Plugin.register_output('ec2-metadata', self)
4
+
5
+ def initialize
6
+ super
7
+ require 'net/http'
8
+ end
9
+
10
+ config_param :output_tag, :string
11
+
12
+ def configure(conf)
13
+ super
14
+
15
+ # <record></record> directive
16
+ @map = {}
17
+ conf.elements.select { |element| element.name == 'record' }.each { |element|
18
+ element.each_pair { |k, v|
19
+ element.has_key?(k)
20
+ @map[k] = v
21
+ }
22
+ }
23
+
24
+ @placeholder_expander = PlaceholderExpander.new
25
+
26
+ # get ec2 metadata
27
+ @ec2_metadata = {}
28
+ @ec2_metadata['instance_id'] = get_instance_id()
29
+ end
30
+
31
+ def emit(tag, es, chain)
32
+ tag_parts = tag.split('.')
33
+ es.each { |time, record|
34
+ new_tag, new_record = modify(@output_tag, record, tag, tag_parts)
35
+ Engine.emit(new_tag, time, new_record)
36
+ }
37
+ chain.next
38
+ rescue => e
39
+ $log.warn "ec2-metadata: #{e.class} #{e.message} #{e.backtrace.join(', ')}"
40
+ end
41
+
42
+ private
43
+
44
+ def get_instance_id
45
+ res = Net::HTTP.get_response("169.254.169.254", "/latest/meta-data/instance-id")
46
+ raise Fluent::ConfigError, "ec2-metadata: failed to get instance-id" unless res.is_a?(Net::HTTPSuccess)
47
+ raise Fluent::ConfigError, "ec2-metadata: invalid instance-id #{res.body}" unless res.body =~ /^i-\h{8}$/
48
+ res.body
49
+ end
50
+
51
+ def modify(output_tag, record, tag, tag_parts)
52
+ @placeholder_expander.prepare_placeholders(record, tag, tag_parts, @ec2_metadata)
53
+
54
+ new_tag = @placeholder_expander.expand(output_tag)
55
+
56
+ new_record = record.dup
57
+ @map.each_pair { |k, v| new_record[k] = @placeholder_expander.expand(v) }
58
+
59
+ [new_tag, new_record]
60
+ end
61
+
62
+ class PlaceholderExpander
63
+ # referenced https://github.com/fluent/fluent-plugin-rewrite-tag-filter
64
+ # referenced https://github.com/sonots/fluent-plugin-record-reformer
65
+ attr_reader :placeholders
66
+
67
+ def prepare_placeholders(record, tag, tag_parts, ec2_metadata)
68
+ placeholders = {
69
+ '${tag}' => tag,
70
+ }
71
+
72
+ size = tag_parts.size
73
+ tag_parts.each_with_index { |t, idx|
74
+ placeholders.store("${tag_parts[#{idx}]}", t)
75
+ placeholders.store("${tag_parts[#{idx-size}]}", t) # support tag_parts[-1]
76
+ }
77
+
78
+ ec2_metadata.each { |k, v|
79
+ placeholders.store("${#{k}}", v)
80
+ }
81
+
82
+ @placeholders = placeholders
83
+ end
84
+
85
+ def expand(str)
86
+ str.gsub(/(\${[a-z_]+(\[-?[0-9]+\])?}|__[A-Z_]+__)/) {
87
+ $log.warn "ec2-metadata: unknown placeholder `#{$1}` found in a tag `#{tag}`" unless @placeholders.include?($1)
88
+ @placeholders[$1]
89
+ }
90
+ end
91
+ end
92
+
93
+ end
94
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ require 'fluent/plugin/out_ec2_metadata'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+
3
+ class EC2MetadataOutputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ output_tag ${instance_id}.${tag}
10
+ <record>
11
+ instance_id ${instance_id}
12
+ </record>
13
+ ]
14
+
15
+ def create_driver(conf = CONFIG, tag='test')
16
+ Fluent::Test::OutputTestDriver.new(Fluent::EC2MetadataOutput, tag).configure(conf)
17
+ end
18
+
19
+ def get_instance_id
20
+ Net::HTTP.get_response('169.254.169.254', '/latest/meta-data/instance-id').body
21
+ end
22
+
23
+ def test_emit
24
+ d = create_driver(CONFIG, 'foo.bar')
25
+
26
+ d.run do
27
+ d.emit("a" => 1)
28
+ d.emit("a" => 2)
29
+ end
30
+
31
+ instance_id = get_instance_id
32
+
33
+ # tag
34
+ assert_equal "#{instance_id}.foo.bar", d.emits[0][0]
35
+ assert_equal "#{instance_id}.foo.bar", d.emits[1][0]
36
+
37
+ # record
38
+ mapped = { 'instance_id' => instance_id }
39
+ assert_equal [
40
+ {"a" => 1}.merge(mapped),
41
+ {"a" => 2}.merge(mapped),
42
+ ], d.records
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-ec2-metadata
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - SAKAMOTO Takumi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fluentd
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
+ description: Output plugin to add ec2 metadata into messages
42
+ email:
43
+ - takumi.saka@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .travis.yml
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - fluent-plugin-ec2-metadata.gemspec
55
+ - lib/fluent/plugin/out_ec2_metadata.rb
56
+ - test/helper.rb
57
+ - test/plugin/test_out_ec2_metadata.rb
58
+ homepage: https://github.com/takus/fluent-plugin-ec2-metadata
59
+ licenses:
60
+ - APLv2
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.0.3
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Output plugin to add ec2 metadata into messages
82
+ test_files:
83
+ - test/helper.rb
84
+ - test/plugin/test_out_ec2_metadata.rb