pulse-meter 0.4.8 → 0.4.9

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -32,11 +32,13 @@ can be updated through client side objects associated with this data. The semant
32
32
  different: some counter, value, series of values, etc. There is no need to care about explicit creation this data:
33
33
  one just creates a client object and writes data to it, e.g.
34
34
 
35
- PulseMeter.redis = Redis.new
36
- sensor = PulseMeter::Sensor::Counter.new :my_counter
37
- sensor.event(5)
38
- ...
39
- sensor.event(3)
35
+ ```ruby
36
+ PulseMeter.redis = Redis.new
37
+ sensor = PulseMeter::Sensor::Counter.new :my_counter
38
+ sensor.event(5)
39
+ ...
40
+ sensor.event(3)
41
+ ```
40
42
 
41
43
  After that the value associated with the counter is immediately available (through CLI, for example). Any other
42
44
  client can access the associated counter by creating object with the same redis db and sensor name.
@@ -94,12 +96,14 @@ There are several caveats with timeline sensors:
94
96
  Observer allows to notify sensors each time some class or instance method is called
95
97
  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:
96
98
 
97
- sensors = PulseMeter::Sensor::Configuration.new(
98
- users_by_name: {sensor_type: 'hashed_counter'}
99
- )
100
- PulseMeter::Observer.observe_class_method(User, :create, sensors) do |execution_time, attrs|
101
- users_by_name({attrs[:name] => 1})
102
- end
99
+ ```ruby
100
+ sensors = PulseMeter::Sensor::Configuration.new(
101
+ users_by_name: {sensor_type: 'hashed_counter'}
102
+ )
103
+ PulseMeter::Observer.observe_class_method(User, :create, sensors) do |execution_time, attrs|
104
+ users_by_name({attrs[:name] => 1})
105
+ end
106
+ ```
103
107
 
104
108
  Each time the observed method is called, the block recieves all method's arguments prepended with method's execution time. Block is executed in context of the receiver object passed to observer (this means that `users_by_name` method refers to `sensors`).
105
109
  One should use `observe_method` to observe instance methods.
@@ -110,135 +114,139 @@ One should use `observe_method` to observe instance methods.
110
114
 
111
115
  Just create sensor objects and write data. Some examples below.
112
116
 
