pulse-meter 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/.travis.yml +4 -0
  2. data/examples/basic.ru +23 -5
  3. data/examples/basic_sensor_data.rb +15 -2
  4. data/examples/full/server.ru +2 -3
  5. data/examples/minimal/server.ru +3 -2
  6. data/lib/pulse-meter/sensor.rb +2 -1
  7. data/lib/pulse-meter/sensor/configuration.rb +3 -1
  8. data/lib/pulse-meter/sensor/hashed_indicator.rb +22 -0
  9. data/lib/pulse-meter/sensor/timeline.rb +13 -1
  10. data/lib/pulse-meter/version.rb +1 -1
  11. data/lib/pulse-meter/visualize/app.rb +6 -2
  12. data/lib/pulse-meter/visualize/base.rb +15 -0
  13. data/lib/pulse-meter/visualize/dsl/base.rb +131 -0
  14. data/lib/pulse-meter/visualize/dsl/errors.rb +0 -6
  15. data/lib/pulse-meter/visualize/dsl/layout.rb +12 -41
  16. data/lib/pulse-meter/visualize/dsl/page.rb +15 -41
  17. data/lib/pulse-meter/visualize/dsl/sensor.rb +9 -10
  18. data/lib/pulse-meter/visualize/dsl/widget.rb +18 -65
  19. data/lib/pulse-meter/visualize/dsl/widget_old.rb +95 -0
  20. data/lib/pulse-meter/visualize/dsl/widgets/area.rb +20 -0
  21. data/lib/pulse-meter/visualize/dsl/widgets/gauge.rb +12 -0
  22. data/lib/pulse-meter/visualize/dsl/widgets/line.rb +21 -0
  23. data/lib/pulse-meter/visualize/dsl/widgets/pie.rb +16 -0
  24. data/lib/pulse-meter/visualize/dsl/widgets/table.rb +19 -0
  25. data/lib/pulse-meter/visualize/layout.rb +7 -16
  26. data/lib/pulse-meter/visualize/page.rb +5 -10
  27. data/lib/pulse-meter/visualize/public/favicon.ico +0 -0
  28. data/lib/pulse-meter/visualize/public/js/application.coffee +156 -107
  29. data/lib/pulse-meter/visualize/public/js/application.js +283 -122
  30. data/lib/pulse-meter/visualize/sensor.rb +7 -13
  31. data/lib/pulse-meter/visualize/views/main.haml +8 -52
  32. data/lib/pulse-meter/visualize/views/widgets/area.haml +31 -0
  33. data/lib/pulse-meter/visualize/views/widgets/extend_options.haml +11 -0
  34. data/lib/pulse-meter/visualize/views/widgets/gauge.haml +13 -0
  35. data/lib/pulse-meter/visualize/views/widgets/line.haml +31 -0
  36. data/lib/pulse-meter/visualize/views/widgets/pie.haml +13 -0
  37. data/lib/pulse-meter/visualize/views/widgets/table.haml +23 -0
  38. data/lib/pulse-meter/visualize/widget.rb +17 -87
  39. data/lib/pulse-meter/visualize/widgets/gauge.rb +47 -0
  40. data/lib/pulse-meter/visualize/widgets/pie.rb +36 -0
  41. data/lib/pulse-meter/visualize/widgets/timeline.rb +90 -0
  42. data/lib/pulse-meter/visualizer.rb +18 -8
  43. data/perl/PulseMeter/Sensor/Base.pm +42 -0
  44. data/perl/PulseMeter/Sensor/Counter.pm +19 -0
  45. data/perl/PulseMeter/Sensor/HashedIndicator.pm +12 -0
  46. data/perl/PulseMeter/Sensor/Indicator.pm +17 -0
  47. data/perl/PulseMeter/Sensor/Timeline.pm +51 -0
  48. data/perl/PulseMeter/Sensor/Timelined/Average.pm +13 -0
  49. data/perl/PulseMeter/Sensor/Timelined/Counter.pm +12 -0
  50. data/perl/PulseMeter/Sensor/Timelined/HashedCounter.pm +12 -0
  51. data/perl/PulseMeter/Sensor/Timelined/Max.pm +18 -0
  52. data/perl/PulseMeter/Sensor/Timelined/Median.pm +8 -0
  53. data/perl/PulseMeter/Sensor/Timelined/Min.pm +18 -0
  54. data/perl/PulseMeter/Sensor/Timelined/Percentile.pm +17 -0
  55. data/perl/PulseMeter/Sensor/Timelined/UniqCounter.pm +13 -0
  56. data/perl/PulseMeter/Sensor/UniqCounter.pm +12 -0
  57. data/pulse-meter.gemspec +1 -0
  58. data/spec/pulse_meter/sensor/configuration_spec.rb +10 -2
  59. data/spec/pulse_meter/sensor/hashed_indicator_spec.rb +39 -0
  60. data/spec/pulse_meter/visualize/dsl/layout_spec.rb +8 -8
  61. data/spec/pulse_meter/visualize/dsl/page_spec.rb +29 -42
  62. data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +5 -5
  63. data/spec/pulse_meter/visualize/dsl/widget_spec.rb +1 -122
  64. data/spec/pulse_meter/visualize/dsl/widgets/area_spec.rb +44 -0
  65. data/spec/pulse_meter/visualize/dsl/widgets/gauge_spec.rb +22 -0
  66. data/spec/pulse_meter/visualize/dsl/widgets/line_spec.rb +44 -0
  67. data/spec/pulse_meter/visualize/dsl/widgets/pie_spec.rb +35 -0
  68. data/spec/pulse_meter/visualize/dsl/widgets/table_spec.rb +36 -0
  69. data/spec/pulse_meter/visualize/layout_spec.rb +3 -3
  70. data/spec/pulse_meter/visualize/page_spec.rb +2 -2
  71. data/spec/pulse_meter/visualize/sensor_spec.rb +4 -4
  72. data/spec/pulse_meter/visualize/series_extractor_spec.rb +3 -3
  73. data/spec/pulse_meter/visualize/widgets/area_spec.rb +78 -0
  74. data/spec/pulse_meter/visualize/widgets/gauge_spec.rb +63 -0
  75. data/spec/pulse_meter/visualize/widgets/line_spec.rb +77 -0
  76. data/spec/pulse_meter/visualize/widgets/pie_spec.rb +73 -0
  77. data/spec/pulse_meter/visualize/widgets/table_spec.rb +78 -0
  78. data/spec/shared_examples/dsl_widget.rb +106 -0
  79. data/spec/shared_examples/timeline_sensor.rb +32 -2
  80. metadata +75 -6
  81. data/lib/pulse-meter/visualize/dsl.rb +0 -0
  82. data/spec/pulse_meter/visualize/widget_spec.rb +0 -122
