pulse-meter 0.2.1 → 0.2.2

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.
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