113
- require 'pulse-meter'
114
- PulseMeter.redis = Redis.new
115
-
116
- # static sensor examples
117
-
118
- counter = PulseMeter::Sensor::Counter.new :my_counter
119
- counter.event(1)
120
- counter.event(2)
121
- puts counter.value
122
- # prints
123
- # 3
124
-
125
- indicator = PulseMeter::Sensor::Indicator.new :my_value
126
- indicator.event(3.14)
127
- indicator.event(2.71)
128
- puts indicator.value
129
- # prints
130
- # 2.71
131
-
132
- hashed_counter = PulseMeter::Sensor::HashedCounter.new :my_h_counter
133
- hashed_counter.event(:x => 1)
134
- hashed_counter.event(:y => 5)
135
- hashed_counter.event(:y => 1)
136
- p hashed_counter.value
137
- # prints
138
- # {"x"=>1, "y"=>6}
139
-
140
- # timeline sensor examples
141
-
142
- requests_per_minute = PulseMeter::Sensor::Timelined::Counter.new(:my_t_counter,
143
- :interval => 60, # count for each minute
144
- :ttl => 24 * 60 * 60 # keep data one day
145
- )
146
- requests_per_minute.event(1)
147
- requests_per_minute.event(1)
148
- sleep(60)
149
- requests_per_minute.event(1)
150
- requests_per_minute.timeline(2 * 60).each do |v|
151
- puts "#{v.start_time}: #{v.value}"
152
- end
153
- # prints somewhat like
154
- # 2012-05-24 11:06:00 +0400: 2
155
- # 2012-05-24 11:07:00 +0400: 1
156
-
157
- max_per_minute = PulseMeter::Sensor::Timelined::Max.new(:my_t_max,
158
- :interval => 60, # max for each minute
159
- :ttl => 24 * 60 * 60 # keep data one day
160
- )
161
- max_per_minute.event(3)
162
- max_per_minute.event(1)
163
- max_per_minute.event(2)
164
- sleep(60)
165
- max_per_minute.event(5)
166
- max_per_minute.event(7)
167
- max_per_minute.event(6)
168
- max_per_minute.timeline(2 * 60).each do |v|
169
- puts "#{v.start_time}: #{v.value}"
170
- end
171
- # prints somewhat like
172
- # 2012-05-24 11:07:00 +0400: 3.0
173
- # 2012-05-24 11:08:00 +0400: 7.0
117
+ ```ruby
118
+ require 'pulse-meter'
119
+ PulseMeter.redis = Redis.new
120
+
121
+ # static sensor examples
122
+
123
+ counter = PulseMeter::Sensor::Counter.new :my_counter
124
+ counter.event(1)
125
+ counter.event(2)
126
+ puts counter.value
127
+ # prints
128
+ # 3
129
+
130
+ indicator = PulseMeter::Sensor::Indicator.new :my_value
131
+ indicator.event(3.14)
132
+ indicator.event(2.71)
133
+ puts indicator.value
134
+ # prints
135
+ # 2.71
136
+
137
+ hashed_counter = PulseMeter::Sensor::HashedCounter.new :my_h_counter
138
+ hashed_counter.event(:x => 1)
139
+ hashed_counter.event(:y => 5)
140
+ hashed_counter.event(:y => 1)
141
+ p hashed_counter.value
142
+ # prints
143
+ # {"x"=>1, "y"=>6}
144
+
145
+ # timeline sensor examples
146
+
147
+ requests_per_minute = PulseMeter::Sensor::Timelined::Counter.new(:my_t_counter,
148
+ :interval => 60, # count for each minute
149
+ :ttl => 24 * 60 * 60 # keep data one day
150
+ )
151
+ requests_per_minute.event(1)
152
+ requests_per_minute.event(1)
153
+ sleep(60)
154
+ requests_per_minute.event(1)
155
+ requests_per_minute.timeline(2 * 60).each do |v|
156
+ puts "#{v.start_time}: #{v.value}"
157
+ end
158
+ # prints somewhat like
159
+ # 2012-05-24 11:06:00 +0400: 2
160
+ # 2012-05-24 11:07:00 +0400: 1
161
+
162
+ max_per_minute = PulseMeter::Sensor::Timelined::Max.new(:my_t_max,
163
+ :interval => 60, # max for each minute
164
+ :ttl => 24 * 60 * 60 # keep data one day
165
+ )
166
+ max_per_minute.event(3)
167
+ max_per_minute.event(1)
168
+ max_per_minute.event(2)
169
+ sleep(60)
170
+ max_per_minute.event(5)
171
+ max_per_minute.event(7)
172
+ max_per_minute.event(6)
173
+ max_per_minute.timeline(2 * 60).each do |v|
174
+ puts "#{v.start_time}: #{v.value}"
175
+ end
176
+ # prints somewhat like
177
+ # 2012-05-24 11:07:00 +0400: 3.0
178
+ # 2012-05-24 11:08:00 +0400: 7.0
179
+ ```
174
180
 
175
181
  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. Using and creating sensors through `PulseMeter::Sensor::Configuration` also allows to ignore any i/o errors (i.e. redis server unavailability), and this is generally the required case.
176
182
 