@@ -2,3 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
+ branches:
6
+ only:
7
+ - master
8
+ - develop
@@ -39,11 +39,11 @@ layout = PulseMeter::Visualizer.draw do |l|
39
39
  c.sensor :goose_count
40
40
  end
41
41
 
42
- p.table "Rhino & Lama & Goose count comparison" do |c|
42
+ p.pie "Rhino & Lama & Gooze count comparison" do |c|
43
43
  c.redraw_interval 5
44
44
  c.values_label 'Count'
45
45
  c.width 5
46
- c.show_last_point true
46
+ c.show_last_point false
47
47
  c.timespan 1200
48
48
 
49
49
  c.sensor :rhino_count, color: '#AAAAAA'
@@ -51,11 +51,28 @@ layout = PulseMeter::Visualizer.draw do |l|
51
51
  c.sensor :goose_count
52
52
  end
53
53
 
54
- p.pie "Rhino & Lama & Gooze count comparison" do |c|
54
+ p.gauge "CPU Usage" do |g|
55
+ g.redraw_interval 5
56
+ g.values_label '%'
57
+ g.width 5
58
+
59
+ g.red_from 90
60
+ g.red_to 100
61
+ g.yellow_from 75
62
+ g.yellow_to 90
63
+ g.minor_ticks 5
64
+ g.height 200
65
+
66
+ g.sensor :cpu
67
+ g.sensor :memory
68
+ g.sensor :temperature
69
+ end
70
+
71
+ p.table "Rhino & Lama & Goose count comparison" do |c|
55
72
  c.redraw_interval 5
56
73
  c.values_label 'Count'
57
- c.width 5
58
- c.show_last_point false
74
+ c.width 10
75
+ c.show_last_point true
59
76
  c.timespan 1200
