fnordmetric 0.7.5 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/V1.0-ROADMAP +97 -0
- data/doc/full_example.rb +95 -511
- data/doc/legacy_example.rb +640 -0
- data/doc/minimal_example.rb +26 -0
- data/doc/preview3.png +0 -0
- data/fnordmetric.gemspec +3 -2
- data/lib/fnordmetric/acceptors/acceptor.rb +29 -0
- data/lib/fnordmetric/{inbound_stream.rb → acceptors/tcp_acceptor.rb} +8 -5
- data/lib/fnordmetric/{inbound_datagram.rb → acceptors/udp_acceptor.rb} +9 -8
- data/lib/fnordmetric/api.rb +2 -2
- data/lib/fnordmetric/context.rb +37 -18
- data/lib/fnordmetric/defaults.rb +9 -0
- data/lib/fnordmetric/ext.rb +72 -0
- data/lib/fnordmetric/gauge.rb +37 -10
- data/lib/fnordmetric/gauge_calculations.rb +38 -16
- data/lib/fnordmetric/gauge_modifiers.rb +67 -0
- data/lib/fnordmetric/gauge_rendering.rb +40 -0
- data/lib/fnordmetric/gauge_validations.rb +15 -0
- data/lib/fnordmetric/gauges/distribution_gauge.rb +85 -0
- data/lib/fnordmetric/gauges/timeseries_gauge.rb +143 -0
- data/lib/fnordmetric/gauges/toplist_gauge.rb +44 -0
- data/lib/fnordmetric/histogram.rb +57 -0
- data/lib/fnordmetric/logger.rb +42 -36
- data/lib/fnordmetric/namespace.rb +47 -23
- data/lib/fnordmetric/session.rb +6 -6
- data/lib/fnordmetric/standalone.rb +15 -35
- data/lib/fnordmetric/timeseries.rb +79 -0
- data/lib/fnordmetric/toplist.rb +61 -0
- data/lib/fnordmetric/version.rb +1 -1
- data/lib/fnordmetric/web/app.rb +122 -0
- data/lib/fnordmetric/web/app_helpers.rb +42 -0
- data/lib/fnordmetric/{dashboard.rb → web/dashboard.rb} +4 -0
- data/lib/fnordmetric/{event.rb → web/event.rb} +7 -2
- data/lib/fnordmetric/web/reactor.rb +87 -0
- data/lib/fnordmetric/web/web.rb +53 -0
- data/lib/fnordmetric/web/websocket.rb +38 -0
- data/lib/fnordmetric/widgets/bars_widget.rb +44 -0
- data/lib/fnordmetric/{html_widget.rb → widgets/html_widget.rb} +0 -0
- data/lib/fnordmetric/widgets/numbers_widget.rb +56 -0
- data/lib/fnordmetric/{pie_widget.rb → widgets/pie_widget.rb} +0 -0
- data/lib/fnordmetric/widgets/timeseries_widget.rb +55 -0
- data/lib/fnordmetric/widgets/toplist_widget.rb +64 -0
- data/lib/fnordmetric/worker.rb +26 -25
- data/lib/fnordmetric.rb +85 -115
- data/readme.md +362 -0
- data/spec/gauge_like_shared.rb +54 -0
- data/spec/gauge_spec.rb +2 -36
- data/spec/namespace_spec.rb +25 -11
- data/spec/spec_helper.rb +4 -0
- data/spec/{inbound_stream_spec.rb → tcp_acceptor_spec.rb} +3 -3
- data/spec/timeseries_gauge_spec.rb +54 -0
- data/spec/{inbound_datagram_spec.rb → udp_acceptor_spec.rb} +3 -3
- data/web/fnordmetric.css +786 -0
- data/web/haml/app.haml +38 -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_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_view.js +260 -0
- data/web/js/fnordmetric.html_widget.js +21 -0
- data/web/js/fnordmetric.js +255 -0
- data/web/js/fnordmetric.numbers_widget.js +121 -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 +343 -0
- data/web/js/fnordmetric.timeline_widget.js +333 -0
- data/web/js/fnordmetric.timeseries_widget.js +388 -0
- data/web/js/fnordmetric.toplist_widget.js +112 -0
- data/web/js/fnordmetric.ui.js +91 -0
- data/web/js/fnordmetric.util.js +244 -0
- data/{pub → web}/loader.gif +0 -0
- data/web/vendor/d3.v2.js +9382 -0
- data/web/vendor/font-awesome/css/font-awesome.css +239 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.eot +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svg +175 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svgz +0 -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 +413 -0
- data/web/vendor/jquery.maskedinput.js +252 -0
- data/web/vendor/rickshaw.css +286 -0
- data/web/vendor/rickshaw.fnordmetric.js +2676 -0
- metadata +129 -79
- data/Gemfile +0 -6
- data/README.md +0 -404
- data/Rakefile +0 -6
- data/doc/version +0 -1
- data/haml/app.haml +0 -79
- data/haml/widget.haml +0 -9
- data/lib/fnordmetric/app.rb +0 -163
- data/lib/fnordmetric/average_metric.rb +0 -7
- data/lib/fnordmetric/bars_widget.rb +0 -26
- data/lib/fnordmetric/combine_metric.rb +0 -7
- data/lib/fnordmetric/count_metric.rb +0 -13
- data/lib/fnordmetric/funnel_widget.rb +0 -2
- data/lib/fnordmetric/metric.rb +0 -80
- data/lib/fnordmetric/metric_api.rb +0 -37
- data/lib/fnordmetric/numbers_widget.rb +0 -26
- data/lib/fnordmetric/report.rb +0 -29
- data/lib/fnordmetric/sum_metric.rb +0 -13
- data/lib/fnordmetric/timeline_widget.rb +0 -30
- data/lib/fnordmetric/toplist_widget.rb +0 -25
- data/pub/fnordmetric.css +0 -145
- data/pub/fnordmetric.js +0 -1179
- data/pub/vendor/highcharts.js +0 -170
- data/pub/vendor/jquery-1.6.1.min.js +0 -18
data/lib/fnordmetric/worker.rb
CHANGED
@@ -1,44 +1,39 @@
|
|
1
1
|
class FnordMetric::Worker
|
2
2
|
|
3
|
-
def initialize
|
4
|
-
@namespaces =
|
5
|
-
@opts =
|
6
|
-
configure(namespaces)
|
7
|
-
end
|
3
|
+
def initialize
|
4
|
+
@namespaces = FnordMetric.namespaces
|
5
|
+
@opts = FnordMetric.options
|
8
6
|
|
9
|
-
|
10
|
-
@redis = EM::Hiredis.connect(@opts[:redis_url])
|
11
|
-
tick
|
7
|
+
FnordMetric.register(self)
|
12
8
|
end
|
13
9
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
@namespaces[key].instance_eval(&block)
|
18
|
-
end
|
10
|
+
def initialized
|
11
|
+
FnordMetric.log("worker started")
|
12
|
+
EM.next_tick(&method(:tick))
|
19
13
|
end
|
20
14
|
|
21
15
|
def tick
|
22
|
-
|
16
|
+
redis.blpop(queue_key, 1).callback do |list, event_id|
|
23
17
|
EM.next_tick(&method(:tick))
|
24
18
|
if event_id
|
25
|
-
|
26
|
-
process_event(event_id, event_data) if event_data
|
19
|
+
redis.get(event_key(event_id)).callback do |event_data|
|
20
|
+
process_event(event_id, event_data) if event_data
|
27
21
|
FnordMetric.log("event_lost: event_data not found for event-id '#{event_id}' - maybe expired?") unless event_data
|
28
|
-
|
22
|
+
redis.hincrby(stats_key, :events_processed, 1)
|
29
23
|
end
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
33
27
|
|
34
28
|
def process_event(event_id, event_data)
|
35
|
-
EM.
|
36
|
-
parse_json(event_data)
|
29
|
+
EM.next_tick do
|
30
|
+
event = parse_json(event_data)
|
31
|
+
if event
|
37
32
|
event[:_time] ||= Time.now.to_i
|
38
33
|
event[:_eid] = event_id
|
39
34
|
announce_event(event)
|
40
|
-
publish_event(event)
|
41
|
-
expire_event(event_id)
|
35
|
+
publish_event(event)
|
36
|
+
expire_event(event_id)
|
42
37
|
end
|
43
38
|
end
|
44
39
|
end
|
@@ -59,16 +54,16 @@ class FnordMetric::Worker
|
|
59
54
|
[@opts[:redis_prefix], 'stats'].join("-")
|
60
55
|
end
|
61
56
|
|
62
|
-
def announce_event(event)
|
63
|
-
namespace(event[:_namespace]).ready!(
|
57
|
+
def announce_event(event)
|
58
|
+
namespace(event[:_namespace]).ready!(redis).announce(event)
|
64
59
|
end
|
65
60
|
|
66
61
|
def expire_event(event_id)
|
67
|
-
|
62
|
+
redis.expire(event_key(event_id), @opts[:event_data_ttl])
|
68
63
|
end
|
69
64
|
|
70
65
|
def publish_event(event)
|
71
|
-
|
66
|
+
redis.publish(pubsub_key, event.to_json)
|
72
67
|
end
|
73
68
|
|
74
69
|
def namespace(key)
|
@@ -79,6 +74,12 @@ class FnordMetric::Worker
|
|
79
74
|
event = Yajl::Parser.new(:symbolize_keys => true).parse(data)
|
80
75
|
event[:_namespace] = event[:_namespace].to_sym if event[:_namespace]
|
81
76
|
event
|
77
|
+
rescue Yajl::ParseError => e
|
78
|
+
FnordMetric.error "invalid json: #{e.to_s}"; false
|
79
|
+
end
|
80
|
+
|
81
|
+
def redis
|
82
|
+
@redis ||= EM::Hiredis.connect(FnordMetric.options[:redis_url]) # FIXPAUL
|
82
83
|
end
|
83
84
|
|
84
85
|
end
|
data/lib/fnordmetric.rb
CHANGED
@@ -5,22 +5,52 @@ require "active_support/core_ext"
|
|
5
5
|
require 'yajl'
|
6
6
|
require 'sinatra/base'
|
7
7
|
require 'haml'
|
8
|
+
require 'json'
|
9
|
+
require "thin"
|
8
10
|
require 'rack/server'
|
11
|
+
require 'rack/websocket'
|
9
12
|
|
10
13
|
require "fnordmetric/ext"
|
11
14
|
require "fnordmetric/version"
|
12
15
|
|
13
16
|
module FnordMetric
|
14
17
|
|
18
|
+
@@options = nil
|
19
|
+
@@pool = []
|
20
|
+
|
15
21
|
@@namespaces = {}
|
16
|
-
@@server_configuration = nil
|
17
22
|
|
18
23
|
def self.namespace(key=nil, &block)
|
19
24
|
@@namespaces[key] = block
|
20
25
|
end
|
21
26
|
|
22
|
-
def self.
|
23
|
-
|
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
|
+
host, port = options[:redis_url].gsub("redis://", "").split(":")
|
51
|
+
redis_opts = { :host => host }
|
52
|
+
redis_opts.merge!(:port => port) if port
|
53
|
+
Redis.new(redis_opts)
|
24
54
|
end
|
25
55
|
|
26
56
|
def self.default_options(opts = {})
|
@@ -39,37 +69,14 @@ module FnordMetric
|
|
39
69
|
}.merge(opts)
|
40
70
|
end
|
41
71
|
|
42
|
-
def self.options(opts = {})
|
43
|
-
default_options(@@server_configuration || {}).merge(opts)
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.start_em(opts = {})
|
47
|
-
EM.run do
|
48
|
-
|
49
|
-
trap("TERM", &method(:shutdown))
|
50
|
-
trap("INT", &method(:shutdown))
|
51
|
-
|
52
|
-
opts = options(opts)
|
53
|
-
app = embedded(opts)
|
54
|
-
|
55
|
-
if opts[:web_interface]
|
56
|
-
server = opts[:web_interface_server].downcase
|
57
|
-
unless ["thin", "hatetepe"].include? server
|
58
|
-
raise "Need an EventMachine webserver, but #{server} isn't"
|
59
|
-
end
|
60
|
-
|
61
|
-
host, port = *opts[:web_interface]
|
62
|
-
Rack::Server.start :app => app, :server => server,
|
63
|
-
:Host => host, :Port => port
|
64
|
-
log "listening on http://#{host}:#{port}"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
72
|
def self.log(msg)
|
70
73
|
puts "[#{Time.now.strftime("%y-%m-%d %H:%M:%S")}] #{msg}"
|
71
74
|
end
|
72
75
|
|
76
|
+
def self.error(msg)
|
77
|
+
log "[ERROR] #{msg}"; nil
|
78
|
+
end
|
79
|
+
|
73
80
|
def self.error!(msg)
|
74
81
|
raise msg if ENV['FNORDMETRIC_ENV'] == 'test'
|
75
82
|
puts(msg); exit!
|
@@ -83,106 +90,69 @@ module FnordMetric
|
|
83
90
|
sleep(1); run
|
84
91
|
end
|
85
92
|
|
86
|
-
def self.shutdown
|
93
|
+
def self.shutdown(fnord=nil)
|
87
94
|
log "shutting down, byebye"
|
88
95
|
EM.stop
|
89
96
|
end
|
90
97
|
|
91
|
-
def self.
|
92
|
-
EM
|
93
|
-
end
|
98
|
+
def self.start_em
|
99
|
+
EM.run do
|
94
100
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
log "#{data_human.join(", ")}, queue_length: #{queue_length}"
|
101
|
+
trap("TERM", &method(:shutdown))
|
102
|
+
trap("INT", &method(:shutdown))
|
103
|
+
|
104
|
+
EM.next_tick do
|
105
|
+
(@@pool || []).map(&:initialized)
|
101
106
|
end
|
107
|
+
|
102
108
|
end
|
103
109
|
end
|
104
110
|
|
105
|
-
def self.
|
106
|
-
|
107
|
-
|
111
|
+
def self.server_configuration=(configuration)
|
112
|
+
puts "DEPRECATION WARNING - FIXPAUL"
|
113
|
+
self.options=(configuration)
|
108
114
|
end
|
109
115
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
def self.embedded(opts={})
|
115
|
-
opts = options(opts)
|
116
|
-
app = nil
|
117
|
-
|
118
|
-
if opts[:rack_app] or opts[:web_interface]
|
119
|
-
app = FnordMetric::App.new(@@namespaces.clone, opts)
|
120
|
-
end
|
121
|
-
|
122
|
-
EM.next_tick do
|
123
|
-
if opts[:start_worker]
|
124
|
-
worker = Worker.new(@@namespaces.clone, opts)
|
125
|
-
worker.ready!
|
126
|
-
end
|
127
|
-
|
128
|
-
if opts[:inbound_stream]
|
129
|
-
inbound_class = opts[:inbound_protocol] == :udp ? InboundDatagram : InboundStream
|
130
|
-
begin
|
131
|
-
inbound_stream = inbound_class.start(opts)
|
132
|
-
log "listening on #{opts[:inbound_protocol]}##{opts[:inbound_stream].join(":")}"
|
133
|
-
rescue
|
134
|
-
log "cant start #{inbound_class.name}. port in use?"
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
if opts[:print_stats]
|
139
|
-
redis = connect_redis(opts[:redis_url])
|
140
|
-
EM::PeriodicTimer.new(opts[:print_stats]) do
|
141
|
-
print_stats(opts, redis)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
app
|
116
|
+
def self.standalone
|
117
|
+
puts "DEPRECATION WARNING - FIXPAUL"
|
118
|
+
require "fnordmetric/standalone"
|
119
|
+
start_em
|
147
120
|
end
|
148
121
|
|
149
122
|
end
|
150
123
|
|
151
|
-
require "fnordmetric/api"
|
152
|
-
require "fnordmetric/udp_client"
|
153
|
-
require "fnordmetric/inbound_stream"
|
154
|
-
require "fnordmetric/inbound_datagram"
|
155
|
-
require "fnordmetric/worker"
|
156
|
-
require "fnordmetric/widget"
|
157
|
-
require "fnordmetric/timeline_widget"
|
158
|
-
require "fnordmetric/numbers_widget"
|
159
|
-
require "fnordmetric/bars_widget"
|
160
|
-
require "fnordmetric/toplist_widget"
|
161
|
-
require "fnordmetric/pie_widget"
|
162
|
-
require "fnordmetric/html_widget"
|
163
|
-
require "fnordmetric/namespace"
|
164
|
-
require "fnordmetric/gauge_modifiers"
|
165
124
|
require "fnordmetric/gauge_calculations"
|
166
|
-
require "fnordmetric/
|
125
|
+
require "fnordmetric/gauge_modifiers"
|
126
|
+
require "fnordmetric/gauge_validations"
|
127
|
+
require "fnordmetric/gauge_rendering"
|
167
128
|
require "fnordmetric/gauge"
|
129
|
+
require "fnordmetric/gauges/timeseries_gauge"
|
130
|
+
require "fnordmetric/gauges/toplist_gauge"
|
131
|
+
require "fnordmetric/gauges/distribution_gauge"
|
132
|
+
require "fnordmetric/context"
|
133
|
+
require "fnordmetric/histogram"
|
134
|
+
require "fnordmetric/timeseries"
|
135
|
+
require "fnordmetric/toplist"
|
136
|
+
require "fnordmetric/namespace"
|
168
137
|
require "fnordmetric/session"
|
169
|
-
require "fnordmetric/
|
170
|
-
require "fnordmetric/
|
171
|
-
require "fnordmetric/
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
138
|
+
require "fnordmetric/api"
|
139
|
+
require "fnordmetric/worker"
|
140
|
+
require "fnordmetric/logger"
|
141
|
+
require "fnordmetric/defaults"
|
142
|
+
require "fnordmetric/web/web"
|
143
|
+
require "fnordmetric/web/app_helpers"
|
144
|
+
require "fnordmetric/web/app"
|
145
|
+
require "fnordmetric/web/websocket"
|
146
|
+
require "fnordmetric/web/reactor"
|
147
|
+
require "fnordmetric/web/event"
|
148
|
+
require "fnordmetric/web/dashboard"
|
149
|
+
require "fnordmetric/acceptors/acceptor"
|
150
|
+
require "fnordmetric/acceptors/tcp_acceptor"
|
151
|
+
require "fnordmetric/acceptors/udp_acceptor"
|
152
|
+
require "fnordmetric/widget"
|
153
|
+
require "fnordmetric/widgets/timeseries_widget"
|
154
|
+
require "fnordmetric/widgets/numbers_widget"
|
155
|
+
require "fnordmetric/widgets/bars_widget"
|
156
|
+
require "fnordmetric/widgets/toplist_widget"
|
157
|
+
require "fnordmetric/widgets/pie_widget"
|
158
|
+
require "fnordmetric/widgets/html_widget"
|