177
- require 'pulse-meter'
178
- PulseMeter.redis = Redis.new
179
-
180
- sensors = PulseMeter::Sensor::Configuration.new(
181
- my_counter: {sensor_type: 'counter'},
182
- my_value: {sensor_type: 'indicator'},
183
- my_h_counter: {sensor_type: 'hashed_counter'},
184
- my_t_counter: {
185
- sensor_type: 'timelined/counter',
186
- args: {
187
- interval: 60, # count for each minute
188
- ttl: 24 * 60 * 60 # keep data one day
189
- }
190
- },
191
- my_t_max: {
192
- sensor_type: 'timelined/max',
193
- args: {
194
- interval: 60, # count for each minute
195
- ttl: 24 * 60 * 60 # keep data one day
196
- }
197
- }
198
- )
199
-
200
- sensors.my_counter(1)
201
- sensors.my_counter(2)
202
- sensors.sensor(:my_counter) do |s|
203
- puts s.value
204
- end
205
-
206
- sensors.my_value(3.14)
207
- sensors.my_value(2.71)
208
- sensors.sensor(:my_value) do |s|
209
- puts s.value
210
- end
211
-
212
-
213
- sensors.my_h_counter(:x => 1)
214
- sensors.my_h_counter(:y => 5)
215
- sensors.my_h_counter(:y => 1)
216
- sensors.sensor(:my_h_counter) do |s|
217
- p s.value
218
- end
183
+ ```ruby
184
+ require 'pulse-meter'
185
+ PulseMeter.redis = Redis.new
186
+
187
+ sensors = PulseMeter::Sensor::Configuration.new(
188
+ my_counter: {sensor_type: 'counter'},
189
+ my_value: {sensor_type: 'indicator'},
190
+ my_h_counter: {sensor_type: 'hashed_counter'},
191
+ my_t_counter: {
192
+ sensor_type: 'timelined/counter',
193
+ args: {
194
+ interval: 60, # count for each minute
195
+ ttl: 24 * 60 * 60 # keep data one day
196
+ }
197
+ },
198
+ my_t_max: {
199
+ sensor_type: 'timelined/max',
200
+ args: {
201
+ interval: 60, # count for each minute
202
+ ttl: 24 * 60 * 60 # keep data one day
203
+ }
204
+ }
205
+ )
206
+
207
+ sensors.my_counter(1)
208
+ sensors.my_counter(2)
209
+ sensors.sensor(:my_counter) do |s|
210
+ puts s.value
211
+ end
212
+
213
+ sensors.my_value(3.14)
214
+ sensors.my_value(2.71)
215
+ sensors.sensor(:my_value) do |s|
216
+ puts s.value
217
+ end
219
218
 
220
- sensors.my_t_counter(1)
221
- sensors.my_t_counter(1)
222
- sleep(60)
223
- sensors.my_t_counter(1)
224
- sensors.sensor(:my_t_counter) do |s|
225
- s.timeline(2 * 60).each do |v|
226
- puts "#{v.start_time}: #{v.value}"
227
- end
228
- end
229
-
230
- sensors.my_t_max(3)
231
- sensors.my_t_max(1)
232
- sensors.my_t_max(2)
233
- sleep(60)
234
- sensors.my_t_max(5)
235
- sensors.my_t_max(7)
236
- sensors.my_t_max(6)
237
- sensors.sensor(:my_t_max) do |s|
238
- s.timeline(2 * 60).each do |v|
239
- puts "#{v.start_time}: #{v.value}"
240
- end
241
- end
219
+
220
+ sensors.my_h_counter(:x => 1)
221
+ sensors.my_h_counter(:y => 5)
222
+ sensors.my_h_counter(:y => 1)
223
+ sensors.sensor(:my_h_counter) do |s|
224
+ p s.value
225
+ end
226
+
227
+ sensors.my_t_counter(1)
228
+ sensors.my_t_counter(1)
229
+ sleep(60)
230
+ sensors.my_t_counter(1)
231
+ sensors.sensor(:my_t_counter) do |s|
232
+ s.timeline(2 * 60).each do |v|
233
+ puts "#{v.start_time}: #{v.value}"
234
+ end
235
+ end
236
+
237
+ sensors.my_t_max(3)
238
+ sensors.my_t_max(1)
239
+ sensors.my_t_max(2)
240
+ sleep(60)
241
+ sensors.my_t_max(5)
242
+ sensors.my_t_max(7)
243
+ sensors.my_t_max(6)
244
+ sensors.sensor(:my_t_max) do |s|
245
+ s.timeline(2 * 60).each do |v|
246
+ puts "#{v.start_time}: #{v.value}"
247
+ end
248
+ end
249
+ ```
242
250
 
243
251
  ## Command line interface
244
252
 
@@ -269,42 +277,46 @@ at project root and visit
269
277
 
270
278
  `client.rb` just creates a timelined counter an sends data to it in an infinite loop.
271
279
 