60
77
 
61
78
  c.sensor :rhino_count, color: '#AAAAAA'
@@ -63,6 +80,7 @@ layout = PulseMeter::Visualizer.draw do |l|
63
80
  c.sensor :goose_count
64
81
  end
65
82
 
83
+
66
84
  end
67
85
 
68
86
  l.page "Ages" do |p|
@@ -48,6 +48,15 @@ cfg = PulseMeter::Sensor::Configuration.new(
48
48
  interval: 20,
49
49
  ttl: 3600
50
50
  }
51
+ },
52
+
53
+ cpu: {sensor_type: 'indicator'},
54
+ memory: {sensor_type: 'indicator'},
55
+ temperature: {
56
+ sensor_type: 'hashed_indicator',
57
+ args: {
58
+ annotation: 'T'
59
+ }
51
60
  }
52
61
  )
53
62
 
@@ -61,6 +70,10 @@ while true
61
70
 
62
71
  10.times do
63
72
  goose_n = Random.rand(4)
64
- cfg.goose_count("goose_#{goose_n}" => 1)
73
+ cfg.goose_count("g_#{goose_n}" => 1)
74
+ cfg.temperature("g_#{goose_n}" => Random.rand(50))
65
75
  end
66
- end
76
+
77
+ cfg.cpu(Random.rand(100))
78
+ cfg.memory(Random.rand(100))
79
+ end
@@ -14,7 +14,7 @@ layout = PulseMeter::Visualizer.draw do |l|
14
14
 
15
15
  # Transfer some global parameters to Google Charts
16
16
  l.gchart_options({
17
- backgroundColor: '#CCC'
17
+ background_color: '#CCC'
18
18
  })
19
19
 
20
20
  # Add some pages
@@ -87,7 +87,6 @@ layout = PulseMeter::Visualizer.draw do |l|
87
87
  w.sensor sensor
88
88
  end
89
89
 
90
- w.timespan 24 * 60 * 60
91
90
  w.redraw_interval 10
92
91
  w.show_last_point true
93
92
  w.values_label "Request count"
@@ -102,4 +101,4 @@ layout = PulseMeter::Visualizer.draw do |l|
102
101
 
103
102
  end
104
103
 
105
- run layout.to_app
104
+ run layout.to_app
@@ -12,9 +12,10 @@ layout = PulseMeter::Visualizer.draw do |l|
12
12
  p.area "Live Counter",
13
13
  sensor: :simple_sample_counter,
14
14
  timespan: 5 * 60,
15
- redraw_interval: 1
15
+ redraw_interval: 1,
16
+ width: 10
16
17
  end
17
18
 
18
19
  end
19
20
 
20
- run layout.to_app
21
+ run layout.to_app
@@ -1,7 +1,8 @@
1
1
  require 'pulse-meter/sensor/base'
2
2
  require 'pulse-meter/sensor/counter'
3
- require 'pulse-meter/sensor/hashed_counter'
4
3
  require 'pulse-meter/sensor/indicator'
4
+ require 'pulse-meter/sensor/hashed_counter'
5
+ require 'pulse-meter/sensor/hashed_indicator'
5
6
  require 'pulse-meter/sensor/remote'
6
7
  require 'pulse-meter/sensor/uniq_counter'
7
8
  require 'pulse-meter/sensor/timeline'
@@ -27,6 +27,8 @@ module PulseMeter
27
27
  name = name.to_s
28
28
  if @sensors.has_key?(name)
29
29
  @sensors[name].event(*args)
30
+ elsif (name =~ /^(.*)_at$/) && @sensors.has_key?($1)
31
+ @sensors[$1].event_at(*args)
30
32
  else
31
33
  raise ArgumentError, "Unknown sensor: `#{name}'"
32
34
  end
@@ -44,4 +46,4 @@ module PulseMeter
44
46
 
45
47
  end
46
48
  end
47
- end
49
+ end
@@ -0,0 +1,22 @@
1
+ module PulseMeter
2
+ module Sensor
3
+ # Static hashed indicator. In fact is is just a named hash with float value
4
+ class HashedIndicator < Indicator
5
+
6
+ # Sets indicator values
7
+ # @param value [Hash] new indicator values
8
+ def event(events)
9
+ events.each_pair {|name, value| redis.hset(value_key, name, value.to_f)}
10
+ end
11
+
12
+ # Get indicator values
13
+ # @return [Fixnum] indicator value or zero unless it was initialized
14
+ def value
15
+ redis.
16
+ hgetall(value_key).
17
+ inject(Hash.new(0)) {|h, (k, v)| h[k] = v.to_f; h}
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -49,6 +49,7 @@ module PulseMeter
49
49
  end
