observed 0.1.1 → 0.2.0.rc1
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 +9 -9
- data/.travis.yml +4 -0
- data/README.md +53 -78
- data/examples/observed.rb +1 -1
- data/exe/observed-oneshot +3 -1
- data/features/explicit_routing.feature +33 -0
- data/features/oneshot.feature +4 -0
- data/features/test_in_single_ruby_source.feature +4 -0
- data/integrations/observed-clockwork/features/run_observed_inside_clockwork.feature +6 -7
- data/integrations/observed-clockwork/lib/observed/clockwork/version.rb +1 -1
- data/integrations/observed-clockwork/lib/observed/clockwork.rb +0 -1
- data/integrations/observed-clockwork/observed-clockwork.gemspec +1 -1
- data/integrations/observed-eventmachine/.gitignore +17 -0
- data/integrations/observed-eventmachine/Gemfile +8 -0
- data/integrations/observed-eventmachine/LICENSE.txt +22 -0
- data/integrations/observed-eventmachine/README.md +29 -0
- data/integrations/observed-eventmachine/Rakefile +1 -0
- data/integrations/observed-eventmachine/examples/observed.rb +30 -0
- data/integrations/observed-eventmachine/features/integration_via_single_ruby_source.feature +48 -0
- data/integrations/observed-eventmachine/features/support/env.rb +8 -0
- data/integrations/observed-eventmachine/lib/observed/eventmachine/version.rb +5 -0
- data/integrations/observed-eventmachine/lib/observed/eventmachine.rb +70 -0
- data/integrations/observed-eventmachine/observed-eventmachine.gemspec +28 -0
- data/lib/observed/application/oneshot.rb +14 -37
- data/lib/observed/builtin_plugins/file.rb +5 -14
- data/lib/observed/builtin_plugins/stdout.rb +7 -14
- data/lib/observed/config.rb +4 -4
- data/lib/observed/config_builder.rb +154 -87
- data/lib/observed/config_dsl.rb +2 -8
- data/lib/observed/configurable.rb +61 -3
- data/lib/observed/context.rb +90 -0
- data/lib/observed/default/observer.rb +2 -5
- data/lib/observed/default.rb +0 -1
- data/lib/observed/event_bus.rb +31 -0
- data/lib/observed/execution_job_factory.rb +95 -0
- data/lib/observed/job.rb +163 -0
- data/lib/observed/jobbed_event_bus.rb +33 -0
- data/lib/observed/logging.rb +40 -0
- data/lib/observed/observer.rb +1 -0
- data/lib/observed/observer_helpers/timer.rb +13 -5
- data/lib/observed/pluggable.rb +11 -0
- data/lib/observed/reporter/regexp_matching.rb +2 -1
- data/lib/observed/reporter/report_formatting.rb +57 -0
- data/lib/observed/reporter.rb +0 -2
- data/lib/observed/system.rb +11 -78
- data/lib/observed/translator.rb +22 -0
- data/lib/observed/version.rb +1 -1
- data/lib/observed.rb +10 -12
- data/omnibus-observed/.gitignore +9 -0
- data/omnibus-observed/Berksfile +3 -0
- data/omnibus-observed/Berksfile.lock +52 -0
- data/omnibus-observed/Gemfile +4 -0
- data/omnibus-observed/README.md +102 -0
- data/omnibus-observed/Vagrantfile +93 -0
- data/omnibus-observed/config/projects/observed.rb +20 -0
- data/omnibus-observed/config/software/observed.rb +19 -0
- data/omnibus-observed/package-scripts/observed/makeselfinst +27 -0
- data/omnibus-observed/package-scripts/observed/postinst +17 -0
- data/omnibus-observed/package-scripts/observed/postrm +9 -0
- data/plugins/observed-fluentd/lib/observed/fluentd/version.rb +1 -1
- data/plugins/observed-gauge/README.md +5 -0
- data/plugins/observed-gauge/lib/observed/gauge/version.rb +1 -1
- data/plugins/observed-gauge/lib/observed/gauge.rb +11 -13
- data/plugins/observed-gauge/observed-gauge.gemspec +1 -1
- data/plugins/observed-gauge/spec/gauge_spec.rb +7 -7
- data/plugins/observed-growl/Gemfile +6 -0
- data/plugins/observed-growl/lib/observed/growl.rb +80 -0
- data/plugins/observed-http/lib/observed/http/version.rb +1 -1
- data/plugins/observed-http/lib/observed/http.rb +10 -8
- data/plugins/observed-http/observed-http.gemspec +1 -1
- data/plugins/observed-http/spec/http_spec.rb +62 -7
- data/plugins/observed-http/spec/integration_spec.rb +14 -0
- data/plugins/observed-shell/Gemfile +5 -0
- data/plugins/observed-shell/lib/observed/shell.rb +54 -0
- data/run-integration-tests +81 -0
- data/spec/builtin_plugins/stdout_spec.rb +7 -3
- data/spec/config_builder_spec.rb +42 -59
- data/spec/config_dsl_spec.rb +4 -0
- data/spec/configurable_spec.rb +141 -31
- data/spec/event_bus_spec.rb +16 -0
- data/spec/execution_job_factory_spec.rb +35 -0
- data/spec/job_factory_spec.rb +16 -0
- data/spec/job_spec.rb +228 -0
- data/spec/jobbed_event_bus_spec.rb +38 -0
- data/spec/observed_spec.rb +203 -0
- data/spec/observer_helpers/timer_spec.rb +187 -0
- data/spec/oneshot_spec.rb +7 -2
- data/spec/system_spec.rb +5 -39
- metadata +55 -12
- data/lib/observed/default/reporter.rb +0 -17
- data/lib/observed/reader.rb +0 -14
- data/lib/observed/writer.rb +0 -14
- data/spec/reader_spec.rb +0 -15
- data/spec/writer_spec.rb +0 -16
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'observed/eventmachine/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "observed-eventmachine"
|
8
|
+
spec.version = Observed::EM::VERSION
|
9
|
+
spec.authors = ["KUOKA Yusuke"]
|
10
|
+
spec.email = ["yusuke.kuoka@gree.net"]
|
11
|
+
spec.description = %q{An integration of Observed with EventMachine}
|
12
|
+
spec.summary = %q{observed-eventmachine allows running Observed observations on EventMachine to achieve scalability}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'eventmachine', '~> 1.0.3'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "cucumber"
|
27
|
+
spec.add_development_dependency "aruba"
|
28
|
+
end
|
@@ -3,10 +3,7 @@ require 'optparse'
|
|
3
3
|
require 'pathname'
|
4
4
|
|
5
5
|
require 'observed/config'
|
6
|
-
require 'observed/
|
7
|
-
require 'observed/config_dsl'
|
8
|
-
require 'observed/observer'
|
9
|
-
require 'observed/system'
|
6
|
+
require 'observed/context'
|
10
7
|
|
11
8
|
module Observed
|
12
9
|
|
@@ -28,17 +25,12 @@ module Observed
|
|
28
25
|
end
|
29
26
|
|
30
27
|
def run(observation_name=nil)
|
31
|
-
system.run(observation_name)
|
32
|
-
end
|
33
|
-
|
34
|
-
def logger
|
35
|
-
@logger ||= Logger.new(STDOUT)
|
28
|
+
@system.run(observation_name)
|
36
29
|
end
|
37
30
|
|
38
31
|
class << self
|
39
|
-
def
|
40
|
-
|
41
|
-
command_line_args = argv.dup
|
32
|
+
def parse_argv!(argv)
|
33
|
+
command_line_args = argv
|
42
34
|
|
43
35
|
args = {}
|
44
36
|
|
@@ -55,38 +47,29 @@ module Observed
|
|
55
47
|
|
56
48
|
opts.parse!(command_line_args)
|
57
49
|
|
58
|
-
|
50
|
+
unless command_line_args.size == 1 || command_line_args.size == 2
|
59
51
|
fail InvalidArgumentError, "Invalid number of arguments #{command_line_args.size} where arguments are #{command_line_args}"
|
60
52
|
end
|
61
53
|
|
62
|
-
args[:config_file] = command_line_args.
|
54
|
+
args[:config_file] = command_line_args.shift
|
55
|
+
|
56
|
+
args
|
57
|
+
end
|
63
58
|
|
59
|
+
def from_argv(argv)
|
60
|
+
args = parse_argv!(argv.dup)
|
64
61
|
create(args)
|
65
62
|
end
|
66
63
|
|
67
64
|
# @param [Hash<Symbol,String>] args
|
68
65
|
# @option args [Array<String>] :argv The Ruby's `ARGV` like object which is treated as intialization parameters for Oneshoft application.
|
69
66
|
def create(args)
|
70
|
-
|
71
|
-
|
72
|
-
else
|
73
|
-
STDOUT
|
74
|
-
end
|
75
|
-
logger = Logger.new(logger_out)
|
76
|
-
logger.level = if args[:debug]
|
77
|
-
Logger::DEBUG
|
78
|
-
else
|
79
|
-
Logger::INFO
|
80
|
-
end
|
81
|
-
sys = Observed::System.new(logger: logger)
|
67
|
+
ctx = Observed::Context.new(args)
|
68
|
+
sys = ctx.system
|
82
69
|
config = if args[:yaml_file]
|
83
70
|
YAML.load_file(args[:yaml_file])
|
84
71
|
elsif args[:config_file]
|
85
|
-
|
86
|
-
config_builder = Observed::ConfigBuilder.new(system: sys, logger: logger)
|
87
|
-
config_dsl = Observed::ConfigDSL.new(builder: config_builder, logger: logger)
|
88
|
-
config_dsl.eval_file(path)
|
89
|
-
config_dsl.config
|
72
|
+
sys.config
|
90
73
|
elsif args[:config]
|
91
74
|
c = args[:config]
|
92
75
|
c
|
@@ -103,12 +86,6 @@ module Observed
|
|
103
86
|
end
|
104
87
|
end
|
105
88
|
|
106
|
-
private
|
107
|
-
|
108
|
-
def system
|
109
|
-
@system
|
110
|
-
end
|
111
|
-
|
112
89
|
end
|
113
90
|
end
|
114
91
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
require 'observed/hash/fetcher'
|
2
2
|
require 'observed/reporter'
|
3
3
|
require 'observed/reporter/regexp_matching'
|
4
|
+
require 'observed/reporter/report_formatting'
|
4
5
|
|
5
6
|
module Observed
|
6
7
|
module BuiltinPlugins
|
7
8
|
class File < Observed::Reporter
|
8
9
|
|
9
10
|
include Observed::Reporter::RegexpMatching
|
11
|
+
include Observed::Reporter::ReportFormatting
|
10
12
|
|
11
13
|
UNDEFINED = Object.new
|
12
14
|
|
13
|
-
attribute :format, default: -> tag, time, data { "#{Time.at(time)} #{tag} #{data}" }
|
14
15
|
attribute :path
|
15
16
|
attribute :mode, default: :append
|
16
17
|
|
@@ -18,15 +19,7 @@ module Observed
|
|
18
19
|
# @param [Time] time
|
19
20
|
# @param [Hash] data
|
20
21
|
def report(tag, time, data)
|
21
|
-
|
22
|
-
formatted_data = case num_params
|
23
|
-
when 3
|
24
|
-
format.call(tag, time, data)
|
25
|
-
when 4
|
26
|
-
format.call(tag, time, data, Observed::Hash::Fetcher.new(data))
|
27
|
-
else
|
28
|
-
fail "Number of parameters for the function for the key :format must be 3 or 4, but was #{num_params}(#{format.parameters}"
|
29
|
-
end
|
22
|
+
formatted_data = format_report(tag, time, data)
|
30
23
|
mode = case self.mode
|
31
24
|
when :append, 'a'
|
32
25
|
'a'
|
@@ -34,16 +27,14 @@ module Observed
|
|
34
27
|
'w'
|
35
28
|
else
|
36
29
|
fail "Unsupported value for the parameter `:mode`: Supported values are :append, :overwrite, " +
|
37
|
-
|
30
|
+
"'a', 'w'. The specified value is #{self.mode.inspect}"
|
38
31
|
end
|
39
32
|
::File.open(path, mode) do |f|
|
40
33
|
f.puts formatted_data
|
41
34
|
end
|
42
35
|
end
|
43
36
|
|
44
|
-
|
45
|
-
'file'
|
46
|
-
end
|
37
|
+
plugin_name 'file'
|
47
38
|
end
|
48
39
|
end
|
49
40
|
end
|
@@ -2,34 +2,27 @@ require 'observed/hash/fetcher'
|
|
2
2
|
require 'observed/observer'
|
3
3
|
require 'observed/reporter'
|
4
4
|
require 'observed/reporter/regexp_matching'
|
5
|
+
require 'observed/reporter/report_formatting'
|
5
6
|
|
6
7
|
module Observed
|
7
8
|
module BuiltinPlugins
|
8
9
|
class Stdout < Observed::Reporter
|
9
10
|
|
10
11
|
include Observed::Reporter::RegexpMatching
|
12
|
+
include Observed::Reporter::ReportFormatting
|
11
13
|
|
12
|
-
attribute :
|
14
|
+
attribute :output, default: STDOUT
|
13
15
|
|
14
16
|
# @param [String] tag
|
15
17
|
# @param [Time] time
|
16
18
|
# @param [Hash] data
|
19
|
+
# @param [Object] format_result
|
17
20
|
def report(tag, time, data)
|
18
|
-
|
19
|
-
formatted_data
|
20
|
-
when 3
|
21
|
-
format.call(tag, time, data)
|
22
|
-
when 4
|
23
|
-
format.call(tag, time, data, Observed::Hash::Fetcher.new(data))
|
24
|
-
else
|
25
|
-
fail "Number of parameters for the function for the key :format must be 3 or 4, but was #{num_params}(#{format.parameters}"
|
26
|
-
end
|
27
|
-
puts formatted_data
|
21
|
+
formatted_data = format_report(tag, time, data)
|
22
|
+
output.puts formatted_data
|
28
23
|
end
|
29
24
|
|
30
|
-
|
31
|
-
'stdout'
|
32
|
-
end
|
25
|
+
plugin_name 'stdout'
|
33
26
|
end
|
34
27
|
end
|
35
28
|
end
|
data/lib/observed/config.rb
CHANGED
@@ -7,10 +7,6 @@ module Observed
|
|
7
7
|
|
8
8
|
include Observed::Configurable
|
9
9
|
|
10
|
-
# !@attribute [rw] writers
|
11
|
-
# @return [Array<Observed::Writer>]
|
12
|
-
attribute :writers
|
13
|
-
|
14
10
|
# !@attribute [rw] readers
|
15
11
|
# @return [Array<Observed::Reader>]
|
16
12
|
attribute :readers
|
@@ -23,5 +19,9 @@ module Observed
|
|
23
19
|
# @return [Array<Observed::Observer>]
|
24
20
|
attribute :observers
|
25
21
|
|
22
|
+
# !@attribuet [rw] translators
|
23
|
+
# @return [Array<Observed::Translator]
|
24
|
+
attribute :translators
|
25
|
+
|
26
26
|
end
|
27
27
|
end
|
@@ -1,36 +1,65 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'thread'
|
3
|
+
|
1
4
|
require 'observed/config'
|
2
5
|
require 'observed/configurable'
|
3
6
|
require 'observed/default'
|
4
7
|
require 'observed/hash'
|
5
|
-
require 'observed/
|
6
|
-
require 'observed/
|
8
|
+
require 'observed/translator'
|
9
|
+
require 'observed/execution_job_factory'
|
7
10
|
|
8
11
|
module Observed
|
9
12
|
|
13
|
+
class ProcObserver < Observed::Observer
|
14
|
+
def initialize(&block)
|
15
|
+
@block = block
|
16
|
+
end
|
17
|
+
def observe(data=nil, options=nil)
|
18
|
+
@block.call data, options
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ProcTranslator < Observed::Translator
|
23
|
+
def initialize(&block)
|
24
|
+
@block = block
|
25
|
+
end
|
26
|
+
def translate(tag, time, data)
|
27
|
+
@block.call data, {tag: tag, time: time}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ProcReporter < Observed::Reporter
|
32
|
+
def initialize(tag_pattern, &block)
|
33
|
+
@tag_pattern = tag_pattern
|
34
|
+
@block = block
|
35
|
+
end
|
36
|
+
def match(tag)
|
37
|
+
tag.match(@tag_pattern) if tag && @tag_pattern
|
38
|
+
end
|
39
|
+
def report(tag, time, data)
|
40
|
+
@block.call data, {tag: tag, time: time}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
10
44
|
class ConfigBuilder
|
11
45
|
include Observed::Configurable
|
12
46
|
|
47
|
+
attribute :logger, default: Logger.new(STDOUT, Logger::DEBUG)
|
48
|
+
|
13
49
|
def initialize(args)
|
14
|
-
@
|
15
|
-
@
|
50
|
+
@group_mutex = ::Mutex.new
|
51
|
+
@context = args[:context]
|
16
52
|
@observer_plugins = args[:observer_plugins] if args[:observer_plugins]
|
17
53
|
@reporter_plugins = args[:reporter_plugins] if args[:reporter_plugins]
|
54
|
+
@translator_plugins = args[:translator_plugins] if args[:translator_plugins]
|
18
55
|
@system = args[:system] || fail("The key :system must be in #{args}")
|
19
|
-
|
56
|
+
configure args
|
20
57
|
end
|
21
58
|
|
22
59
|
def system
|
23
60
|
@system
|
24
61
|
end
|
25
62
|
|
26
|
-
def writer_plugins
|
27
|
-
@writer_plugins || select_named_plugins_of(Observed::Writer)
|
28
|
-
end
|
29
|
-
|
30
|
-
def reader_plugins
|
31
|
-
@reader_plugins || select_named_plugins_of(Observed::Reader)
|
32
|
-
end
|
33
|
-
|
34
63
|
def observer_plugins
|
35
64
|
@observer_plugins || select_named_plugins_of(Observed::Observer)
|
36
65
|
end
|
@@ -39,6 +68,10 @@ module Observed
|
|
39
68
|
@reporter_plugins || select_named_plugins_of(Observed::Reporter)
|
40
69
|
end
|
41
70
|
|
71
|
+
def translator_plugins
|
72
|
+
@translator_plugins || select_named_plugins_of(Observed::Translator)
|
73
|
+
end
|
74
|
+
|
42
75
|
def select_named_plugins_of(klass)
|
43
76
|
plugins = {}
|
44
77
|
klass.select_named_plugins.each do |plugin|
|
@@ -49,8 +82,6 @@ module Observed
|
|
49
82
|
|
50
83
|
def build
|
51
84
|
Observed::Config.new(
|
52
|
-
writers: writers,
|
53
|
-
readers: readers,
|
54
85
|
observers: observers,
|
55
86
|
reporters: reporters
|
56
87
|
)
|
@@ -60,31 +91,53 @@ module Observed
|
|
60
91
|
# @param [Hash] args The configuration for each reporter which may or may not contain (1) which reporter plugin to
|
61
92
|
# use or which writer plugin to use (in combination with the default reporter plugin) (2) initialization parameters
|
62
93
|
# to instantiate the reporter/writer plugin
|
63
|
-
def report(tag_pattern, args)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
94
|
+
def report(tag_pattern=nil, args={}, &block)
|
95
|
+
if tag_pattern.is_a? ::Hash
|
96
|
+
args = tag_pattern
|
97
|
+
tag_pattern = nil
|
98
|
+
end
|
99
|
+
reporter = if args[:via] || args[:using]
|
69
100
|
via = args[:via] || args[:using]
|
70
101
|
with = args[:with] || args[:which] || {}
|
71
|
-
with = ({logger: @logger}).merge(with).merge({tag_pattern: tag_pattern})
|
102
|
+
with = ({logger: @logger}).merge(with).merge({tag_pattern: tag_pattern, system: system})
|
72
103
|
plugin = reporter_plugins[via] ||
|
73
104
|
fail(RuntimeError, %Q|The reporter plugin named "#{via}" is not found in "#{reporter_plugins}"|)
|
74
105
|
plugin.new(with)
|
106
|
+
elsif block_given?
|
107
|
+
Observed::ProcReporter.new tag_pattern, &block
|
108
|
+
else
|
109
|
+
fail "Invalid combination of arguments: #{tag_pattern} #{args}"
|
75
110
|
end
|
76
|
-
begin
|
77
|
-
reporter.match('test')
|
78
|
-
rescue => e
|
79
|
-
fail "A mis-configured reporter plugin found: #{reporter}"
|
80
|
-
rescue NotImplementedError => e
|
81
|
-
builtin_methods = Object.methods
|
82
|
-
info = (reporter.methods - builtin_methods).map {|sym| reporter.method(sym) }.map(&:source_location).compact
|
83
|
-
fail "Incomplete reporter plugin found: #{reporter}, defined in: #{info}"
|
84
|
-
end
|
85
111
|
|
86
112
|
reporters << reporter
|
87
|
-
reporter
|
113
|
+
report_it = convert_to_job(reporter)
|
114
|
+
if tag_pattern
|
115
|
+
receive(tag_pattern).then(report_it)
|
116
|
+
end
|
117
|
+
report_it
|
118
|
+
end
|
119
|
+
|
120
|
+
class ObserverCompatibilityAdapter < Observed::Observer
|
121
|
+
include Observed::Configurable
|
122
|
+
attribute :observer
|
123
|
+
attribute :system
|
124
|
+
attribute :tag
|
125
|
+
|
126
|
+
def configure(args)
|
127
|
+
super
|
128
|
+
observer.configure(args)
|
129
|
+
end
|
130
|
+
|
131
|
+
def observe(data=nil, options=nil)
|
132
|
+
case observer.method(:observe).parameters.size
|
133
|
+
when 0
|
134
|
+
observer.observe
|
135
|
+
when 1
|
136
|
+
observer.observe data
|
137
|
+
when 2
|
138
|
+
observer.observe data, options
|
139
|
+
end
|
140
|
+
end
|
88
141
|
end
|
89
142
|
|
90
143
|
# @param [String] tag The tag which is assigned to data which is generated from this observer, and is sent to
|
@@ -92,67 +145,74 @@ module Observed
|
|
92
145
|
# @param [Hash] args The configuration for each observer which may or may not contain (1) which observer plugin to
|
93
146
|
# use or which reader plugin to use (in combination with the default observer plugin) (2) initialization parameters
|
94
147
|
# to instantiate the observer/reader plugin
|
95
|
-
def observe(tag, args)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
148
|
+
def observe(tag=nil, args={}, &block)
|
149
|
+
if tag.is_a? ::Hash
|
150
|
+
args = tag
|
151
|
+
tag = nil
|
152
|
+
end
|
153
|
+
observer = if args[:via] || args[:using]
|
100
154
|
via = args[:via] || args[:using] ||
|
101
155
|
fail(RuntimeError, %Q|Missing observer plugin name for the tag "#{tag}" in "#{args}"|)
|
102
156
|
with = args[:with] || args[:which] || {}
|
103
157
|
plugin = observer_plugins[via] ||
|
104
158
|
fail(RuntimeError, %Q|The observer plugin named "#{via}" is not found in "#{observer_plugins}"|)
|
105
|
-
plugin.new(({logger:
|
159
|
+
observer = plugin.new(({logger: logger}).merge(with).merge(tag: tag, system: system))
|
160
|
+
ObserverCompatibilityAdapter.new(
|
161
|
+
system: system,
|
162
|
+
observer: observer,
|
163
|
+
tag: tag
|
164
|
+
)
|
165
|
+
elsif block_given?
|
166
|
+
Observed::ProcObserver.new &block
|
167
|
+
else
|
168
|
+
fail "No args valid args (in args=#{args}) or a block given"
|
169
|
+
end
|
170
|
+
observe_that = convert_to_job(observer)
|
171
|
+
result = if tag
|
172
|
+
a = observe_that.then(emit(tag))
|
173
|
+
group tag, (group(tag) + [a])
|
174
|
+
a
|
175
|
+
else
|
176
|
+
observe_that
|
177
|
+
end
|
178
|
+
observers << result
|
179
|
+
result
|
180
|
+
end
|
181
|
+
|
182
|
+
def translate(args={}, &block)
|
183
|
+
translator = if args[:via] || args[:using]
|
184
|
+
#tag_pattern || fail("Tag pattern missing: #{tag_pattern} where args: #{args}")
|
185
|
+
via = args[:via] || args[:using]
|
186
|
+
with = args[:with] || args[:which] || {}
|
187
|
+
with = ({logger: logger}).merge(with).merge({system: system})
|
188
|
+
plugin = translator_plugins[via] ||
|
189
|
+
fail(RuntimeError, %Q|The reporter plugin named "#{via}" is not found in "#{translator_plugins}"|)
|
190
|
+
plugin.new(with)
|
191
|
+
else
|
192
|
+
Observed::ProcTranslator.new &block
|
106
193
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
def read(args)
|
132
|
-
from = args[:from]
|
133
|
-
with = args[:with] || [:which]
|
134
|
-
reader = case from
|
135
|
-
when String
|
136
|
-
plugin = reader_plugins[from] || fail(RuntimeError, %Q|The reader plugin named "#{from}" is not found in "#{reader_plugins}"|)
|
137
|
-
with = ({logger: @logger}).merge(with)
|
138
|
-
plugin.new(with)
|
139
|
-
when Observed::Reader
|
140
|
-
from
|
141
|
-
when nil
|
142
|
-
nil
|
143
|
-
else
|
144
|
-
fail "Unexpected type of value for the key :from in: #{args}"
|
145
|
-
end
|
146
|
-
readers << reader if reader
|
147
|
-
reader
|
148
|
-
end
|
149
|
-
|
150
|
-
def writers
|
151
|
-
@writers ||= []
|
152
|
-
end
|
153
|
-
|
154
|
-
def readers
|
155
|
-
@readers ||= []
|
194
|
+
convert_to_job(translator)
|
195
|
+
end
|
196
|
+
|
197
|
+
def emit(tag)
|
198
|
+
@context.jobbed_event_bus.pipe_to_emit(tag)
|
199
|
+
end
|
200
|
+
|
201
|
+
def receive(pattern)
|
202
|
+
@context.jobbed_event_bus.receive(pattern)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Updates or get the observations belongs to the group named `name`
|
206
|
+
def group(name, observations=nil)
|
207
|
+
@group_mutex.synchronize do
|
208
|
+
@observations ||= {}
|
209
|
+
@observations[name] = observations if observations
|
210
|
+
@observations[name] || []
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def run_group(name)
|
215
|
+
@context.job_factory.parallel(group(name))
|
156
216
|
end
|
157
217
|
|
158
218
|
def reporters
|
@@ -162,6 +222,13 @@ module Observed
|
|
162
222
|
def observers
|
163
223
|
@observers ||= []
|
164
224
|
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def convert_to_job(underlying)
|
229
|
+
@execution_job_factory ||= @context.execution_job_factory
|
230
|
+
@execution_job_factory.convert_to_job(underlying)
|
231
|
+
end
|
165
232
|
end
|
166
233
|
|
167
234
|
end
|
data/lib/observed/config_dsl.rb
CHANGED
@@ -15,16 +15,15 @@ module Observed
|
|
15
15
|
|
16
16
|
include Observed::Configurable
|
17
17
|
|
18
|
-
def_delegators :@builder, :observe, :report, :read, :write
|
18
|
+
def_delegators :@builder, :observe, :translate, :report, :read, :write, :emit, :group, :run_group, :receive
|
19
19
|
|
20
20
|
attribute :builder
|
21
|
+
attribute :logger, default: Logger.new(STDOUT)
|
21
22
|
|
22
23
|
def initialize(args)
|
23
24
|
args[:builder] || fail("The key :builder must exist in #{args}")
|
24
25
|
@builder = args[:builder]
|
25
26
|
|
26
|
-
@logger = args[:logger] if args[:logger]
|
27
|
-
|
28
27
|
configure(args)
|
29
28
|
end
|
30
29
|
|
@@ -68,10 +67,5 @@ module Observed
|
|
68
67
|
eval_file file
|
69
68
|
end
|
70
69
|
|
71
|
-
private
|
72
|
-
|
73
|
-
def logger
|
74
|
-
@logger ||= Logger.new(STDOUT)
|
75
|
-
end
|
76
70
|
end
|
77
71
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Observed
|
2
|
+
# Indicates that classes included this module to have attributes which are configurable.
|
3
|
+
# `configurable` means that the attributes can be configured via named parameters of
|
4
|
+
# the constructor and the `configure` instance method of the class included this module.
|
2
5
|
module Configurable
|
3
6
|
|
4
7
|
def initialize(args={})
|
@@ -14,11 +17,25 @@ module Observed
|
|
14
17
|
self
|
15
18
|
end
|
16
19
|
|
20
|
+
# @param [String|Symbol] name
|
21
|
+
def has_attribute_value?(name)
|
22
|
+
!! get_attribute_value(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [String|Symbol] name
|
26
|
+
# @return [Object] In order of precedence, the value of the instance variable named `"@" + name`,
|
27
|
+
# or the value `@attributes[name]`, or the default value for the attribute named `name`
|
28
|
+
def get_attribute_value(name)
|
29
|
+
instance_variable_get("@#{name.to_s}") || @attributes[name] || self.class.defaults[name]
|
30
|
+
end
|
31
|
+
|
17
32
|
module ClassMethods
|
18
33
|
# @param [String|Symbol] name
|
19
34
|
def attribute(name, options={})
|
20
|
-
|
21
|
-
|
35
|
+
unless instance_methods.include? name.intern
|
36
|
+
define_method(name) do
|
37
|
+
get_attribute_value(name) || fail_for_not_configured_parameter(name)
|
38
|
+
end
|
22
39
|
end
|
23
40
|
default_value = options && options[:default]
|
24
41
|
default name => default_value if default_value
|
@@ -36,13 +53,54 @@ module Observed
|
|
36
53
|
self.new(args)
|
37
54
|
end
|
38
55
|
|
56
|
+
# Inherits the default values stored in @defaults to the sub-class
|
57
|
+
def inherited(klass)
|
58
|
+
super if defined? super
|
59
|
+
klass.default defaults
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
module ModuleMethods
|
65
|
+
# @param [String|Symbol] name
|
66
|
+
def attribute(name, options={})
|
67
|
+
@attributes ||= {}
|
68
|
+
@attributes = @attributes.merge(name => options)
|
69
|
+
end
|
70
|
+
|
71
|
+
def attributes
|
72
|
+
@attributes ||
|
73
|
+
fail(<<EOS
|
74
|
+
#{self} includes Observed::Configurable. Though, no attributes are configured for #{self}.
|
75
|
+
We don't need to include Observed::Configurable, or it might be a bug?
|
76
|
+
EOS
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def included(klass)
|
81
|
+
ensure_configurable klass
|
82
|
+
|
83
|
+
attributes.each do |name, options|
|
84
|
+
klass.attribute name, options
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def ensure_configurable(klass)
|
89
|
+
unless klass.include? Configurable
|
90
|
+
fail "The class #{klass} must include Observed::Configurable to include #{self}"
|
91
|
+
end
|
92
|
+
end
|
39
93
|
end
|
40
94
|
|
41
95
|
class NotConfiguredError < RuntimeError; end
|
42
96
|
|
43
97
|
class << self
|
44
98
|
def included(klass)
|
45
|
-
klass.
|
99
|
+
if klass.is_a? Class
|
100
|
+
klass.extend ClassMethods
|
101
|
+
else
|
102
|
+
klass.extend ModuleMethods
|
103
|
+
end
|
46
104
|
end
|
47
105
|
end
|
48
106
|
|