272
- require "pulse-meter"
280
+ ```ruby
281
+ require "pulse-meter"
273
282
 
274
- PulseMeter.redis = Redis.new
283
+ PulseMeter.redis = Redis.new
275
284
 
276
- sensor = PulseMeter::Sensor::Timelined::Counter.new(:simple_sample_counter,
277
- :interval => 5,
278
- :ttl => 60 * 60
279
- )
285
+ sensor = PulseMeter::Sensor::Timelined::Counter.new(:simple_sample_counter,
286
+ :interval => 5,
287
+ :ttl => 60 * 60
288
+ )
280
289
 
281
- while true
282
- STDERR.puts "tick"
283
- sensor.event(1)
284
- sleep(Random.rand)
285
- end
290
+ while true
291
+ STDERR.puts "tick"
292
+ sensor.event(1)
293
+ sleep(Random.rand)
294
+ end
295
+ ```
286
296
 
287
297
  `server.ru` is a Rackup file creating a simple layout with one page and one widget on it, which displays
288
298
  the sensor's data. The layout is converted to a rack application and launched.
289
299
 
290
- require "pulse-meter/visualizer"
300
+ ```ruby
301
+ require "pulse-meter/visualizer"
291
302
 
292
- PulseMeter.redis = Redis.new
303
+ PulseMeter.redis = Redis.new
293
304
 
294
- layout = PulseMeter::Visualizer.draw do |l|
305
+ layout = PulseMeter::Visualizer.draw do |l|
295
306
 
296
- l.title "Minimal App"
307
+ l.title "Minimal App"
297
308
 
298
- l.page "Main Page" do |p|
299
- p.area "Live Counter",
300
- sensor: :simple_sample_counter,
301
- timespan: 5 * 60,
302
- redraw_interval: 1
303
- end
309
+ l.page "Main Page" do |p|
310
+ p.area "Live Counter",
311
+ sensor: :simple_sample_counter,
312
+ timespan: 5 * 60,
313
+ redraw_interval: 1
314
+ end
304
315
 
305
- end
316
+ end
306
317
 
307
- run layout.to_app
318
+ run layout.to_app
319
+ ```
308
320
 
309
321
  `Procfile` allows to launch both "client" script and the web server with `foreman`.
310
322
 
@@ -320,243 +332,249 @@ at project root and visit
320
332
 
321
333
  `client.rb` imitating users visiting some imaginary site.
322
334
 
