fluent-plugin-config_reloader 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: bea4e93686ec8aa255f0c3ab478d87254447f749
4
+ data.tar.gz: 67a4cbb98f6797a8c2955bf5ce0c2a53d4999a79
5
+ SHA512:
6
+ metadata.gz: b4dfd1712399776b69068037cad856b0e990a11fdf80cf9fbcd06e4e50de1b797cc69198b5ea194ba0a227cd9113a5e8234a30432436ab94f86b264ed88fc806
7
+ data.tar.gz: 70c397dc59d601bab9fae90c9435560a920eb2daa510d936ac5375efaa6dcbc378f179859c5e26ff9655ac69b3243bd12bcb392ddb2aa4f855e594394d79613b
data/.gitignore ADDED
@@ -0,0 +1,19 @@
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
19
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # fluent-plugin-config_reloader
2
+
3
+ reload child plugin's config plugin.
4
+
5
+ ## Output Plugin
6
+
7
+ ```
8
+ config_file child.conf
9
+ reload_file reload.txt
10
+ reload_file_watch_interval 5
11
+ ```
12
+ - config_file: child conf file path
13
+ - Require 1 `match` directive in this file
14
+ - reload_file: reload file path(reload when touch this file)
15
+ - reload_file_watch_interval (optional): reload file watch interval sec(default 1)
16
+
17
+ ## example
18
+
19
+ ```
20
+ <match example.**>
21
+ type config_reloader
22
+ config_file conf/child.conf
23
+ reload_file reload.txt
24
+ </match>
25
+ ```
26
+
27
+ ### conf/child.conf
28
+
29
+ ```
30
+ <match>
31
+ type stdout
32
+ </match>
33
+ ```
34
+
35
+ ### Use out_copy...
36
+
37
+ ```
38
+ <store>
39
+ type copy
40
+ <store>
41
+ type stdout
42
+ </store>
43
+ <store>
44
+ type null
45
+ </store>
46
+ </store>
47
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
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-config_reloader"
7
+ spec.version = '0.0.1'
8
+ spec.authors = ["bash0C7"]
9
+ spec.email = ["koshiba+github@4038nullpointer.com"]
10
+ spec.description = "Fluentd plugin to reload child plugin's config"
11
+ spec.summary = "Fluentd plugin to reload child plugin's config"
12
+ spec.homepage = "https://github.com/bash0C7/fluent-plugin-config_reloader"
13
+ spec.license = "Ruby's"
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_dependency "fluentd"
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "pry"
25
+ end
@@ -0,0 +1,151 @@
1
+ module Fluent
2
+ class Fluent::ConfigReloaderOutput < Fluent::MultiOutput
3
+ Fluent::Plugin.register_output('config_reloader', self)
4
+
5
+ config_param :config_file, :string
6
+ config_param :reload_file, :string
7
+ config_param :reload_file_watch_interval, :integer, :default => 1
8
+
9
+ class ReloadFileWatcher
10
+ require 'observer'
11
+ include ::Observable
12
+
13
+ attr_reader :thread
14
+
15
+ def self.create(observer, watch_file, interval)
16
+ obj = self.new
17
+ obj.add_observer(observer)
18
+ obj.watch watch_file, interval
19
+
20
+ obj
21
+ end
22
+
23
+ def watch watch_file, interval
24
+ mtime = Time.now
25
+
26
+ @thread = Thread.new do
27
+ loop do
28
+ if File.exists?(watch_file) && File.mtime(watch_file) > mtime
29
+ mtime = File.mtime(watch_file)
30
+
31
+ changed
32
+ notify_observers
33
+ end
34
+ sleep interval
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def initialize
41
+ super
42
+
43
+ @q = Queue.new
44
+ end
45
+
46
+ def outputs
47
+ [@output]
48
+ end
49
+
50
+ def configure(conf)
51
+ super
52
+
53
+ load_config_file
54
+ end
55
+
56
+ def start
57
+ output_start
58
+ @thread = Thread.new(&method(:run))
59
+
60
+ @watcher = ReloadFileWatcher.create(self, @reload_file, @reload_file_watch_interval)
61
+
62
+ rescue
63
+ $log.warn "raises exception: #{$!.class}, '#{$!.message}"
64
+ end
65
+
66
+ def shutdown
67
+ @watcher.delete_observers
68
+ Thread.kill(@thread)
69
+ output_shutdown
70
+ rescue
71
+ $log.warn "raises exception: #{$!.class}, '#{$!.message}"
72
+ end
73
+
74
+ def emit(tag, es, chain)
75
+ param = OpenStruct.new
76
+ param.tag = tag
77
+ param.es = es
78
+ param.chain = chain
79
+
80
+ @q.push param
81
+ end
82
+
83
+ def update
84
+ $log.warn 'config_reloader: reload config file start'
85
+ output_shutdown
86
+ load_config_file
87
+ output_start
88
+ $log.warn 'config_reloader: reload config file end'
89
+ end
90
+
91
+ private
92
+
93
+ def output_start
94
+ @output.start
95
+ end
96
+
97
+ def output_shutdown
98
+ @output.shutdown
99
+ end
100
+
101
+ def load_config_file
102
+ path = File.expand_path(@config_file)
103
+
104
+ store_elements = File.open(path) do |io|
105
+ if File.extname(path) == '.rb'
106
+ require 'fluent/config/dsl'
107
+ Config::DSL::Parser.parse(io, path)
108
+ else
109
+ Config.parse(io, File.basename(path), File.dirname(path), false)
110
+ end
111
+ end.elements.select {|e| e.name == 'store'}
112
+
113
+ raise ConfigError, "Multiple <store> directives are not available" unless store_elements.size == 1
114
+
115
+ store_element = store_elements.first
116
+
117
+ type = store_element['type']
118
+ unless type
119
+ raise ConfigError, "Missing 'type' parameter on <store> directive"
120
+ end
121
+ log.debug "adding store type=#{type.dump}"
122
+
123
+ @output = Plugin.new_output(type)
124
+ @output.configure(store_element)
125
+ end
126
+
127
+ def run
128
+ loop do
129
+ param = @q.pop
130
+
131
+ tag = param.tag
132
+ es = param.es
133
+ chain = param.chain
134
+
135
+ begin
136
+ unless es.repeatable?
137
+ m = MultiEventStream.new
138
+ es.each {|time,record|
139
+ m.add(time, record)
140
+ }
141
+ es = m
142
+ end
143
+ chain = OutputChain.new([@output], tag, es, chain)
144
+ chain.next
145
+ rescue
146
+ $log.warn "raises exception: #{$!.class}, '#{$!.message}, #{param}'"
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
data/spec/child.conf ADDED
@@ -0,0 +1,9 @@
1
+ <store>
2
+ type copy
3
+ <store>
4
+ type stdout
5
+ </store>
6
+ <store>
7
+ type null
8
+ </store>
9
+ </store>
@@ -0,0 +1,3 @@
1
+ <store>
2
+ type test
3
+ </store>
data/spec/fluent.conf ADDED
@@ -0,0 +1,13 @@
1
+ <source>
2
+ type exec
3
+ command echo http://example.com
4
+ keys uri
5
+ tag example
6
+ run_interval 1s
7
+ </source>
8
+
9
+ <match example.**>
10
+ type config_reloader
11
+ config_file spec/child.conf
12
+ reload_file spec/reload.txt
13
+ </match>
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe do
4
+ let(:driver) {Fluent::Test::OutputTestDriver.new(Fluent::ConfigReloaderOutput, tag).configure(config)}
5
+
6
+ describe 'emit' do
7
+ let(:tag) {'test.metrics'}
8
+ let(:record1) {{ 'field1' => 50, 'otherfield' => 99}}
9
+ let(:record2) {{ 'field1' => 150, 'otherfield' => 199}}
10
+ let(:time) {0}
11
+
12
+ let(:config) {
13
+ %[
14
+ type config_reloader
15
+ config_file spec/child_test.conf
16
+ reload_file spec/reload.txt
17
+ reload_file_watch_interval 0
18
+ ]
19
+ }
20
+
21
+
22
+ describe :emit do
23
+ it do
24
+ d = driver
25
+ d.run do
26
+ d.instance.emit(tag, Fluent::OneEventStream.new(time.to_i, {"a"=>1}), Fluent::Test::TestOutputChain.new)
27
+ d.instance.emit(tag, Fluent::OneEventStream.new(time.to_i, {"a"=>2}), Fluent::Test::TestOutputChain.new)
28
+ sleep 1
29
+ end
30
+ d.instance.outputs.each {|o|
31
+ expect([
32
+ [time, {"a"=>1}],
33
+ [time, {"a"=>2}],
34
+ ]).to eq(o.events)
35
+ }
36
+ end
37
+ end
38
+
39
+ describe :update do
40
+ let(:reload_file) {'spec/reload.txt'}
41
+ after(:each) do
42
+ File.delete(reload_file) if File.exists?(reload_file)
43
+ end
44
+
45
+ it do
46
+ pending("WIP")
47
+
48
+ expect_any_instance_of(Fluent::ConfigReloaderOutput).to receive(:update).once
49
+
50
+ d = driver
51
+ d.run do
52
+ d.instance.emit(tag, Fluent::OneEventStream.new(time.to_i, {"a"=>1}), Fluent::Test::TestOutputChain.new)
53
+ sleep 1
54
+ end
55
+ open(reload_file, 'w') do |o|
56
+ o.write 'xx'
57
+ end
58
+ sleep 2
59
+ sleep 2
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+ # Run specs in random order to surface order dependencies. If you find an
12
+ # order dependency and want to debug it, you can fix the order by providing
13
+ # the seed, which is printed after each run.
14
+ # --seed 1234
15
+ config.order = 'random'
16
+
17
+ require 'pry'
18
+
19
+ require 'fluent/load'
20
+ require 'fluent/test'
21
+
22
+ require 'fluent/plugin/out_config_reloader'
23
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-config_reloader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - bash0C7
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
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: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Fluentd plugin to reload child plugin's config
84
+ email:
85
+ - koshiba+github@4038nullpointer.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - fluent-plugin-config_reloader.gemspec
96
+ - lib/fluent/plugin/out_config_reloader.rb
97
+ - spec/child.conf
98
+ - spec/child_test.conf
99
+ - spec/fluent.conf
100
+ - spec/lib/fluent/plugin/out_config_reloader_spec.rb
101
+ - spec/spec_helper.rb
102
+ homepage: https://github.com/bash0C7/fluent-plugin-config_reloader
103
+ licenses:
104
+ - Ruby's
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.0
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: Fluentd plugin to reload child plugin's config
126
+ test_files:
127
+ - spec/child.conf
128
+ - spec/child_test.conf
129
+ - spec/fluent.conf
130
+ - spec/lib/fluent/plugin/out_config_reloader_spec.rb
131
+ - spec/spec_helper.rb