librato-rack 0.3.0 → 0.4.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.tar.gz.sig +1 -2
- data/CHANGELOG.md +10 -0
- data/LICENSE +3 -3
- data/README.md +7 -0
- data/lib/librato/collector/group.rb +2 -2
- data/lib/librato/rack.rb +41 -5
- data/lib/librato/rack/configuration.rb +31 -3
- data/lib/librato/rack/logger.rb +32 -9
- data/lib/librato/rack/tracker.rb +16 -4
- data/lib/librato/rack/version.rb +1 -1
- data/lib/librato/rack/worker.rb +29 -8
- data/test/apps/queue_wait.ru +38 -0
- data/test/integration/no_stats_test.rb +1 -1
- data/test/integration/queue_wait_test.rb +65 -0
- data/test/integration/request_test.rb +12 -0
- data/test/unit/collector/group_test.rb +2 -0
- data/test/unit/rack/logger_test.rb +17 -0
- data/test/unit/rack/tracker_test.rb +14 -0
- data/test/unit/rack/worker_test.rb +57 -2
- metadata +10 -5
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
QU�1(��h̜{�ּb=?gְ����v5"��͊"ҳv����!�l6�B���h�Yް��Ț,�s���j~]|���_*N�$Z�� P\��n=j�
|
1
|
+
�fI>�j.;8Q:�sj���atL���0_�g������R-���%� ���ζ�}���L�ơ��`�+ Ǒ�aH!��o��1�i �n�)p%x�G���/
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
### Version 0.4.0
|
2
|
+
* Add HTTP method (GET, POST) metrics
|
3
|
+
* Add log buffering support
|
4
|
+
* Ensure all options passed to a grouped increment are respected
|
5
|
+
* LIBRATO_AUTORUN can be used to prevent startup
|
6
|
+
* Add ability to interrupt reporter process
|
7
|
+
* Start reporting deprecations for old config methods
|
8
|
+
* Add docs for best practices for background workers
|
9
|
+
* Other documentation improvements
|
10
|
+
|
1
11
|
### Version 0.3.0
|
2
12
|
* Add experimental support for EventMachine and EMSynchrony (Balwant K)
|
3
13
|
* Start testing suite against jruby/rbx
|
data/LICENSE
CHANGED
@@ -8,9 +8,9 @@ modification, are permitted provided that the following conditions are met:
|
|
8
8
|
* Redistributions in binary form must reproduce the above copyright
|
9
9
|
notice, this list of conditions and the following disclaimer in the
|
10
10
|
documentation and/or other materials provided with the distribution.
|
11
|
-
* Neither the name of
|
12
|
-
|
13
|
-
|
11
|
+
* Neither the name of Librato, Inc. nor the names of its contributors
|
12
|
+
may be used to endorse or promote products derived from this software
|
13
|
+
without specific prior written permission.
|
14
14
|
|
15
15
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
16
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
data/README.md
CHANGED
@@ -49,6 +49,7 @@ By default you can use `LIBRATO_USER` and `LIBRATO_TOKEN` to pass your account d
|
|
49
49
|
|
50
50
|
* `LIBRATO_SOURCE` - the default source to use for submitted metrics. If this is not set, hostname of the executing machine will be the default source
|
51
51
|
* `LIBRATO_PREFIX` - a prefix which will be prepended to all metric names
|
52
|
+
* `LIBRATO_AUTORUN` - set to `'0'` to prevent the reporter from starting, useful if you don't want `librato-rack` to start under certain circumstances
|
52
53
|
* `LIBRATO_LOG_LEVEL` - see logging section for more
|
53
54
|
* `LIBRATO_EVENT_MODE` - use with evented apps, see "Use with EventMachine" below
|
54
55
|
|
@@ -148,6 +149,12 @@ Can also be written as:
|
|
148
149
|
|
149
150
|
Symbols can be used interchangeably with strings for metric names.
|
150
151
|
|
152
|
+
## Use with Background Workers / Cron Jobs
|
153
|
+
|
154
|
+
`librato-rack` is designed to run within a long-running process and report periodically. Intermittently running rake tasks and most background job tools (delayed job, resque, queue_classic) don't run long enough for this to work.
|
155
|
+
|
156
|
+
Never fear, [we have some guidelines](https://github.com/librato/librato-rails/wiki/Monitoring-Background-Workers) for how to instrument your workers properly.
|
157
|
+
|
151
158
|
## Cross-Process Aggregation
|
152
159
|
|
153
160
|
`librato-rack` submits measurements back to the Librato platform on a _per-process_ basis. By default these measurements are then combined into a single measurement per source (default is your hostname) before persisting the data.
|
@@ -13,9 +13,9 @@ module Librato
|
|
13
13
|
yield self.class.new(@collector, prefix)
|
14
14
|
end
|
15
15
|
|
16
|
-
def increment(counter,
|
16
|
+
def increment(counter, options={})
|
17
17
|
counter = "#{@prefix}#{counter}"
|
18
|
-
@collector.increment counter,
|
18
|
+
@collector.increment counter, options
|
19
19
|
end
|
20
20
|
|
21
21
|
def measure(*args, &block)
|
data/lib/librato/rack.rb
CHANGED
@@ -27,31 +27,50 @@ module Librato
|
|
27
27
|
# run lambda { |env| [200, {"Content-Type" => 'text/html'}, ["Hello!"]] }
|
28
28
|
# end
|
29
29
|
#
|
30
|
+
# @example Using a custom config object
|
31
|
+
# config = Librato::Rack::Configuration.new
|
32
|
+
# config.user = 'myuser@mysite.com'
|
33
|
+
# config.token = 'mytoken'
|
34
|
+
# …more configuration
|
35
|
+
#
|
36
|
+
# use Librato::Rack, :config => config
|
37
|
+
# run MyApp
|
38
|
+
#
|
30
39
|
class Rack
|
31
40
|
attr_reader :config, :tracker
|
32
41
|
|
33
42
|
def initialize(app, options={})
|
43
|
+
old_style = false
|
34
44
|
if options.respond_to?(:tracker) # old-style single argument
|
35
45
|
config = options
|
46
|
+
old_style = true
|
36
47
|
else
|
37
48
|
config = options.fetch(:config, Configuration.new)
|
38
49
|
end
|
39
50
|
@app, @config = app, config
|
40
51
|
@tracker = Tracker.new(@config)
|
41
52
|
Librato.register_tracker(@tracker) # create global reference
|
53
|
+
|
54
|
+
if old_style
|
55
|
+
@tracker.deprecate 'middleware setup no longer takes a single argument, use `use Librato::Rack :config => config` instead.'
|
56
|
+
end
|
42
57
|
end
|
43
58
|
|
44
59
|
def call(env)
|
45
|
-
check_log_output(env)
|
60
|
+
check_log_output(env) unless @log_target
|
46
61
|
@tracker.check_worker
|
62
|
+
request_method = env["REQUEST_METHOD"]
|
47
63
|
record_header_metrics(env)
|
48
64
|
response, duration = process_request(env)
|
49
|
-
record_request_metrics(response.first, duration)
|
65
|
+
record_request_metrics(response.first, request_method, duration)
|
50
66
|
response
|
51
67
|
end
|
52
68
|
|
53
69
|
private
|
54
70
|
|
71
|
+
# this generally will only get called on the first request
|
72
|
+
# it figures out the environment-appropriate logging outlet
|
73
|
+
# and notifies config and tracker about it
|
55
74
|
def check_log_output(env)
|
56
75
|
return if @log_target
|
57
76
|
if in_heroku_env?
|
@@ -60,7 +79,7 @@ module Librato
|
|
60
79
|
else
|
61
80
|
default = env['rack.errors'] || $stderr
|
62
81
|
end
|
63
|
-
config.log_target ||= default
|
82
|
+
@tracker.update_log_target(config.log_target ||= default)
|
64
83
|
@log_target = config.log_target
|
65
84
|
end
|
66
85
|
|
@@ -82,10 +101,21 @@ module Librato
|
|
82
101
|
end
|
83
102
|
|
84
103
|
def record_header_metrics(env)
|
85
|
-
|
104
|
+
queue_start = env['HTTP_X_REQUEST_START'] || env['HTTP_X_QUEUE_START']
|
105
|
+
if queue_start
|
106
|
+
queue_start = queue_start.to_s.gsub('t=', '').to_i
|
107
|
+
case queue_start.to_s.length
|
108
|
+
when 16 # microseconds
|
109
|
+
wait = ((Time.now.to_f * 1000000).to_i - queue_start) / 1000.0
|
110
|
+
tracker.timing 'rack.request.queue.time', wait
|
111
|
+
when 13 # milliseconds
|
112
|
+
wait = (Time.now.to_f * 1000).to_i - queue_start
|
113
|
+
tracker.timing 'rack.request.queue.time', wait
|
114
|
+
end
|
115
|
+
end
|
86
116
|
end
|
87
117
|
|
88
|
-
def record_request_metrics(status, duration)
|
118
|
+
def record_request_metrics(status, http_method, duration)
|
89
119
|
return if config.disable_rack_metrics
|
90
120
|
tracker.group 'rack.request' do |group|
|
91
121
|
group.increment 'total'
|
@@ -99,6 +129,12 @@ module Librato
|
|
99
129
|
s.timing "#{status}.time", duration
|
100
130
|
s.timing "#{status.to_s[0]}xx.time", duration
|
101
131
|
end
|
132
|
+
|
133
|
+
group.group 'method' do |m|
|
134
|
+
http_method.downcase!
|
135
|
+
m.increment http_method
|
136
|
+
m.timing "#{http_method}.time", duration
|
137
|
+
end
|
102
138
|
end
|
103
139
|
end
|
104
140
|
|
@@ -12,10 +12,10 @@ module Librato
|
|
12
12
|
class Configuration
|
13
13
|
EVENT_MODES = [:eventmachine, :synchrony]
|
14
14
|
|
15
|
-
attr_accessor :user, :token, :
|
16
|
-
:log_level, :flush_interval, :log_target,
|
15
|
+
attr_accessor :user, :token, :autorun, :api_endpoint, :tracker,
|
16
|
+
:source_pids, :log_level, :flush_interval, :log_target,
|
17
17
|
:disable_rack_metrics
|
18
|
-
attr_reader :prefix, :source
|
18
|
+
attr_reader :prefix, :source, :deprecations
|
19
19
|
|
20
20
|
def initialize
|
21
21
|
# set up defaults
|
@@ -24,14 +24,17 @@ module Librato
|
|
24
24
|
self.flush_interval = 60
|
25
25
|
self.source_pids = false
|
26
26
|
@listeners = []
|
27
|
+
@deprecations = []
|
27
28
|
|
28
29
|
# check environment
|
29
30
|
self.user = ENV['LIBRATO_USER'] || ENV['LIBRATO_METRICS_USER']
|
30
31
|
self.token = ENV['LIBRATO_TOKEN'] || ENV['LIBRATO_METRICS_TOKEN']
|
32
|
+
self.autorun = detect_autorun
|
31
33
|
self.prefix = ENV['LIBRATO_PREFIX'] || ENV['LIBRATO_METRICS_PREFIX']
|
32
34
|
self.source = ENV['LIBRATO_SOURCE'] || ENV['LIBRATO_METRICS_SOURCE']
|
33
35
|
self.log_level = ENV['LIBRATO_LOG_LEVEL'] || :info
|
34
36
|
self.event_mode = ENV['LIBRATO_EVENT_MODE']
|
37
|
+
check_deprecations
|
35
38
|
end
|
36
39
|
|
37
40
|
def event_mode
|
@@ -76,6 +79,31 @@ module Librato
|
|
76
79
|
fields
|
77
80
|
end
|
78
81
|
|
82
|
+
private
|
83
|
+
|
84
|
+
def check_deprecations
|
85
|
+
%w{USER TOKEN PREFIX SOURCE}.each do |item|
|
86
|
+
if ENV["LIBRATO_METRICS_#{item}"]
|
87
|
+
deprecate "LIBRATO_METRICS_#{item} will be removed in a future release, please use LIBRATO_#{item} instead."
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def deprecate(message)
|
93
|
+
@deprecations << message
|
94
|
+
end
|
95
|
+
|
96
|
+
def detect_autorun
|
97
|
+
case ENV['LIBRATO_AUTORUN']
|
98
|
+
when '0', 'FALSE'
|
99
|
+
false
|
100
|
+
when '1', 'TRUE'
|
101
|
+
true
|
102
|
+
else
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
79
107
|
end
|
80
108
|
end
|
81
109
|
end
|
data/lib/librato/rack/logger.rb
CHANGED
@@ -8,10 +8,12 @@ module Librato
|
|
8
8
|
class Logger
|
9
9
|
LOG_LEVELS = [:off, :error, :warn, :info, :debug, :trace]
|
10
10
|
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :prefix
|
12
|
+
attr_reader :outlet
|
12
13
|
|
13
|
-
def initialize(
|
14
|
-
|
14
|
+
def initialize(outlet=nil)
|
15
|
+
@buffer = []
|
16
|
+
self.outlet = outlet
|
15
17
|
self.prefix = '[librato-rack] '
|
16
18
|
end
|
17
19
|
|
@@ -24,12 +26,10 @@ module Librato
|
|
24
26
|
def log(level, message=nil, &block)
|
25
27
|
return unless should_log?(level)
|
26
28
|
message = prefix + (message || block.call)
|
27
|
-
if
|
28
|
-
|
29
|
-
elsif logger.respond_to?(:error) # logger obj
|
30
|
-
log_to_logger(level, message)
|
29
|
+
if outlet.nil?
|
30
|
+
buffer(level, message)
|
31
31
|
else
|
32
|
-
|
32
|
+
write_to_outlet(level, message)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -48,8 +48,21 @@ module Librato
|
|
48
48
|
@log_level ||= :info
|
49
49
|
end
|
50
50
|
|
51
|
+
def outlet=(outlet)
|
52
|
+
@outlet = outlet
|
53
|
+
flush_buffer unless (outlet.nil? || @buffer.empty?)
|
54
|
+
end
|
55
|
+
|
51
56
|
private
|
52
57
|
|
58
|
+
def buffer(level, message)
|
59
|
+
@buffer << [level, message]
|
60
|
+
end
|
61
|
+
|
62
|
+
def flush_buffer
|
63
|
+
@buffer.each { |buffered| write_to_outlet(*buffered) }
|
64
|
+
end
|
65
|
+
|
53
66
|
# write message to an ruby stdlib logger object or another class with
|
54
67
|
# similar interface, respecting log levels when we can map them
|
55
68
|
def log_to_logger(level, message)
|
@@ -59,13 +72,23 @@ module Librato
|
|
59
72
|
else
|
60
73
|
method = :info
|
61
74
|
end
|
62
|
-
|
75
|
+
outlet.send(method, message)
|
63
76
|
end
|
64
77
|
|
65
78
|
def should_log?(level)
|
66
79
|
LOG_LEVELS.index(self.log_level) >= LOG_LEVELS.index(level)
|
67
80
|
end
|
68
81
|
|
82
|
+
def write_to_outlet(level, message)
|
83
|
+
if outlet.respond_to?(:puts) # io obj
|
84
|
+
outlet.puts(message)
|
85
|
+
elsif outlet.respond_to?(:error) # logger obj
|
86
|
+
log_to_logger(level, message)
|
87
|
+
else
|
88
|
+
raise "invalid outlet: not a Logger or IO object"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
69
92
|
end
|
70
93
|
end
|
71
94
|
end
|
data/lib/librato/rack/tracker.rb
CHANGED
@@ -34,6 +34,8 @@ module Librato
|
|
34
34
|
@worker.run_periodically(config.flush_interval) do
|
35
35
|
flush
|
36
36
|
end
|
37
|
+
|
38
|
+
config.deprecations.each { |d| deprecate(d) }
|
37
39
|
end
|
38
40
|
|
39
41
|
# primary collector object used by this tracker
|
@@ -41,6 +43,11 @@ module Librato
|
|
41
43
|
@collector ||= Librato::Collector.new
|
42
44
|
end
|
43
45
|
|
46
|
+
# log a deprecation message
|
47
|
+
def deprecate(message)
|
48
|
+
log :warn, "DEPRECATION: #{message}"
|
49
|
+
end
|
50
|
+
|
44
51
|
# send all current data to Metrics
|
45
52
|
def flush
|
46
53
|
log :debug, "flushing pid #{@pid} (#{Time.now}).."
|
@@ -58,6 +65,11 @@ module Librato
|
|
58
65
|
config.source_pids ? "#{source}.#{$$}" : source
|
59
66
|
end
|
60
67
|
|
68
|
+
# change output stream for logging
|
69
|
+
def update_log_target(target)
|
70
|
+
logger.outlet = target
|
71
|
+
end
|
72
|
+
|
61
73
|
private
|
62
74
|
|
63
75
|
# access to client instance
|
@@ -123,16 +135,16 @@ module Librato
|
|
123
135
|
if !config.user || !config.token
|
124
136
|
# don't show this unless we're debugging, expected behavior
|
125
137
|
log :debug, 'halting: credentials not present.'
|
126
|
-
|
138
|
+
elsif config.autorun == false
|
139
|
+
log :debug, 'halting: LIBRATO_AUTORUN disabled startup'
|
127
140
|
elsif qualified_source !~ SOURCE_REGEX
|
128
141
|
log :warn, "halting: '#{qualified_source}' is an invalid source name."
|
129
|
-
false
|
130
142
|
elsif on_heroku && !config.explicit_source?
|
131
143
|
log :warn, 'halting: source must be provided in configuration.'
|
132
|
-
false
|
133
144
|
else
|
134
|
-
true
|
145
|
+
return true
|
135
146
|
end
|
147
|
+
false
|
136
148
|
end
|
137
149
|
|
138
150
|
def source
|
data/lib/librato/rack/version.rb
CHANGED
data/lib/librato/rack/worker.rb
CHANGED
@@ -10,9 +10,12 @@ module Librato
|
|
10
10
|
# available options:
|
11
11
|
# * timer - type of timer to use, valid options are
|
12
12
|
# :sleep (default), :eventmachine, or :synchrony
|
13
|
+
# * sync - try to synchronize timer executions to whole
|
14
|
+
# minutes or subdivisions thereof
|
13
15
|
def initialize(options={})
|
14
16
|
@interrupt = false
|
15
17
|
@timer = (options[:timer] || :sleep).to_sym
|
18
|
+
@sync = options[:sync] || false
|
16
19
|
end
|
17
20
|
|
18
21
|
# run the given block every <period> seconds, looping
|
@@ -32,18 +35,36 @@ module Librato
|
|
32
35
|
# they will be in sync.
|
33
36
|
#
|
34
37
|
def start_time(period)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
if @sync
|
39
|
+
earliest = Time.now + period
|
40
|
+
# already on a whole minute
|
41
|
+
return earliest if earliest.sec == 0
|
42
|
+
if period > 30
|
43
|
+
# bump to whole minute
|
44
|
+
earliest + (60-earliest.sec)
|
45
|
+
else
|
46
|
+
# ensure sync to whole minute if minute is evenly divisible
|
47
|
+
earliest + (period-(earliest.sec%period))
|
48
|
+
end
|
41
49
|
else
|
42
|
-
|
43
|
-
|
50
|
+
if period > 30
|
51
|
+
# ensure some wobble in start times,
|
52
|
+
# trade a slightly irregular first period for a more even
|
53
|
+
# distribution for network requests between processes
|
54
|
+
start = Time.now
|
55
|
+
start + (60-start.sec) + rand(60)
|
56
|
+
else
|
57
|
+
Time.now + period
|
58
|
+
end
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
62
|
+
# stop worker loop at the beginning of the next round
|
63
|
+
# of execution
|
64
|
+
def stop!
|
65
|
+
@interrupt = true
|
66
|
+
end
|
67
|
+
|
47
68
|
private
|
48
69
|
|
49
70
|
# run continuous loop executing every <period>, will start
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'librato-rack'
|
3
|
+
|
4
|
+
# Simulate the environment variables Heroku passes along
|
5
|
+
# with each request
|
6
|
+
#
|
7
|
+
class QueueWait
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
case env['PATH_INFO']
|
14
|
+
when '/milli'
|
15
|
+
env['HTTP_X_REQUEST_START'] = (Time.now.to_f * 1000).to_i.to_s
|
16
|
+
sleep 0.005
|
17
|
+
when '/micro'
|
18
|
+
env['HTTP_X_REQUEST_START'] = (Time.now.to_f * 1000000).to_i.to_s
|
19
|
+
sleep 0.01
|
20
|
+
when '/queue_start'
|
21
|
+
env['HTTP_X_QUEUE_START'] = (Time.now.to_f * 1000).to_i.to_s
|
22
|
+
sleep 0.015
|
23
|
+
when '/with_t'
|
24
|
+
env['HTTP_X_REQUEST_START'] = "t=#{(Time.now.to_f * 1000000).to_i}".to_s
|
25
|
+
sleep 0.02
|
26
|
+
end
|
27
|
+
@app.call(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
use QueueWait
|
32
|
+
use Librato::Rack
|
33
|
+
|
34
|
+
def application(env)
|
35
|
+
[200, {"Content-Type" => 'text/html'}, ["Hello!"]]
|
36
|
+
end
|
37
|
+
|
38
|
+
run method(:application)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
|
4
|
+
# Tests for universal tracking for all request paths
|
5
|
+
#
|
6
|
+
class QueueWaitTest < Minitest::Test
|
7
|
+
include Rack::Test::Methods
|
8
|
+
|
9
|
+
def app
|
10
|
+
Rack::Builder.parse_file('test/apps/queue_wait.ru').first
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
# clear metrics before each run
|
15
|
+
aggregate.delete_all
|
16
|
+
counters.delete_all
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_milliseconds
|
20
|
+
get '/milli'
|
21
|
+
|
22
|
+
# puts "milli: #{aggregate["rack.request.queue.time"].inspect}"
|
23
|
+
assert_equal 1, aggregate["rack.request.queue.time"][:count],
|
24
|
+
'should track total queue time'
|
25
|
+
assert_in_delta 5, aggregate["rack.request.queue.time"][:sum], 4
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_microseconds
|
29
|
+
get '/micro'
|
30
|
+
|
31
|
+
# puts "micro: #{aggregate["rack.request.queue.time"].inspect}"
|
32
|
+
assert_equal 1, aggregate["rack.request.queue.time"][:count],
|
33
|
+
'should track total queue time'
|
34
|
+
assert_in_delta 10, aggregate["rack.request.queue.time"][:sum], 4
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_queue_start
|
38
|
+
get '/queue_start'
|
39
|
+
|
40
|
+
# puts "micro: #{aggregate["rack.request.queue.time"].inspect}"
|
41
|
+
assert_equal 1, aggregate["rack.request.queue.time"][:count],
|
42
|
+
'should track total queue time'
|
43
|
+
assert_in_delta 15, aggregate["rack.request.queue.time"][:sum], 4
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_with_t
|
47
|
+
get '/with_t'
|
48
|
+
|
49
|
+
# puts "micro: #{aggregate["rack.request.queue.time"].inspect}"
|
50
|
+
assert_equal 1, aggregate["rack.request.queue.time"][:count],
|
51
|
+
'should track total queue time'
|
52
|
+
assert_in_delta 20, aggregate["rack.request.queue.time"][:sum], 4
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def aggregate
|
58
|
+
Librato.tracker.collector.aggregate
|
59
|
+
end
|
60
|
+
|
61
|
+
def counters
|
62
|
+
Librato.tracker.collector.counters
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -42,6 +42,18 @@ class RequestTest < Minitest::Test
|
|
42
42
|
assert_equal 1, aggregate["rack.request.status.2xx.time"][:count]
|
43
43
|
end
|
44
44
|
|
45
|
+
def test_track_http_method_info
|
46
|
+
get '/'
|
47
|
+
|
48
|
+
assert_equal 1, counters['rack.request.method.get']
|
49
|
+
assert_equal 1, aggregate['rack.request.method.get.time'][:count]
|
50
|
+
|
51
|
+
post '/'
|
52
|
+
|
53
|
+
assert_equal 1, counters['rack.request.method.post']
|
54
|
+
assert_equal 1, aggregate['rack.request.method.post.time'][:count]
|
55
|
+
end
|
56
|
+
|
45
57
|
def test_track_exceptions
|
46
58
|
begin
|
47
59
|
get '/exception'
|
@@ -8,8 +8,10 @@ module Librato
|
|
8
8
|
collector = Collector.new
|
9
9
|
collector.group 'foo' do |g|
|
10
10
|
g.increment :bar
|
11
|
+
g.increment :baz, :source => 'bang'
|
11
12
|
end
|
12
13
|
assert_equal 1, collector.counters['foo.bar']
|
14
|
+
assert_equal 1, collector.counters.fetch('foo.baz', source: 'bang')
|
13
15
|
end
|
14
16
|
|
15
17
|
def test_measure
|
@@ -79,6 +79,23 @@ module Librato
|
|
79
79
|
assert buffer_lines[0].index('[test prefix] '), 'should use prefix'
|
80
80
|
end
|
81
81
|
|
82
|
+
def test_log_buffering
|
83
|
+
buffer = StringIO.new
|
84
|
+
logger = Logger.new # no outlet provided
|
85
|
+
logger.prefix = ''
|
86
|
+
|
87
|
+
logger.log :error, 'some business'
|
88
|
+
logger.log :error, 'some more business'
|
89
|
+
logger.outlet = buffer
|
90
|
+
logger.log :error, 'some ongoing business'
|
91
|
+
|
92
|
+
buffer.rewind
|
93
|
+
lines = buffer.readlines
|
94
|
+
assert_equal 'some business', lines[0].chomp
|
95
|
+
assert_equal 'some more business', lines[1].chomp
|
96
|
+
assert_equal 'some ongoing business', lines[2].chomp
|
97
|
+
end
|
98
|
+
|
82
99
|
private
|
83
100
|
|
84
101
|
def buffer_lines
|
@@ -32,6 +32,20 @@ module Librato
|
|
32
32
|
assert_equal true, new_tracker.send(:should_start?)
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_autorun_can_prevent_startup
|
36
|
+
ENV['LIBRATO_AUTORUN']='0'
|
37
|
+
config = Configuration.new
|
38
|
+
config.user, config.token = 'foo', 'bar'
|
39
|
+
@buffer = StringIO.new
|
40
|
+
config.log_target = @buffer
|
41
|
+
tracker = Tracker.new(config)
|
42
|
+
|
43
|
+
assert_equal false, tracker.send(:should_start?),
|
44
|
+
'should not start if autorun set to 0'
|
45
|
+
|
46
|
+
ENV.delete('LIBRATO_AUTORUN')
|
47
|
+
end
|
48
|
+
|
35
49
|
private
|
36
50
|
|
37
51
|
def buffer_lines
|
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'stringio'
|
3
3
|
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'em-synchrony'
|
6
|
+
|
4
7
|
module Librato
|
5
8
|
class Rack
|
6
9
|
class WorkerTest < Minitest::Test
|
@@ -8,18 +11,34 @@ module Librato
|
|
8
11
|
def test_basic_use
|
9
12
|
worker = Worker.new
|
10
13
|
counter = 0
|
11
|
-
|
14
|
+
|
15
|
+
thread = Thread.new do
|
12
16
|
worker.run_periodically(0.1) do
|
13
17
|
counter += 1
|
14
18
|
end
|
15
19
|
end
|
20
|
+
|
16
21
|
sleep 0.45
|
17
|
-
|
22
|
+
assert_in_delta 4, counter, 1
|
23
|
+
|
24
|
+
worker.stop!
|
25
|
+
thread.join
|
18
26
|
end
|
19
27
|
|
20
28
|
def test_start_time
|
21
29
|
worker = Worker.new
|
22
30
|
|
31
|
+
20.times do
|
32
|
+
time = Time.now
|
33
|
+
start = worker.start_time(60)
|
34
|
+
assert start >= time + 1, 'should be more than 1 second from when run'
|
35
|
+
assert start <= time + 120, 'should not be more than 60 seconds from when run'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_start_time_with_sync
|
40
|
+
worker = Worker.new(sync: true)
|
41
|
+
|
23
42
|
time = Time.now
|
24
43
|
start = worker.start_time(60)
|
25
44
|
assert start >= time + 60, 'should be more than 60 seconds from when run'
|
@@ -43,6 +62,42 @@ module Librato
|
|
43
62
|
assert_equal :sleep, worker.timer
|
44
63
|
end
|
45
64
|
|
65
|
+
def test_eventmachine_timer
|
66
|
+
worker = Worker.new(:timer => :eventmachine)
|
67
|
+
counter = 0
|
68
|
+
|
69
|
+
thread = Thread.new do
|
70
|
+
EventMachine.run do
|
71
|
+
worker.run_periodically(0.1) do
|
72
|
+
counter += 1
|
73
|
+
end
|
74
|
+
EM.add_timer(0.6) { worker.stop!; EM.stop }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
sleep 0.45
|
79
|
+
assert_in_delta 4, counter, 1
|
80
|
+
thread.join
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_em_synchrony_timer
|
84
|
+
worker = Worker.new(:timer => :synchrony)
|
85
|
+
counter = 0
|
86
|
+
|
87
|
+
thread = Thread.new do
|
88
|
+
EM.synchrony do
|
89
|
+
worker.run_periodically(0.1) do
|
90
|
+
counter += 1
|
91
|
+
end
|
92
|
+
EventMachine.stop
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
sleep 0.45
|
97
|
+
assert_in_delta 4, counter, 1
|
98
|
+
Thread.kill(thread)
|
99
|
+
end
|
100
|
+
|
46
101
|
end
|
47
102
|
end
|
48
103
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: librato-rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -37,7 +37,7 @@ cert_chain:
|
|
37
37
|
bktaNmhlblFBRjFDSDk2WmNxY0pIMTc5UzJ0SWlLRE04a2VlUklVT1BDM1dU
|
38
38
|
MGZhb2svMgpnQTJvemRyODUxYy9uQT09Ci0tLS0tRU5EIENFUlRJRklDQVRF
|
39
39
|
LS0tLS0K
|
40
|
-
date: 2013-08-
|
40
|
+
date: 2013-08-19 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: librato-metrics
|
@@ -100,9 +100,11 @@ files:
|
|
100
100
|
- test/apps/custom.ru
|
101
101
|
- test/apps/deprecated.ru
|
102
102
|
- test/apps/no_stats.ru
|
103
|
+
- test/apps/queue_wait.ru
|
103
104
|
- test/integration/custom_test.rb
|
104
105
|
- test/integration/deprecated_test.rb
|
105
106
|
- test/integration/no_stats_test.rb
|
107
|
+
- test/integration/queue_wait_test.rb
|
106
108
|
- test/integration/request_test.rb
|
107
109
|
- test/remote/tracker_test.rb
|
108
110
|
- test/test_helper.rb
|
@@ -115,7 +117,8 @@ files:
|
|
115
117
|
- test/unit/rack/tracker_test.rb
|
116
118
|
- test/unit/rack/worker_test.rb
|
117
119
|
homepage: https://github.com/librato/librato-rack
|
118
|
-
licenses:
|
120
|
+
licenses:
|
121
|
+
- BSD 3-clause
|
119
122
|
post_install_message:
|
120
123
|
rdoc_options: []
|
121
124
|
require_paths:
|
@@ -128,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
131
|
version: '0'
|
129
132
|
segments:
|
130
133
|
- 0
|
131
|
-
hash:
|
134
|
+
hash: -3276523900394881660
|
132
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
136
|
none: false
|
134
137
|
requirements:
|
@@ -137,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
140
|
version: '0'
|
138
141
|
segments:
|
139
142
|
- 0
|
140
|
-
hash:
|
143
|
+
hash: -3276523900394881660
|
141
144
|
requirements: []
|
142
145
|
rubyforge_project:
|
143
146
|
rubygems_version: 1.8.23
|
@@ -149,9 +152,11 @@ test_files:
|
|
149
152
|
- test/apps/custom.ru
|
150
153
|
- test/apps/deprecated.ru
|
151
154
|
- test/apps/no_stats.ru
|
155
|
+
- test/apps/queue_wait.ru
|
152
156
|
- test/integration/custom_test.rb
|
153
157
|
- test/integration/deprecated_test.rb
|
154
158
|
- test/integration/no_stats_test.rb
|
159
|
+
- test/integration/queue_wait_test.rb
|
155
160
|
- test/integration/request_test.rb
|
156
161
|
- test/remote/tracker_test.rb
|
157
162
|
- test/test_helper.rb
|
metadata.gz.sig
CHANGED
Binary file
|