323
- require "pulse-meter"
324
-
325
- PulseMeter.redis = Redis.new
326
-
327
- sensors = PulseMeter::Sensor::Configuration.new(
328
- requests_per_minute: {
329
- sensor_type: 'timelined/counter',
330
- args: {
331
- annotation: 'Requests per minute',
332
- interval: 60,
333
- ttl: 60 * 60 * 24 # keep data one day
334
- }
335
- },
336
- requests_per_hour: {
337
- sensor_type: 'timelined/counter',
338
- args: {
339
- annotation: 'Requests per hour',
340
- interval: 60 * 60,
341
- ttl: 60 * 60 * 24 * 30 # keep data 30 days
342
- }
343
- },
344
- # when ActiveSupport extentions are loaded, a better way is to write just
345
- # :interval => 1.hour,
346
- # :ttl => 30.days
347
- errors_per_minute: {
348
- sensor_type: 'timelined/counter',
349
- args: {
350
- annotation: 'Errors per minute',
351
- interval: 60,
352
- ttl: 60 * 60 * 24
353
- }
354
- },
355
- errors_per_hour: {
356
- sensor_type: 'timelined/counter',
357
- args: {
358
- annotation: 'Errors per hour',
359
- interval: 60 * 60,
360
- ttl: 60 * 60 * 24 * 30
361
- }
362
- },
363
- longest_minute_request: {
364
- sensor_type: 'timelined/max',
365
- args: {
366
- annotation: 'Longest minute requests',
367
- interval: 60,
368
- ttl: 60 * 60 * 24
369
- }
370
- },
371
- shortest_minute_request: {
372
- sensor_type: 'timelined/min',
373
- args: {
374
- annotation: 'Shortest minute requests',
375
- interval: 60,
376
- ttl: 60 * 60 * 24
377
- }
378
- },
379
- perc90_minute_request: {
380
- sensor_type: 'timelined/percentile',
381
- args: {
382
- annotation: 'Minute request 90-percent percentile',
383
- interval: 60,
384
- ttl: 60 * 60 * 24,
385
- p: 0.9
386
- }
387
- },
388
- cpu: {
389
- sensor_type: 'indicator',
390
- args: {
391
- annotation: 'CPU%'
392
- }
393
- }
394
- )
395
-
396
- agent_names = [:ie, :firefox, :chrome, :other]
397
- agent_names.each do |agent|
398
- sensors.add_sensor(agent,
399
- sensor_type: 'timelined/counter',
400
- args: {
401
- annotation: "Requests from #{agent} browser",
402
- interval: 60 * 60,
403
- ttl: 60 * 60 * 24 * 30
404
- }
405
- )
406
- end
407
-
408
- while true
409
- sensors.requests_per_minute(1)
410
- sensors.requests_per_hour(1)
411
-
412
- if Random.rand(10) < 1 # let "errors" sometimes occur
413
- sensors.errors_per_minute(1)
414
- sensors.errors_per_hour(1)
415
- end
416
-
417
- request_time = 0.1 + Random.rand
418
-
419
- sensors.longest_minute_request(request_time)
420
- sensors.shortest_minute_request(request_time)
421
- sensors.perc90_minute_request(request_time)
422
-
423
- agent_counter = sensors.sensor(agent_names.shuffle.first)
424
- agent_counter.event(1)
425
-
426
- sensors.cpu(Random.rand(100))
427
-
428
- sleep(Random.rand / 10)
429
- end
335
+ ```ruby
336
+ require "pulse-meter"
337
+
338
+ PulseMeter.redis = Redis.new
339
+
340
+ sensors = PulseMeter::Sensor::Configuration.new(
341
+ requests_per_minute: {
342
+ sensor_type: 'timelined/counter',
343
+ args: {
344
+ annotation: 'Requests per minute',
345
+ interval: 60,
346
+ ttl: 60 * 60 * 24 # keep data one day
347
+ }
348
+ },
349
+ requests_per_hour: {
350
+ sensor_type: 'timelined/counter',
351
+ args: {
352
+ annotation: 'Requests per hour',
353
+ interval: 60 * 60,
354
+ ttl: 60 * 60 * 24 * 30 # keep data 30 days
355
+ }
356
+ },
357
+ # when ActiveSupport extentions are loaded, a better way is to write just
358
+ # :interval => 1.hour,
359
+ # :ttl => 30.days
360
+ errors_per_minute: {
361
+ sensor_type: 'timelined/counter',
362
+ args: {
363
+ annotation: 'Errors per minute',
364
+ interval: 60,
365
+ ttl: 60 * 60 * 24
366
+ }
367
+ },
368
+ errors_per_hour: {
369
+ sensor_type: 'timelined/counter',
370
+ args: {
371
+ annotation: 'Errors per hour',
372
+ interval: 60 * 60,
373
+ ttl: 60 * 60 * 24 * 30
374
+ }
375
+ },
376
+ longest_minute_request: {
377
+ sensor_type: 'timelined/max',
378
+ args: {
379
+ annotation: 'Longest minute requests',
380
+ interval: 60,
381
+ ttl: 60 * 60 * 24
382
+ }
383
+ },
384
+ shortest_minute_request: {
385
+ sensor_type: 'timelined/min',
386
+ args: {
387
+ annotation: 'Shortest minute requests',
388
+ interval: 60,
389
+ ttl: 60 * 60 * 24
390
+ }
391
+ },
392
+ perc90_minute_request: {
393
+ sensor_type: 'timelined/percentile',
394
+ args: {
395
+ annotation: 'Minute request 90-percent percentile',
396
+ interval: 60,
397
+ ttl: 60 * 60 * 24,
398
+ p: 0.9
399
+ }
400
+ },
401
+ cpu: {
402
+ sensor_type: 'indicator',
403
+ args: {
404
+ annotation: 'CPU%'
405
+ }
406
+ }
407
+ )
408
+
409
+ agent_names = [:ie, :firefox, :chrome, :other]
410
+ agent_names.each do |agent|
411
+ sensors.add_sensor(agent,
412
+ sensor_type: 'timelined/counter',
413
+ args: {
414
+ annotation: "Requests from #{agent} browser",
415
+ interval: 60 * 60,
416
+ ttl: 60 * 60 * 24 * 30
417
+ }
418
+ )
419
+ end
420
+
421
+ while true
422
+ sensors.requests_per_minute(1)
423
+ sensors.requests_per_hour(1)
424
+
425
+ if Random.rand(10) < 1 # let "errors" sometimes occur
426
+ sensors.errors_per_minute(1)
427
+ sensors.errors_per_hour(1)
428
+ end
429
+
430
+ request_time = 0.1 + Random.rand
431
+
432
+ sensors.longest_minute_request(request_time)
433
+ sensors.shortest_minute_request(request_time)
434
+ sensors.perc90_minute_request(request_time)
435
+
436
+ agent_counter = sensors.sensor(agent_names.shuffle.first)
437
+ agent_counter.event(1)
438
+
439
+ sensors.cpu(Random.rand(100))
440
+
441
+ sleep(Random.rand / 10)
442
+ end
443
+ ```
430
444
 
