bp-fnordmetric 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Rakefile +6 -0
- data/fnordmetric.gemspec +41 -0
- data/lib/fnordmetric.rb +149 -0
- data/lib/fnordmetric/acceptors/acceptor.rb +42 -0
- data/lib/fnordmetric/acceptors/amqp_acceptor.rb +56 -0
- data/lib/fnordmetric/acceptors/fyrehose_acceptor.rb +43 -0
- data/lib/fnordmetric/acceptors/stomp_acceptor.rb +71 -0
- data/lib/fnordmetric/acceptors/tcp_acceptor.rb +58 -0
- data/lib/fnordmetric/acceptors/udp_acceptor.rb +37 -0
- data/lib/fnordmetric/api.rb +46 -0
- data/lib/fnordmetric/cache.rb +20 -0
- data/lib/fnordmetric/context.rb +96 -0
- data/lib/fnordmetric/defaults.rb +22 -0
- data/lib/fnordmetric/enterprise/compatibility_handler.rb +42 -0
- data/lib/fnordmetric/ext.rb +75 -0
- data/lib/fnordmetric/gauge.rb +98 -0
- data/lib/fnordmetric/gauge_calculations.rb +106 -0
- data/lib/fnordmetric/gauge_modifiers.rb +144 -0
- data/lib/fnordmetric/gauge_rendering.rb +40 -0
- data/lib/fnordmetric/gauge_validations.rb +15 -0
- data/lib/fnordmetric/gauges/distribution_gauge.rb +87 -0
- data/lib/fnordmetric/gauges/server_health_gauge.rb +13 -0
- data/lib/fnordmetric/gauges/timeseries_gauge.rb +138 -0
- data/lib/fnordmetric/gauges/toplist_gauge.rb +44 -0
- data/lib/fnordmetric/histogram.rb +64 -0
- data/lib/fnordmetric/logger.rb +63 -0
- data/lib/fnordmetric/namespace.rb +208 -0
- data/lib/fnordmetric/session.rb +139 -0
- data/lib/fnordmetric/standalone.rb +20 -0
- data/lib/fnordmetric/timeseries.rb +79 -0
- data/lib/fnordmetric/toplist.rb +61 -0
- data/lib/fnordmetric/udp_client.rb +22 -0
- data/lib/fnordmetric/util.rb +25 -0
- data/lib/fnordmetric/version.rb +3 -0
- data/lib/fnordmetric/web/app.rb +63 -0
- data/lib/fnordmetric/web/app_helpers.rb +42 -0
- data/lib/fnordmetric/web/dashboard.rb +40 -0
- data/lib/fnordmetric/web/event.rb +99 -0
- data/lib/fnordmetric/web/reactor.rb +127 -0
- data/lib/fnordmetric/web/web.rb +59 -0
- data/lib/fnordmetric/web/websocket.rb +41 -0
- data/lib/fnordmetric/widget.rb +82 -0
- data/lib/fnordmetric/widgets/bars_widget.rb +44 -0
- data/lib/fnordmetric/widgets/html_widget.rb +28 -0
- data/lib/fnordmetric/widgets/numbers_widget.rb +80 -0
- data/lib/fnordmetric/widgets/pie_widget.rb +23 -0
- data/lib/fnordmetric/widgets/timeseries_widget.rb +65 -0
- data/lib/fnordmetric/widgets/toplist_widget.rb +68 -0
- data/lib/fnordmetric/worker.rb +89 -0
- data/lib/fnordmetric/zero_config_gauge.rb +138 -0
- data/run_specs.sh +11 -0
- data/spec/api_spec.rb +49 -0
- data/spec/context_spec.rb +42 -0
- data/spec/dashboard_spec.rb +38 -0
- data/spec/event_spec.rb +170 -0
- data/spec/ext_spec.rb +14 -0
- data/spec/fnordmetric_spec.rb +56 -0
- data/spec/gauge_like_shared.rb +56 -0
- data/spec/gauge_modifiers_spec.rb +583 -0
- data/spec/gauge_spec.rb +230 -0
- data/spec/namespace_spec.rb +114 -0
- data/spec/session_spec.rb +231 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/tcp_acceptor_spec.rb +35 -0
- data/spec/timeseries_gauge_spec.rb +56 -0
- data/spec/udp_acceptor_spec.rb +35 -0
- data/spec/util_spec.rb +46 -0
- data/spec/widget_spec.rb +113 -0
- data/spec/worker_spec.rb +40 -0
- data/web/.gitignore +4 -0
- data/web/build.sh +34 -0
- data/web/css/fnordmetric.core.css +868 -0
- data/web/haml/app.haml +20 -0
- data/web/haml/distribution_gauge.haml +118 -0
- data/web/haml/timeseries_gauge.haml +80 -0
- data/web/haml/toplist_gauge.haml +194 -0
- data/web/img/head.png +0 -0
- data/web/img/list.png +0 -0
- data/web/img/list_active.png +0 -0
- data/web/img/list_hover.png +0 -0
- data/web/img/loader.gif +0 -0
- data/web/img/loader_white.gif +0 -0
- data/web/img/navbar.png +0 -0
- data/web/img/navbar_btn.png +0 -0
- data/web/img/picto_gauge.png +0 -0
- data/web/js/fnordmetric.bars_widget.js +178 -0
- data/web/js/fnordmetric.dashboard_view.js +99 -0
- data/web/js/fnordmetric.gauge_explorer.js +173 -0
- data/web/js/fnordmetric.gauge_view.js +260 -0
- data/web/js/fnordmetric.html_widget.js +21 -0
- data/web/js/fnordmetric.js +315 -0
- data/web/js/fnordmetric.numbers_widget.js +122 -0
- data/web/js/fnordmetric.overview_view.js +35 -0
- data/web/js/fnordmetric.pie_widget.js +118 -0
- data/web/js/fnordmetric.realtime_timeline_widget.js +175 -0
- data/web/js/fnordmetric.session_view.js +342 -0
- data/web/js/fnordmetric.timeline_widget.js +333 -0
- data/web/js/fnordmetric.timeseries_widget.js +405 -0
- data/web/js/fnordmetric.toplist_widget.js +119 -0
- data/web/js/fnordmetric.ui.js +91 -0
- data/web/js/fnordmetric.util.js +248 -0
- data/web/vendor/font-awesome/css/font-awesome-ie7.min.css +22 -0
- data/web/vendor/font-awesome/css/font-awesome.css +540 -0
- data/web/vendor/font-awesome/css/font-awesome.min.css +33 -0
- data/web/vendor/font-awesome/font/FontAwesome.otf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.eot +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svg +284 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.ttf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.woff +0 -0
- data/web/vendor/jquery-1.6.2.min.js +18 -0
- data/web/vendor/jquery-ui.min.js +6 -0
- data/web/vendor/jquery.combobox.js +129 -0
- data/web/vendor/jquery.maskedinput.js +252 -0
- metadata +438 -0
data/Gemfile
ADDED
data/Rakefile
ADDED
data/fnordmetric.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "date"
|
4
|
+
require "fnordmetric/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "bp-fnordmetric"
|
8
|
+
s.version = FnordMetric::VERSION
|
9
|
+
s.date = Date.today.to_s
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ["Paul Asmuth"]
|
12
|
+
s.email = ["paul@paulasmuth.com"]
|
13
|
+
s.homepage = "http://github.com/paulasmuth/fnordmetric"
|
14
|
+
s.summary = %q{FnordMetric is a Ruby Event-Tracking gem on steroids}
|
15
|
+
s.description = %q{FnordMetric is a Ruby Event-Tracking gem on steroids}
|
16
|
+
s.licenses = ["MIT"]
|
17
|
+
|
18
|
+
s.add_dependency "sinatra", ">= 1.2.6"
|
19
|
+
s.add_dependency "redis", ">= 2.2.2"
|
20
|
+
s.add_dependency "eventmachine"
|
21
|
+
s.add_dependency "websocket-rack", "0.4.0"
|
22
|
+
s.add_dependency "em-hiredis", ">= 0.1.1"
|
23
|
+
s.add_dependency "json"
|
24
|
+
s.add_dependency "i18n"
|
25
|
+
s.add_dependency "haml"
|
26
|
+
s.add_dependency "rack"
|
27
|
+
s.add_dependency "rack-test"
|
28
|
+
s.add_dependency "yajl-ruby"
|
29
|
+
s.add_dependency "thin", ">= 1.3.0"
|
30
|
+
s.add_dependency "activesupport"
|
31
|
+
|
32
|
+
s.add_development_dependency "delorean"
|
33
|
+
s.add_development_dependency "rspec", "~> 2.8.0"
|
34
|
+
s.add_development_dependency "shoulda"
|
35
|
+
|
36
|
+
s.files = `git ls-files`.split("\n") - [".gitignore", ".rspec", ".travis.yml"]
|
37
|
+
s.files += ["web/fnordmetric-ui.js", "web/fnordmetric-ui.css", "web/fnordmetric-core.js", "web/fnordmetric-core.css"]
|
38
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
39
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
end
|
data/lib/fnordmetric.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require "eventmachine"
|
2
|
+
require 'em-hiredis'
|
3
|
+
require 'redis'
|
4
|
+
require "active_support/core_ext"
|
5
|
+
require 'yajl'
|
6
|
+
require 'sinatra/base'
|
7
|
+
require 'haml'
|
8
|
+
require 'json'
|
9
|
+
require "thin"
|
10
|
+
require 'rack/server'
|
11
|
+
require 'rack/websocket'
|
12
|
+
|
13
|
+
require "fnordmetric/ext"
|
14
|
+
require "fnordmetric/version"
|
15
|
+
|
16
|
+
module FnordMetric
|
17
|
+
|
18
|
+
@@options = nil
|
19
|
+
@@pool = []
|
20
|
+
|
21
|
+
@@namespaces = {}
|
22
|
+
|
23
|
+
def self.namespace(key=nil, &block)
|
24
|
+
@@namespaces[key] = block
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.namespaces
|
28
|
+
{}.tap do |_namespaces|
|
29
|
+
@@namespaces.each do |key, block|
|
30
|
+
_namespaces[key] = FnordMetric::Namespace.new(key, options.clone)
|
31
|
+
_namespaces[key].instance_eval(&block)
|
32
|
+
_namespaces[key].instance_eval(&FnordMetric::DEFAULT_PROC)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.options(opts = {})
|
38
|
+
default_options(@@options || {}).merge(opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.options=(opts)
|
42
|
+
@@options = opts
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.register(obj)
|
46
|
+
@@pool.push(obj)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.mk_redis
|
50
|
+
Redis.new(:url => options[:redis_url])
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.default_options(opts = {})
|
54
|
+
FnordMetric::DEFAULT_OPTIONS.merge(opts)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.log(msg)
|
58
|
+
puts "[#{Time.now.strftime("%y-%m-%d %H:%M:%S")}] #{msg}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.error(msg)
|
62
|
+
log "[ERROR] #{msg}"; nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.error!(msg)
|
66
|
+
raise msg if ENV['FNORDMETRIC_ENV'] == 'test'
|
67
|
+
puts(msg); exit!
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.run
|
71
|
+
start_em
|
72
|
+
rescue Exception => e
|
73
|
+
raise e
|
74
|
+
log "!!! eventmachine died, restarting... #{e.message}"
|
75
|
+
sleep(1); run
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.shutdown(fnord=nil)
|
79
|
+
log "shutting down, byebye"
|
80
|
+
EM.stop
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.start_em
|
84
|
+
EM.run do
|
85
|
+
|
86
|
+
trap("TERM", &method(:shutdown))
|
87
|
+
trap("INT", &method(:shutdown))
|
88
|
+
|
89
|
+
EM.next_tick do
|
90
|
+
(@@pool || []).map(&:initialized)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.server_configuration=(configuration)
|
97
|
+
puts "DEPRECATION WARNING - FIXPAUL"
|
98
|
+
self.options=(configuration)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.standalone
|
102
|
+
puts "DEPRECATION WARNING - FIXPAUL"
|
103
|
+
require "fnordmetric/standalone"
|
104
|
+
start_em
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
require "fnordmetric/gauge_calculations"
|
110
|
+
require "fnordmetric/gauge_modifiers"
|
111
|
+
require "fnordmetric/gauge_validations"
|
112
|
+
require "fnordmetric/gauge_rendering"
|
113
|
+
require "fnordmetric/gauge"
|
114
|
+
require "fnordmetric/zero_config_gauge"
|
115
|
+
require "fnordmetric/gauges/timeseries_gauge"
|
116
|
+
require "fnordmetric/gauges/toplist_gauge"
|
117
|
+
require "fnordmetric/gauges/distribution_gauge"
|
118
|
+
require "fnordmetric/context"
|
119
|
+
require "fnordmetric/histogram"
|
120
|
+
require "fnordmetric/timeseries"
|
121
|
+
require "fnordmetric/toplist"
|
122
|
+
require "fnordmetric/namespace"
|
123
|
+
require "fnordmetric/session"
|
124
|
+
require "fnordmetric/api"
|
125
|
+
require "fnordmetric/worker"
|
126
|
+
require "fnordmetric/logger"
|
127
|
+
require "fnordmetric/defaults"
|
128
|
+
require "fnordmetric/util"
|
129
|
+
require "fnordmetric/web/web"
|
130
|
+
require "fnordmetric/web/app_helpers"
|
131
|
+
require "fnordmetric/web/app"
|
132
|
+
require "fnordmetric/web/websocket"
|
133
|
+
require "fnordmetric/web/reactor"
|
134
|
+
require "fnordmetric/web/event"
|
135
|
+
require "fnordmetric/web/dashboard"
|
136
|
+
require "fnordmetric/acceptors/acceptor"
|
137
|
+
require "fnordmetric/acceptors/tcp_acceptor"
|
138
|
+
require "fnordmetric/acceptors/udp_acceptor"
|
139
|
+
require "fnordmetric/acceptors/fyrehose_acceptor"
|
140
|
+
require "fnordmetric/acceptors/amqp_acceptor"
|
141
|
+
require "fnordmetric/acceptors/stomp_acceptor"
|
142
|
+
require "fnordmetric/widget"
|
143
|
+
require "fnordmetric/widgets/timeseries_widget"
|
144
|
+
require "fnordmetric/widgets/numbers_widget"
|
145
|
+
require "fnordmetric/widgets/bars_widget"
|
146
|
+
require "fnordmetric/widgets/toplist_widget"
|
147
|
+
require "fnordmetric/widgets/pie_widget"
|
148
|
+
require "fnordmetric/widgets/html_widget"
|
149
|
+
require "fnordmetric/enterprise/compatibility_handler"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class FnordMetric::Acceptor
|
2
|
+
|
3
|
+
def initialize(opts)
|
4
|
+
@opts = opts
|
5
|
+
|
6
|
+
FnordMetric.register(self)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialized
|
10
|
+
inbound_class = if @opts[:protocol] == :udp
|
11
|
+
FnordMetric::UDPAcceptor
|
12
|
+
elsif @opts[:protocol] == :tcp
|
13
|
+
FnordMetric::TCPAcceptor
|
14
|
+
elsif @opts[:protocol] == :fyrehose
|
15
|
+
FnordMetric::FyrehoseAcceptor
|
16
|
+
elsif @opts[:protocol] == :amqp
|
17
|
+
FnordMetric::AMQPAcceptor
|
18
|
+
elsif @opts[:protocol] == :stomp
|
19
|
+
FnordMetric::STOMPAcceptor
|
20
|
+
else
|
21
|
+
raise "unknown protocol: #{@opts[:protocol]}"
|
22
|
+
end
|
23
|
+
|
24
|
+
@opts[:listen] = [
|
25
|
+
@opts[:host] || "0.0.0.0",
|
26
|
+
@opts[:port] || 2323
|
27
|
+
]
|
28
|
+
|
29
|
+
begin
|
30
|
+
inbound_stream = inbound_class.start(@opts)
|
31
|
+
if inbound_class.respond_to?(:outbound?) && inbound_class.outbound?
|
32
|
+
FnordMetric.log "connected to #{@opts[:protocol]}://#{@opts[:listen][0..1].join(":")}"
|
33
|
+
else
|
34
|
+
FnordMetric.log "listening on #{@opts[:protocol]}://#{@opts[:listen][0..1].join(":")}"
|
35
|
+
end
|
36
|
+
rescue Exception => e
|
37
|
+
raise e if ENV["FNORDMETRIC_ENV"] == "dev"
|
38
|
+
FnordMetric.log "cant start #{inbound_class.name} on #{@opts[:protocol]}://#{@opts[:listen][0..1].join(":")}. port in use?"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class FnordMetric::AMQPAcceptor
|
2
|
+
|
3
|
+
def self.start(opts)
|
4
|
+
begin
|
5
|
+
require "amqp"
|
6
|
+
rescue LoadError
|
7
|
+
FnordMetric.error("require 'amqp' failed, you need the amqp gem")
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
new(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(opts)
|
15
|
+
amqp = AMQP.connect(:host => 'firehose')
|
16
|
+
amqp_channel = AMQP::Channel.new(amqp)
|
17
|
+
|
18
|
+
msg_handler = lambda do |channel, data|
|
19
|
+
event = begin
|
20
|
+
JSON.parse(data)
|
21
|
+
rescue
|
22
|
+
FnordMetric.log("[AMQP] received invalid JSON: #{data[0..60]}")
|
23
|
+
end
|
24
|
+
|
25
|
+
if event
|
26
|
+
event["_type"] ||= channel
|
27
|
+
events << event
|
28
|
+
push_next_event
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
opts[:channels].each do |channel|
|
33
|
+
queue = amqp_channel.queue(channel, :auto_delete => true)
|
34
|
+
queue.subscribe{ |data| msg_handler[channel, data] }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def push_next_event
|
39
|
+
return true if events.empty?
|
40
|
+
api.event(@events.pop)
|
41
|
+
EM.next_tick(&method(:push_next_event))
|
42
|
+
end
|
43
|
+
|
44
|
+
def events
|
45
|
+
@events ||= []
|
46
|
+
end
|
47
|
+
|
48
|
+
def api
|
49
|
+
@api ||= FnordMetric::API.new(FnordMetric.options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.outbound?
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class FnordMetric::FyrehoseAcceptor
|
2
|
+
|
3
|
+
def self.start(opts)
|
4
|
+
require "fyrehose"
|
5
|
+
require "fyrehose/reactor"
|
6
|
+
|
7
|
+
new(opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(opts)
|
11
|
+
reactor = EM.connect(opts[:host], opts[:port], Fyrehose::Reactor)
|
12
|
+
|
13
|
+
reactor.on_message do |channel, data|
|
14
|
+
event = JSON.parse(data)
|
15
|
+
event["_type"] ||= channel
|
16
|
+
events << event
|
17
|
+
push_next_event
|
18
|
+
end
|
19
|
+
|
20
|
+
opts[:channels].each do |channel|
|
21
|
+
reactor.subscribe(channel)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def push_next_event
|
26
|
+
return true if events.empty?
|
27
|
+
api.event(@events.pop)
|
28
|
+
EM.next_tick(&method(:push_next_event))
|
29
|
+
end
|
30
|
+
|
31
|
+
def events
|
32
|
+
@events ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
def api
|
36
|
+
@api ||= FnordMetric::API.new(FnordMetric.options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.outboud?
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class FnordMetric::STOMPAcceptor
|
2
|
+
|
3
|
+
def self.start(opts)
|
4
|
+
begin
|
5
|
+
require "stomp"
|
6
|
+
rescue LoadError
|
7
|
+
FnordMetric.error("require 'stomp' failed, you need the stomp gem")
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
new(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(opts)
|
15
|
+
@mutex = Mutex.new
|
16
|
+
|
17
|
+
client = Stomp::Client.new(:hosts => [{
|
18
|
+
:host => opts[:host],
|
19
|
+
:port => opts[:port],
|
20
|
+
:passcode => opts[:password],
|
21
|
+
:login => opts[:username]}])
|
22
|
+
|
23
|
+
msg_handler = lambda do |topic, msg|
|
24
|
+
data = msg.body
|
25
|
+
|
26
|
+
event = begin
|
27
|
+
JSON.parse(data)
|
28
|
+
rescue
|
29
|
+
FnordMetric.log("[STOMP] received invalid JSON: #{data[0..60]}")
|
30
|
+
end
|
31
|
+
|
32
|
+
if event
|
33
|
+
event["_type"] ||= topic.gsub(/^\/topic\//, '')
|
34
|
+
@mutex.synchronize{ events << event }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
opts[:topics].each do |topic|
|
39
|
+
client.subscribe(topic){ |data| msg_handler[topic, data] }
|
40
|
+
end
|
41
|
+
|
42
|
+
Thread.new do
|
43
|
+
client.join
|
44
|
+
end
|
45
|
+
|
46
|
+
EM.next_tick(&method(:push_next_event))
|
47
|
+
end
|
48
|
+
|
49
|
+
def push_next_event
|
50
|
+
nxt = @mutex.synchronize{ events.pop }
|
51
|
+
unless nxt
|
52
|
+
EM::Timer.new(0.01, &method(:push_next_event))
|
53
|
+
return true
|
54
|
+
end
|
55
|
+
api.event(nxt)
|
56
|
+
EM.next_tick(&method(:push_next_event))
|
57
|
+
end
|
58
|
+
|
59
|
+
def events
|
60
|
+
@events ||= []
|
61
|
+
end
|
62
|
+
|
63
|
+
def api
|
64
|
+
@api ||= FnordMetric::API.new(FnordMetric.options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.outbound?
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class FnordMetric::TCPAcceptor < EventMachine::Connection
|
2
|
+
@@opts = nil
|
3
|
+
|
4
|
+
def self.start(opts)
|
5
|
+
@@opts = opts
|
6
|
+
EM.start_server(*(opts[:listen] + [self]))
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.options(opts)
|
10
|
+
@@opts = opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_data(chunk)
|
14
|
+
@buffer << chunk
|
15
|
+
next_event
|
16
|
+
end
|
17
|
+
|
18
|
+
def next_event
|
19
|
+
read_next_event
|
20
|
+
push_next_event
|
21
|
+
end
|
22
|
+
|
23
|
+
def read_next_event
|
24
|
+
while (event = @buffer.slice!(/^(.*)\n/))
|
25
|
+
@events_buffered += 1
|
26
|
+
@events << event
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def push_next_event
|
31
|
+
return true if @events.empty?
|
32
|
+
@events_buffered -= 1
|
33
|
+
api.event(@events.pop)
|
34
|
+
close_connection?
|
35
|
+
EM.next_tick(&method(:push_next_event))
|
36
|
+
end
|
37
|
+
|
38
|
+
def close_connection?
|
39
|
+
#@backend.hangup unless @streaming || (@events_buffered!=0)
|
40
|
+
end
|
41
|
+
|
42
|
+
def post_init
|
43
|
+
@events_buffered = 0
|
44
|
+
@streaming = true
|
45
|
+
@buffer = ""
|
46
|
+
@events = []
|
47
|
+
end
|
48
|
+
|
49
|
+
def unbind
|
50
|
+
@streaming = false
|
51
|
+
close_connection?
|
52
|
+
end
|
53
|
+
|
54
|
+
def api
|
55
|
+
@api ||= FnordMetric::API.new(FnordMetric.options)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|