50
50
 
51
51
  # Processes event
52
+ # @param value event value
52
53
  def event(value = nil)
53
54
  multi do
54
55
  current_key = current_raw_data_key
@@ -57,7 +58,18 @@ module PulseMeter
57
58
  end
58
59
  end
59
60
 
60
-
61
+ # Processes event from the past
62
+ # @param time [Time] event time
63
+ # @param value event value
64
+ def event_at(time, value = nil)
65
+ multi do
66
+ interval_id = get_interval_id(time)
67
+ key = raw_data_key(interval_id)
68
+ aggregate_event(key, value)
69
+ redis.expire(key, raw_data_ttl)
70
+ end
71
+ end
72
+
61
73
  # Reduces data in given interval.
62
74
  # @note Interval id is
63
75
  # just unixtime of its lower bound. Ruduction is a process
@@ -1,3 +1,3 @@
1
1
  module PulseMeter
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -1,12 +1,16 @@
1
- require 'sinatra/base'
2
- require 'haml'
3
1
  require 'gon-sinatra'
2
+ require 'haml'
3
+ require 'sinatra/base'
4
+ require 'sinatra/partial'
4
5
 
5
6
  module PulseMeter
6
7
  module Visualize
7
8
  class App < Sinatra::Base
8
9
  include PulseMeter::Mixins::Utils
9
10
  register Gon::Sinatra
11
+ register Sinatra::Partial
12
+
13
+ set :partial_template_engine, :haml
10
14
 
11
15
  def initialize(layout)
12
16
  @layout = layout
@@ -0,0 +1,15 @@
1
+ module PulseMeter
2
+ module Visualize
3
+ class Base
4
+ def initialize(opts)
5
+ @opts = opts
6
+ end
7
+
8
+ def method_missing(name, *args)
9
+ @opts[name.to_sym]
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+
@@ -0,0 +1,131 @@
1
+ module PulseMeter
2
+ module Visualize
3
+ module DSL
4
+ class DArray < Array; end
5
+ class BadDataClass < PulseMeter::Visualize::DSL::Error; end
6
+ class Base
7
+ include PulseMeter::Mixins::Utils
8
+
9
+ def initialize
10
+ @opts = {}
11
+ end
12
+
13
+ def process_args(args)
14
+ args.each_pair do |k, v|
15
+ send(k, v)
16
+ end
17
+ end
18
+
19
+ class << self
20
+
21
+ def deprecated_setter(name)
22
+ define_method(name) do |*args|
23
+ STDERR.puts "DEPRECATION: #{name} DSL helper does not take any effect anymore."
24
+ end
25
+ end
26
+
27
+ def setter(name, &block)
28
+ define_method(name) do |val|
29
+ block.call(val) if block
30
+ @opts[name] = val
31
+ end
32
+ end
33
+
34
+ def bool_setter(name)
35
+ define_method(name) do |val|
36
+ @opts[name] = !!val
37
+ end
38
+ end
39
+
40
+ def string_setter(name, &block)
41
+ define_method(name) do |val|
42
+ val = val.to_s
43
+ block.call(val) if block
44
+ @opts[name] = val
45
+ end
46
+ end
47
+
48
+ def int_setter(name, &block)
49
+ define_method(name) do |val|
50
+ val = val.to_i
51
+ block.call(val) if block
52
+ @opts[name] = val
53
+ end
54
+ end
55
+
56
+ def hash_extender(name, &block)
57
+ define_method(name) do |val|
58
+ @opts[name] ||= {}
59
+ @opts[name].merge!(val)
60
+ end
61
+ end
62
+
63
+ def array_extender(name, &block)
64
+ define_method(name) do |val|
65
+ @opts[name] ||=[]
66
+ block.call(val) if block
67
+ @opts[name] << val
68
+ end
69
+ end
70
+
71
+ def dsl_setter(name, klass)
72
+ define_method(name) do |*args, &block|
73
+ @opts[name] = create_dsl_obj(args, klass, block)
74
+ end
75
+ end
76
+
77
+ def dsl_array_extender(collection_name, name, klass)
78
+ define_method(name) do |*args, &block|
79
+ @opts[collection_name] ||= DArray.new
80
+ @opts[collection_name] << create_dsl_obj(args, klass, block)
81
+ end
82
+ end
83
+
84
+ def data_class
85
+ @data_class || PulseMeter::Visualize::Base
86
+ end
87
+
88
+ def data_class=(klass)
89
+ raise BadDataClass unless klass.is_a?(Class) && klass <= PulseMeter::Visualize::Base
90
+ @data_class = klass
91
+ end
92
+
93
+ end
94
+
95
+ def create_dsl_obj(args, klass, block)
96
+ params, options = extract_params(args)
97
+ dsl_obj = klass.new(*params)
98
+ dsl_obj.process_args(options)
99
+ block.call(dsl_obj) if block
100
+ dsl_obj
101
+ end
102
+
103
+ def extract_params(args)
104
+ opts = if args.last.is_a?(Hash)
105
+ args.pop
106
+ else
107
+ {}
108
+ end
109
+ [args, opts]
110
+ end
111
+
112
+ def to_data
113
+ klass = self.class.data_class
114
+ args = @opts.each_with_object({}) do |(k, v), acc|
115
+ acc[k] = case v
116
+ when PulseMeter::Visualize::DSL::Base
117
+ v.to_data
118
+ when DArray
119
+ v.map(&:to_data)
120
+ else
121
+ v
122
+ end
123
+ end
124
+ klass.new(args)
125
+ end
126
+
127
+ end
128
+ end
129
+ end
130
+ end
131
+
@@ -17,12 +17,6 @@ module PulseMeter
17
17
  end