431
445
  A more complicated visualization
432
446
 
433
- require "pulse-meter/visualizer"
447
+ ```ruby
448
+ require "pulse-meter/visualizer"
434
449
 
435
- PulseMeter.redis = Redis.new
450
+ PulseMeter.redis = Redis.new
436
451
 
437
- layout = PulseMeter::Visualizer.draw do |l|
452
+ layout = PulseMeter::Visualizer.draw do |l|
438
453
 
439
- # Application title
440
- l.title "Full Example"
454
+ # Application title
455
+ l.title "Full Example"
441
456
 
442
- # Use local time for x-axis of charts
443
- l.use_utc false
457
+ # Use local time for x-axis of charts
458
+ l.use_utc false
444
459
 
445
- # Transfer some global parameters to Google Charts
446
- l.gchart_options({
447
- background_color: '#CCC'
448
- })
460
+ # Transfer some global parameters to Google Charts
461
+ l.gchart_options({
462
+ background_color: '#CCC'
463
+ })
449
464
 
450
- # Add some pages
451
- l.page "Request count" do |p|
465
+ # Add some pages
466
+ l.page "Request count" do |p|
452
467
 
453
- # Add chart (of Google Charts `area' style, `pie' and `line' are also available)
454
- p.area "Requests per minute" do |w|
468
+ # Add chart (of Google Charts `area' style, `pie' and `line' are also available)
469
+ p.area "Requests per minute" do |w|
455
470
 
456
- # Plot :requests_per_minute values on this chart with black color
457
- w.sensor :requests_per_minute, color: '#000000'
471
+ # Plot :requests_per_minute values on this chart with black color
472
+ w.sensor :requests_per_minute, color: '#000000'
458
473
 
459
- # Plot :errors_per_minute values on this chart with red color
460
- w.sensor :errors_per_minute, color: '#FF0000'
474
+ # Plot :errors_per_minute values on this chart with red color
475
+ w.sensor :errors_per_minute, color: '#FF0000'
461
476
 
462
- # Plot values for the last hour
463
- w.timespan 60 * 60
477
+ # Plot values for the last hour
478
+ w.timespan 60 * 60
464
479
 
465
- # Redraw chart every 10 seconds
466
- w.redraw_interval 10
480
+ # Redraw chart every 10 seconds
481
+ w.redraw_interval 10
467
482
 
468
- # Plot incomplete data
469
- w.show_last_point true
483
+ # Plot incomplete data
484
+ w.show_last_point true
470
485
 
471
- # Meaning of the y-axis
472
- w.values_label "Request count"
486
+ # Meaning of the y-axis
487
+ w.values_label "Request count"
473
488
 
474
- # Occupy half (5/10) of the page (horizontally)
475
- w.width 5
489
+ # Occupy half (5/10) of the page (horizontally)
490
+ w.width 5
476
491
 
477
- # Transfer page-wide (and page-specific) options to Google Charts
478
- p.gchart_options({
479
- height: 500
480
- })
481
- end
492
+ # Transfer page-wide (and page-specific) options to Google Charts
493
+ p.gchart_options({
494
+ height: 500
495
+ })
496
+ end
482
497
 
483
- p.area "Requests per hour" do |w|
498
+ p.area "Requests per hour" do |w|
484
499
 
485
- w.sensor :requests_per_hour, color: '#555555'
486
- w.sensor :errors_per_hour, color: '#FF0000'
500
+ w.sensor :requests_per_hour, color: '#555555'
501
+ w.sensor :errors_per_hour, color: '#FF0000'
487
502
 
488
- w.timespan 24 * 60 * 60
489
- w.redraw_interval 10
490
- w.show_last_point true
491
- w.values_label "Request count"
492
- w.width 5
503
+ w.timespan 24 * 60 * 60
504
+ w.redraw_interval 10
505
+ w.show_last_point true
506
+ w.values_label "Request count"
507
+ w.width 5
493
508
 
494
- end
495
- end
509
+ end
510
+ end
496
511
 
497
- l.page "Request times" do |p|
498
- p.area "Requests time" do |w|
512
+ l.page "Request times" do |p|
513
+ p.area "Requests time" do |w|
499
514
 
500
- w.sensor :longest_minute_request
501
- w.sensor :shortest_minute_request
502
- w.sensor :perc90_minute_request
515
+ w.sensor :longest_minute_request
516
+ w.sensor :shortest_minute_request
517
+ w.sensor :perc90_minute_request
503
518
 
504
- w.timespan 60 * 60
505
- w.redraw_interval 10
506
- w.show_last_point true
507
- w.values_label "Time in seconds"
508
- w.width 10
519
+ w.timespan 60 * 60
520
+ w.redraw_interval 10
521
+ w.show_last_point true
522
+ w.values_label "Time in seconds"
523
+ w.width 10
509
524
 
510
- end
511
- end
525
+ end
526
+ end
512
527
 
513
- l.page "Browsers" do |p|
514
- p.pie "Requests from browser" do |w|
528
+ l.page "Browsers" do |p|
529
+ p.pie "Requests from browser" do |w|
515
530
 
516
- [:ie, :firefox, :chrome, :other].each do |sensor|
517
- w.sensor sensor
518
- end
531
+ [:ie, :firefox, :chrome, :other].each do |sensor|
532
+ w.sensor sensor
533
+ end
519
534
 
520
- w.redraw_interval 10
521
- w.show_last_point true
522
- w.values_label "Request count"
523
- w.width 10
535
+ w.redraw_interval 10
536
+ w.show_last_point true
537
+ w.values_label "Request count"
538
+ w.width 10
524
539
 
525
- end
540
+ end
526
541
 
527
- p.gchart_options({
528
- height: 500
529
- })
530
- end
542
+ p.gchart_options({
543
+ height: 500
544
+ })
545
+ end
531
546
 
532
- l.page "Gauge" do |p|
547
+ l.page "Gauge" do |p|
533
548
 
534
- p.gauge "CPU Load" do |g|
535
- g.redraw_interval 5
536
- g.values_label '%'
537
- g.width 5
549
+ p.gauge "CPU Load" do |g|
550
+ g.redraw_interval 5
551
+ g.values_label '%'
552
+ g.width 5
538
553
 
539
- g.red_from 90
540
- g.red_to 100
541
- g.yellow_from 75
542
- g.yellow_to 90
543
- g.minor_ticks 5
544
- g.height 200
554
+ g.red_from 90
555
+ g.red_to 100
556
+ g.yellow_from 75
557
+ g.yellow_to 90
558
+ g.minor_ticks 5
559
+ g.height 200
545
560
 
546
- g.sensor :cpu
547
- end
561
+ g.sensor :cpu
562
+ end
548
563
 
549
- end
564
+ end
550
565
 
551
- end
566
+ end
552
567
 
553
- run layout.to_app
568
+ run layout.to_app
569
+ ```
554
570
 
555
571
  ## Installation
556
572
 
557
573
  Add this line to your application's Gemfile:
558
574
 
559
- gem 'pulse-meter'
575
+ ```ruby
576
+ gem 'pulse-meter'
577
+ ```
560
578
 
561
579
  And then execute:
562
580