pulse-meter 0.2.11 → 0.3.0
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.
- data/.rbenv-version +1 -1
- data/README.md +32 -16
- data/Rakefile +29 -10
- data/examples/basic.ru +1 -1
- data/examples/full/server.ru +1 -1
- data/examples/minimal/server.ru +1 -1
- data/lib/pulse-meter.rb +1 -0
- data/lib/pulse-meter/observer.rb +117 -0
- data/lib/pulse-meter/sensor.rb +1 -0
- data/lib/pulse-meter/sensor/timeline.rb +3 -2
- data/lib/pulse-meter/sensor/timelined/multi_percentile.rb +43 -0
- data/lib/pulse-meter/version.rb +1 -1
- data/lib/pulse-meter/visualize/app.rb +28 -12
- data/lib/pulse-meter/visualize/coffee/application.coffee +40 -0
- data/lib/pulse-meter/visualize/coffee/collections/page_info_list.coffee +17 -0
- data/lib/pulse-meter/visualize/coffee/collections/sensor_info_list.coffee +4 -0
- data/lib/pulse-meter/visualize/coffee/collections/widget_list.coffee +14 -0
- data/lib/pulse-meter/visualize/coffee/extensions.coffee +26 -0
- data/lib/pulse-meter/visualize/coffee/models/dinamic_widget.coffee +34 -0
- data/lib/pulse-meter/visualize/coffee/models/page_info.coffee +2 -0
- data/lib/pulse-meter/visualize/coffee/models/sensor_info.coffee +2 -0
- data/lib/pulse-meter/visualize/coffee/models/widget.coffee +54 -0
- data/lib/pulse-meter/visualize/coffee/presenters/area.coffee +2 -0
- data/lib/pulse-meter/visualize/coffee/presenters/gauge.coffee +11 -0
- data/lib/pulse-meter/visualize/coffee/presenters/line.coffee +2 -0
- data/lib/pulse-meter/visualize/coffee/presenters/pie.coffee +20 -0
- data/lib/pulse-meter/visualize/coffee/presenters/series.coffee +44 -0
- data/lib/pulse-meter/visualize/coffee/presenters/table.coffee +10 -0
- data/lib/pulse-meter/visualize/coffee/presenters/timeline.coffee +13 -0
- data/lib/pulse-meter/visualize/coffee/presenters/widget.coffee +65 -0
- data/lib/pulse-meter/visualize/coffee/router.coffee +21 -0
- data/lib/pulse-meter/visualize/coffee/views/dynamic_chart.coffee +91 -0
- data/lib/pulse-meter/visualize/coffee/views/dynamic_widget.coffee +58 -0
- data/lib/pulse-meter/visualize/coffee/views/page_title.coffee +17 -0
- data/lib/pulse-meter/visualize/coffee/views/page_titles.coffee +15 -0
- data/lib/pulse-meter/visualize/coffee/views/sensor_info_list.coffee +19 -0
- data/lib/pulse-meter/visualize/coffee/views/widget.coffee +99 -0
- data/lib/pulse-meter/visualize/coffee/views/widget_chart.coffee +13 -0
- data/lib/pulse-meter/visualize/coffee/views/widget_list.coffee +15 -0
- data/lib/pulse-meter/visualize/layout.rb +4 -4
- data/lib/pulse-meter/visualize/public/css/application.css +13 -4
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_75_ffffff_1x400.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-icons_222222_256x240.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-icons_454545_256x240.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-icons_888888_256x240.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/pulse-meter/visualize/public/css/images/ui-icons_f6cf3b_256x240.png +0 -0
- data/lib/pulse-meter/visualize/public/css/jquery-ui-1.8.16.bootstrap.css +1320 -0
- data/lib/pulse-meter/visualize/public/js/application.js +900 -691
- data/lib/pulse-meter/visualize/public/js/jquery-ui-1.8.16.bootstrap.min.js +791 -0
- data/lib/pulse-meter/visualize/public/js/jquery-ui-1.8.23.custom.min.js +21 -0
- data/lib/pulse-meter/visualize/public/js/jquery-ui-timepicker-addon.js +1687 -0
- data/lib/pulse-meter/visualize/sensor.rb +2 -2
- data/lib/pulse-meter/visualize/views/main.haml +2 -3
- data/lib/pulse-meter/visualize/views/sensors.haml +14 -1
- data/lib/pulse-meter/visualize/views/widgets/area.haml +46 -24
- data/lib/pulse-meter/visualize/views/widgets/line.haml +46 -23
- data/lib/pulse-meter/visualize/views/widgets/table.haml +37 -15
- data/lib/pulse-meter/visualize/widgets/timeline.rb +20 -5
- data/pulse-meter.gemspec +4 -0
- data/spec/pulse_meter/observer_spec.rb +252 -0
- data/spec/pulse_meter/sensor/timelined/multi_percentile_spec.rb +21 -0
- data/spec/pulse_meter/visualize/sensor_spec.rb +5 -5
- data/spec/pulse_meter/visualize/widgets/area_spec.rb +1 -74
- data/spec/pulse_meter/visualize/widgets/line_spec.rb +1 -73
- data/spec/pulse_meter/visualize/widgets/table_spec.rb +1 -73
- data/spec/shared_examples/timeline_sensor.rb +10 -0
- data/spec/shared_examples/widget.rb +97 -0
- data/spec/spec_helper.rb +1 -0
- metadata +120 -5
- data/lib/pulse-meter/visualize/public/js/application.coffee +0 -616
data/.rbenv-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.9.
|
|
1
|
+
1.9.3-p125
|
data/README.md
CHANGED
|
@@ -76,10 +76,26 @@ There are several caveats with timeline sensors:
|
|
|
76
76
|
When building a visualisation you may choose to display the last value or not.
|
|
77
77
|
* For some sensors (currently Median and Percentile) considerable amount of data should be stored for a
|
|
78
78
|
particular interval to obtain value for this interval. So it is a good idea to schedule
|
|
79
|
-
|
|
79
|
+
`pulse reduce`
|
|
80
80
|
command on a regular basis. This command reduces the stored data for passed intervals to single values,
|
|
81
81
|
so that they do not consume storage space.
|
|
82
82
|
|
|
83
|
+
|
|
84
|
+
### Observers
|
|
85
|
+
|
|
86
|
+
Observer allows to notify a sensor each time some class or instance method is called
|
|
87
|
+
Suppose you have a user model and want to count users distribytion by name. To do this you have to observe class method `create` of User class:
|
|
88
|
+
|
|
89
|
+
counter = PulseMeter::Sensor::HashedCounter.new :users_by_name
|
|
90
|
+
PulseMeter::Observer.observe_class_method(User, :create, counter) do |execution_time, attrs|
|
|
91
|
+
event({attrs[:name] => 1})
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
Block recieves all execution time and observed method's argements and is executed in context of sensor passed to observer (this means that event method refers to `counter`).
|
|
95
|
+
To observe instance methods use `observe_method`.
|
|
96
|
+
|
|
97
|
+
`unobserve_class_method` and `unobserve_method` remove observations from class or instace method.
|
|
98
|
+
|
|
83
99
|
## Client usage
|
|
84
100
|
|
|
85
101
|
Just create sensor objects and write data. Some examples below.
|
|
@@ -146,7 +162,7 @@ Just create sensor objects and write data. Some examples below.
|
|
|
146
162
|
# 2012-05-24 11:07:00 +0400: 3.0
|
|
147
163
|
# 2012-05-24 11:08:00 +0400: 7.0
|
|
148
164
|
|
|
149
|
-
There is also an alternative and a bit more DRY way for sensor creation, management and usage using
|
|
165
|
+
There is also an alternative and a bit more DRY way for sensor creation, management and usage using `PulseMeter::Sensor::Configuration` class. It is also convenient for creating a bunch of sensors from some configuration data.
|
|
150
166
|
|
|
151
167
|
require 'pulse-meter'
|
|
152
168
|
PulseMeter.redis = Redis.new
|
|
@@ -205,12 +221,12 @@ Just create sensor objects and write data. Some examples below.
|
|
|
205
221
|
|
|
206
222
|
## Command line interface
|
|
207
223
|
|
|
208
|
-
Gem includes a tool
|
|
209
|
-
You should pay attention to the command
|
|
224
|
+
Gem includes a tool `pulse`, which allows to send events to sensors, list them, etc.
|
|
225
|
+
You should pay attention to the command `pulse reduce`, which is generally should be
|
|
210
226
|
scheduled on a regular basis to keep data in Redis small.
|
|
211
227
|
|
|
212
|
-
To see available commands of this tool one can run the example above(see
|
|
213
|
-
and run
|
|
228
|
+
To see available commands of this tool one can run the example above(see `examples/readme_client_example.rb`)
|
|
229
|
+
and run `pulse help`.
|
|
214
230
|
|
|
215
231
|
## Visualisation
|
|
216
232
|
|
|
@@ -225,12 +241,12 @@ There is a minimal and a full example below.
|
|
|
225
241
|
|
|
226
242
|
### Minimal example
|
|
227
243
|
|
|
228
|
-
It can be found in
|
|
229
|
-
|
|
244
|
+
It can be found in `examples/minimal` folder. To run it, execute
|
|
245
|
+
`bundle && cd examples/minimal && bundle exec foreman start` (or just `rake example:minimal`)
|
|
230
246
|
at project root and visit
|
|
231
|
-
|
|
247
|
+
`http://localhost:9292` at your browser.
|
|
232
248
|
|
|
233
|
-
|
|
249
|
+
`client.rb` just creates a timelined counter an sends data to it in an infinite loop.
|
|
234
250
|
|
|
235
251
|
require "pulse-meter"
|
|
236
252
|
|
|
@@ -247,7 +263,7 @@ at project root and visit
|
|
|
247
263
|
sleep(Random.rand)
|
|
248
264
|
end
|
|
249
265
|
|
|
250
|
-
|
|
266
|
+
`server.ru` is a Rackup file creating a simple layout with one page and one widget on it, which displays
|
|
251
267
|
the sensor's data. The layout is converted to a rack application and launched.
|
|
252
268
|
|
|
253
269
|
require "pulse-meter/visualizer"
|
|
@@ -269,19 +285,19 @@ the sensor's data. The layout is converted to a rack application and launched.
|
|
|
269
285
|
|
|
270
286
|
run layout.to_app
|
|
271
287
|
|
|
272
|
-
|
|
288
|
+
`Procfile` allows to launch both "client" script and the web server with `foreman`.
|
|
273
289
|
|
|
274
290
|
web: bundle exec rackup server.ru
|
|
275
291
|
sensor_data_generator: bundle exec ruby client.rb
|
|
276
292
|
|
|
277
293
|
### Full example with DSL explanation
|
|
278
294
|
|
|
279
|
-
It can be found in
|
|
280
|
-
|
|
295
|
+
It can be found in `examples/full` folder. To run it, execute
|
|
296
|
+
`bundle && cd examples/full && bundle exec foreman start` (or just `rake example:full`)
|
|
281
297
|
at project root and visit
|
|
282
|
-
|
|
298
|
+
`http://localhost:9292` at your browser.
|
|
283
299
|
|
|
284
|
-
|
|
300
|
+
`client.rb` imitating users visiting some imaginary site.
|
|
285
301
|
|
|
286
302
|
require "pulse-meter"
|
|
287
303
|
|
data/Rakefile
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
2
|
require 'bundler/gem_tasks'
|
|
3
|
+
require 'coffee-script'
|
|
4
|
+
require 'listen'
|
|
3
5
|
require 'rspec/core/rake_task'
|
|
4
|
-
require
|
|
6
|
+
require 'sprockets'
|
|
7
|
+
require 'tilt'
|
|
8
|
+
require 'yard'
|
|
5
9
|
require 'yard/rake/yardoc_task'
|
|
6
10
|
|
|
7
11
|
RSpec::Core::RakeTask.new(:spec)
|
|
@@ -13,17 +17,32 @@ ROOT = File.dirname(__FILE__)
|
|
|
13
17
|
task :default => :spec
|
|
14
18
|
|
|
15
19
|
namespace :coffee do
|
|
16
|
-
|
|
17
|
-
task :compile do
|
|
18
|
-
system 'coffee', '-c', "#{ROOT}/lib/pulse-meter/visualize/public/"
|
|
19
|
-
puts "Done"
|
|
20
|
-
end
|
|
20
|
+
COFFEE_PATH = "#{ROOT}/lib/pulse-meter/visualize/coffee"
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
def compile_js
|
|
23
|
+
Tilt::CoffeeScriptTemplate.default_bare = true
|
|
24
|
+
env = Sprockets::Environment.new
|
|
25
|
+
env.append_path COFFEE_PATH
|
|
26
|
+
data = env['application.coffee']
|
|
27
|
+
open("#{ROOT}/lib/pulse-meter/visualize/public/js/application.js", "w").write(data)
|
|
28
|
+
puts "application.js compiled"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
desc "Compile coffee to js"
|
|
32
|
+
task :compile do
|
|
33
|
+
compile_js
|
|
34
|
+
end
|
|
26
35
|
|
|
36
|
+
desc "Watch coffee files and recomplile them immediately"
|
|
37
|
+
task :watch do
|
|
38
|
+
Listen.to(COFFEE_PATH) do |modified, added, removed|
|
|
39
|
+
puts "Modified: #{modified}" unless modified.empty?
|
|
40
|
+
puts "Added: #{added}" unless added.empty?
|
|
41
|
+
puts "Removed: #{removed}" unless removed.empty?
|
|
42
|
+
puts "Recompiling..."
|
|
43
|
+
compile_js
|
|
44
|
+
end
|
|
45
|
+
end
|
|
27
46
|
end
|
|
28
47
|
|
|
29
48
|
namespace :yard do
|
data/examples/basic.ru
CHANGED
data/examples/full/server.ru
CHANGED
data/examples/minimal/server.ru
CHANGED
data/lib/pulse-meter.rb
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'pulse-meter'
|
|
2
|
+
|
|
3
|
+
module PulseMeter
|
|
4
|
+
class Observer
|
|
5
|
+
class << self
|
|
6
|
+
# Removes observation from instance method
|
|
7
|
+
# @param klass [Class] class
|
|
8
|
+
# @param method [Symbol] instance method name
|
|
9
|
+
def unobserve_method(klass, method)
|
|
10
|
+
with_observer = method_with_observer(method)
|
|
11
|
+
without_observer = method_without_observer(method)
|
|
12
|
+
|
|
13
|
+
return unless klass.method_defined? with_observer
|
|
14
|
+
klass.class_eval do
|
|
15
|
+
alias_method method, without_observer
|
|
16
|
+
remove_method with_observer
|
|
17
|
+
remove_method without_observer
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Removes observation from class method
|
|
22
|
+
# @param klass [Class] class
|
|
23
|
+
# @param method [Symbol] class method name
|
|
24
|
+
def unobserve_class_method(klass, method)
|
|
25
|
+
with_observer = method_with_observer(method)
|
|
26
|
+
without_observer = method_without_observer(method)
|
|
27
|
+
|
|
28
|
+
return unless klass.respond_to? with_observer
|
|
29
|
+
metaclass(klass).instance_eval do
|
|
30
|
+
alias_method method, without_observer
|
|
31
|
+
remove_method with_observer
|
|
32
|
+
remove_method without_observer
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Registeres an observer for instance method
|
|
37
|
+
# @param klass [Class] class
|
|
38
|
+
# @param method [Symbol] instance method
|
|
39
|
+
# @param sensor [Object] notifications receiver
|
|
40
|
+
# @param proc [Proc] proc to be called in context of receiver each time observed method called
|
|
41
|
+
def observe_method(klass, method, sensor, &proc)
|
|
42
|
+
with_observer = method_with_observer(method)
|
|
43
|
+
without_observer = method_without_observer(method)
|
|
44
|
+
|
|
45
|
+
return if klass.method_defined? with_observer
|
|
46
|
+
|
|
47
|
+
klass.class_eval do
|
|
48
|
+
alias_method without_observer, method
|
|
49
|
+
define_method with_observer do |*args, &block|
|
|
50
|
+
result = nil
|
|
51
|
+
start_time = Time.now
|
|
52
|
+
begin
|
|
53
|
+
result = self.send without_observer, *args, &block
|
|
54
|
+
ensure
|
|
55
|
+
begin
|
|
56
|
+
delta = ((Time.now - start_time) * 1000).to_i
|
|
57
|
+
sensor.instance_exec delta, *args, &proc
|
|
58
|
+
rescue Exception
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
result
|
|
62
|
+
end
|
|
63
|
+
alias_method method, with_observer
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Registeres an observer for class method
|
|
68
|
+
# @param klass [Class] class
|
|
69
|
+
# @param method [Symbol] class method
|
|
70
|
+
# @param sensor [Object] notifications receiver
|
|
71
|
+
# @param proc [Proc] proc to be called in context of receiver each time observed method called
|
|
72
|
+
def observe_class_method(klass, method, sensor, &proc)
|
|
73
|
+
with_observer = method_with_observer(method)
|
|
74
|
+
without_observer = method_without_observer(method)
|
|
75
|
+
|
|
76
|
+
return if klass.respond_to? with_observer
|
|
77
|
+
|
|
78
|
+
metaclass(klass).instance_eval do
|
|
79
|
+
alias_method without_observer, method
|
|
80
|
+
define_method with_observer do |*args, &block|
|
|
81
|
+
result = nil
|
|
82
|
+
start_time = Time.now
|
|
83
|
+
begin
|
|
84
|
+
result = self.send without_observer, *args, &block
|
|
85
|
+
ensure
|
|
86
|
+
begin
|
|
87
|
+
delta = ((Time.now - start_time) * 1000).to_i
|
|
88
|
+
sensor.instance_exec delta, *args, &proc
|
|
89
|
+
rescue Exception
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
result
|
|
93
|
+
end
|
|
94
|
+
alias_method method, with_observer
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def metaclass(klass)
|
|
101
|
+
klass.class_eval do
|
|
102
|
+
class << self
|
|
103
|
+
self
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def method_with_observer(method)
|
|
109
|
+
"#{method}_with_observer"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def method_without_observer(method)
|
|
113
|
+
"#{method}_without_observer"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/pulse-meter/sensor.rb
CHANGED
|
@@ -15,6 +15,7 @@ require 'pulse-meter/sensor/timelined/hashed_indicator'
|
|
|
15
15
|
require 'pulse-meter/sensor/timelined/min'
|
|
16
16
|
require 'pulse-meter/sensor/timelined/max'
|
|
17
17
|
require 'pulse-meter/sensor/timelined/percentile'
|
|
18
|
+
require 'pulse-meter/sensor/timelined/multi_percentile'
|
|
18
19
|
require 'pulse-meter/sensor/timelined/median'
|
|
19
20
|
require 'pulse-meter/sensor/timelined/uniq_counter'
|
|
20
21
|
|
|
@@ -74,8 +74,9 @@ module PulseMeter
|
|
|
74
74
|
interval_data_key = data_key(interval_id)
|
|
75
75
|
multi do
|
|
76
76
|
redis.del(interval_raw_data_key)
|
|
77
|
-
redis.
|
|
78
|
-
|
|
77
|
+
if redis.setnx(interval_data_key, value)
|
|
78
|
+
redis.expire(interval_data_key, ttl)
|
|
79
|
+
end
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module PulseMeter
|
|
2
|
+
module Sensor
|
|
3
|
+
module Timelined
|
|
4
|
+
# Calculates n'th percentile in interval
|
|
5
|
+
class MultiPercentile < Timeline
|
|
6
|
+
attr_reader :p_value
|
|
7
|
+
|
|
8
|
+
def initialize(name, options)
|
|
9
|
+
@p_value = assert_array!(options, :p, [])
|
|
10
|
+
@p_value.each {|p| assert_ranged_float!({:percentile => p}, :percentile, 0, 1)}
|
|
11
|
+
super(name, options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def aggregate_event(key, value)
|
|
15
|
+
redis.zadd(key, value, "#{value}::#{uniqid}")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def summarize(key)
|
|
19
|
+
@p_value.each_with_object({}) do |p, acc|
|
|
20
|
+
count = redis.zcard(key)
|
|
21
|
+
percentile = if count > 0
|
|
22
|
+
position = p > 0 ? (p * count).round - 1 : 0
|
|
23
|
+
el = redis.zrange(key, position, position)[0]
|
|
24
|
+
redis.zscore(key, el)
|
|
25
|
+
else
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
acc[p] = percentile
|
|
29
|
+
end.to_json
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def deflate(value)
|
|
35
|
+
hash = JSON.parse(value)
|
|
36
|
+
hash.each {|p, v| hash[p] = v.to_f}
|
|
37
|
+
hash
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/pulse-meter/version.rb
CHANGED
|
@@ -24,25 +24,35 @@ module PulseMeter
|
|
|
24
24
|
get '/' do
|
|
25
25
|
@title = @layout.title
|
|
26
26
|
gon.pageInfos = camelize_keys(@layout.page_infos)
|
|
27
|
-
|
|
27
|
+
gon.options = camelize_keys(@layout.options)
|
|
28
28
|
haml :main
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
get '/pages/:id/widgets' do
|
|
32
|
+
id = params[:id].to_i
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
content_type :json
|
|
35
35
|
camelize_keys(@layout.widgets(id - 1)).to_json
|
|
36
|
-
|
|
36
|
+
end
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
get '/pages/:page_id/widgets/:id' do
|
|
39
|
+
page_id = params[:page_id].to_i
|
|
40
|
+
id = params[:id].to_i
|
|
41
41
|
timespan = params[:timespan].to_i
|
|
42
|
+
start_time = params[:startTime].to_i
|
|
43
|
+
end_time = params[:endTime].to_i
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
camelize_keys(
|
|
45
|
-
|
|
45
|
+
content_type :json
|
|
46
|
+
camelize_keys(
|
|
47
|
+
@layout.widget(
|
|
48
|
+
page_id - 1,
|
|
49
|
+
id - 1,
|
|
50
|
+
timespan: timespan,
|
|
51
|
+
start_time: start_time,
|
|
52
|
+
end_time: end_time
|
|
53
|
+
)
|
|
54
|
+
).to_json
|
|
55
|
+
end
|
|
46
56
|
|
|
47
57
|
get '/sensors' do
|
|
48
58
|
content_type :json
|
|
@@ -50,9 +60,15 @@ module PulseMeter
|
|
|
50
60
|
end
|
|
51
61
|
|
|
52
62
|
get '/dynamic_widget' do
|
|
63
|
+
start_time = params[:startTime].to_i
|
|
64
|
+
end_time = params[:endTime].to_i
|
|
65
|
+
timespan = params[:timespan].to_i
|
|
66
|
+
|
|
53
67
|
content_type :json
|
|
54
68
|
camelize_keys(@layout.dynamic_widget(
|
|
55
|
-
timespan:
|
|
69
|
+
timespan: timespan,
|
|
70
|
+
start_time: start_time,
|
|
71
|
+
end_time: end_time,
|
|
56
72
|
sensors: params[:sensor],
|
|
57
73
|
type: params[:type])
|
|
58
74
|
).to_json
|