18
18
  end
19
19
 
20
- class BadWidgetType < Error
21
- def initialize(type)
22
- super("Bad widget type: `#{type}'")
23
- end
24
- end
25
-
26
20
  class BadWidgetWidth < Error
27
21
  def initialize(width)
28
22
  super("Bad widget width: `#{width}'")
@@ -1,54 +1,25 @@
1
1
  module PulseMeter
2
2
  module Visualize
3
3
  module DSL
4
- class Layout
4
+ class Layout < Base
5
5
  DEFAULT_TITLE = "Pulse Meter"
6
- DEFAULT_GCHART_OPTIONS = {}
7
6
 
8
- def initialize
9
- @pages = []
10
- @title = DEFAULT_TITLE
11
- @use_utc = true
12
- @gchart_options = DEFAULT_GCHART_OPTIONS.dup
13
- end
14
-
15
- def title(title)
16
- @title = title
17
- end
7
+ self.data_class = PulseMeter::Visualize::Layout
18
8
 
19
- def use_utc(use = true)
20
- @use_utc = use
21
- end
22
-
23
- def outlier_color(_)
24
- STDERR.puts "DEPRECATION: outlier_color DSL helper does not take effect anymore"
25
- end
26
-
27
- def highchart_options(_)
28
- STDERR.puts "DEPRECATION: highchart_options DSL helper does not take effect anymore, use gchart_options instead"
29
- end
30
-
31
- def gchart_options(options = {})
32
- @gchart_options.merge!(options)
9
+ def initialize
10
+ super()
11
+ self.title(DEFAULT_TITLE)
12
+ self.use_utc(false)
33
13
  end
34
14
 
35
- def page(title, &block)
36
- page = PulseMeter::Visualize::DSL::Page.new(title)
37
- yield(page)
38
- @pages << page
39
- end
15
+ string_setter :title
16
+ bool_setter :use_utc
17
+ hash_extender :gchart_options
40
18
 
41
- def to_layout
42
- pages = @pages.map(&:to_page)
43
- title = @title || ''
44
- PulseMeter::Visualize::Layout.new( {
45
- pages: pages,
46
- title: title,
47
- use_utc: @use_utc,
48
- gchart_options: @gchart_options
49
- } )
50
- end
19
+ deprecated_setter :outlier_color
20
+ deprecated_setter :highchart_options
51
21
 
22
+ dsl_array_extender :pages, :page, PulseMeter::Visualize::DSL::Page
52
23
  end
53
24
  end
54
25
  end