statue19 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68ddfa3744c63889bf94581ac7fb3d3faaf76ada
4
- data.tar.gz: 8b3313832255195944ca2e4fd6bc4249a6c4b21b
3
+ metadata.gz: '09aa5e04b7e09529ee0d5ff1d271383c74bd6a45'
4
+ data.tar.gz: e43f69867039cbb5bb0ec4b939ab98f215a93979
5
5
  SHA512:
6
- metadata.gz: 2685204941aed389de449b449eb19acbba4f267edfd7f5e2c3870164ee850a318afd331da2adba2307bcadb2b80ecc9ff25b696daac7ac44c0d3dce4ab8952cb
7
- data.tar.gz: ab37ee18ac4173ba6f774724d8ad292983123440626499602df0d7e10adf9609110d700eef9214024d8a16dd06dca65c93e55686b7a3556c3010487c809ece8c
6
+ metadata.gz: c272bea07f6d5829a963e00e5045fbe29cecb42b484a9e8a304617e201e7d1756a3b6db8b2f517dcf95ec706e4ad1f547f405c20d74f90a2f586b7e3909f69e8
7
+ data.tar.gz: 00faf7422ced2af9a60be254558074ab21eba6eb90045745bddfad412c5605761ed35d15a575885b861751d410347c8e36d380c1710cc3d41e7830fac91af00d
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.3
5
+ - jruby-19mode
6
+ bundler_args: --binstubs
7
+ script: bin/rake test
data/CHANGELOG.md CHANGED
@@ -1,3 +1,48 @@
1
+ ## [0.3.0] - 2017-03-13
2
+
3
+ ### Feature
4
+
5
+ - Extract duration measuring to `Statue::Clock` and be explicit that we are handling milliseconds.
6
+ - `RackStatistics` queue time is now taken from `X-Request-Start` header.
7
+
8
+ ### Backward incompatible changes
9
+
10
+ - All duration reports are now sent in milliseconds (as it should have always been). These includes:
11
+ - `Statue.report_duration`
12
+ - `RackStatistics` middleware metrics
13
+ - `Statue.stopwatch`
14
+ - Removed `Statue.duration`, you should use `Statue::Clock.duration_in_ms` (which is more explicit)
15
+ - `RackStatistics`: `request.<key>` metric was renamed to `request.<key>.runtime` to have more uniform names
16
+ - `RackStatistics`: now sends specific counter for when your application didn't handle the exception
17
+ - `UDPBacked`: now receives host/port named params or can be built from a string with
18
+ `UDPBacked.from_uri(<uri>)`
19
+
20
+ ## [0.2.7] - 2016-03-09
21
+
22
+ ## Fixes
23
+
24
+ - Make UDPBacked compatible with JRuby
25
+
26
+ ## [0.2.4] - 2016-02-04
27
+
28
+ ## Features
29
+
30
+ - Add support for gauges
31
+
32
+ ## [0.2.2] - 2016-02-02
33
+
34
+ ## Fixes
35
+
36
+ - Allow RackStatistics to handle not integer status codes
37
+
38
+ ## [0.2.1] - 2016-01-07
39
+
40
+ ## Features
41
+
42
+ - Add stopwatchs to report multiple partial times
43
+
1
44
  ## [0.2.0] - 2015-11-17
2
- ### Added
45
+
46
+ ### Features
47
+
3
48
  - Add support for multithreaded applications
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Statue
2
2
 
3
+ ![Build Status](https://travis-ci.org/restorando/statue.svg?branch=ruby19-compat)
4
+
3
5
  / ___)(_ _)/ _\(_ _)/ )( \( __)
4
6
  \___ \ )( / \ )( ) \/ ( ) _)
5
7
  (____/ (__)\_/\_/(__) \____/(____)
data/lib/statue.rb CHANGED
@@ -7,9 +7,9 @@ require 'statue/stopwatch'
7
7
  module Statue
8
8
  extend self
9
9
 
10
- attr_accessor :namespace, :logger
11
-
12
- attr_accessor :backend
10
+ attr_accessor :namespace
11
+ attr_accessor :logger
12
+ attr_writer :backend
13
13
 
14
14
  def report_duration(metric_name, duration = nil, options = {}, &block)
15
15
  result = nil
@@ -30,13 +30,9 @@ module Statue
30
30
  def report_success_or_failure(metric_name, options = {}, &block)
31
31
  success_method = options.delete(:success_method)
32
32
  result = block.call
33
- success = success_method ? result.public_send(success_method) : result
34
33
 
35
- if success
36
- report_increment("#{metric_name}.success", 1, options)
37
- else
38
- report_increment("#{metric_name}.failure", 1, options)
39
- end
34
+ success = success_method ? result.public_send(success_method) : result
35
+ report_increment("#{metric_name}.#{success ? "success" : "failure"}", 1, options)
40
36
 
41
37
  result
42
38
  rescue
@@ -49,13 +45,7 @@ module Statue
49
45
  end
50
46
 
51
47
  def backend
52
- @backend ||= UDPBackend.new
53
- end
54
-
55
- def duration
56
- start = clock_now
57
- yield
58
- clock_now - start
48
+ @backend ||= UDPBackend.from_uri("statsd://127.0.0.1:8125")
59
49
  end
60
50
 
61
51
  def debug(text, &block)
@@ -66,18 +56,4 @@ module Statue
66
56
  logger.error(text, &block) if logger
67
57
  end
68
58
 
69
- if defined?(Process::CLOCK_MONOTONIC)
70
- def clock_now
71
- Process.clock_gettime Process::CLOCK_MONOTONIC
72
- end
73
- elsif RUBY_PLATFORM == 'java'
74
- def clock_now
75
- java.lang.System.nanoTime() / 1_000_000_000.0
76
- end
77
- else
78
- def clock_now
79
- Time.now.to_f
80
- end
81
- end
82
-
83
59
  end
@@ -4,7 +4,12 @@ module Statue
4
4
  class UDPBackend
5
5
  attr_reader :host, :port
6
6
 
7
- def initialize(host = nil, port = nil)
7
+ def self.from_uri(uri)
8
+ uri = URI(uri)
9
+ new(uri.host, uri.port)
10
+ end
11
+
12
+ def initialize(host, port)
8
13
  @host = host
9
14
  @port = port
10
15
  end
@@ -0,0 +1,26 @@
1
+ module Statue
2
+ module Clock
3
+ extend self
4
+
5
+ if defined?(Process::CLOCK_MONOTONIC)
6
+ def now_in_ms
7
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1_000
8
+ end
9
+ elsif RUBY_PLATFORM == 'java'
10
+ def now_in_ms
11
+ java.lang.System.nanoTime() / 1_000_000.0
12
+ end
13
+ else
14
+ def now_in_ms
15
+ Time.now.to_f * 1_000
16
+ end
17
+ end
18
+
19
+ def duration_in_ms
20
+ start = now_in_ms
21
+ yield
22
+ now_in_ms - start
23
+ end
24
+
25
+ end
26
+ end
data/lib/statue/metric.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'statue/clock'
2
+
1
3
  module Statue
2
4
  class Metric
3
5
  TYPES = {
@@ -9,6 +11,7 @@ module Statue
9
11
  }
10
12
 
11
13
  attr_accessor :type, :name, :value, :sample_rate
14
+ attr_reader :full_name, :type_description
12
15
 
13
16
  def self.counter(name, value = 1, options = {})
14
17
  new(options.merge(type: :c, value: value, name: name))
@@ -20,7 +23,7 @@ module Statue
20
23
 
21
24
  def self.measure(name, options = {}, &block)
22
25
  duration = options.delete(:duration)
23
- value = duration || Statue.duration(&block)
26
+ value = duration || Statue::Clock.duration_in_ms(&block)
24
27
  new(options.merge(type: :ms, value: value, name: name))
25
28
  end
26
29
 
@@ -28,7 +31,9 @@ module Statue
28
31
  @type = options.fetch(:type)
29
32
  @name = options.fetch(:name)
30
33
  @value = options.fetch(:value)
34
+ @type_description = TYPES[type] or raise ArgumentError, "invalid type: #{type}"
31
35
  @sample_rate = options[:sample_rate] || 1.0
36
+ @full_name = Statue.namespace ? "#{Statue.namespace}.#{@name}" : @name
32
37
  end
33
38
 
34
39
  def to_s
@@ -38,15 +43,7 @@ module Statue
38
43
  end
39
44
 
40
45
  def inspect
41
- "#<StatsD::Instrument::Metric #{full_name} #{TYPES[type]}(#{value})@#{sample_rate}>"
42
- end
43
-
44
- def full_name
45
- if Statue.namespace
46
- "#{Statue.namespace}.#{@name}"
47
- else
48
- @name
49
- end
46
+ "#<StatsD::Instrument::Metric #{full_name} #{type_description}(#{value})@#{sample_rate}>"
50
47
  end
51
48
 
52
49
  end
@@ -4,7 +4,7 @@ module Statue
4
4
  # Middleware to send metrics about rack requests
5
5
  #
6
6
  # this middleware reports metrics with the following pattern:
7
- # `request.{env['REQUEST_METHOD']}.{path_name}
7
+ # `{env['REQUEST_METHOD']}.{path_name}
8
8
  #
9
9
  # where `path_name` can be configured when inserting the middleware like this:
10
10
  # `use RackStatistics, path_name: ->(env) { ... build the path name ... }`
@@ -17,17 +17,18 @@ module Statue
17
17
  #
18
18
  # Counters:
19
19
  #
20
- # * <key>.status-XXX (where XXX is the status code)
21
- # * <key>.success (on any status 2XX)
22
- # * <key>.unmodified (on status 304)
23
- # * <key>.redirect (on any status 3XX)
24
- # * <key>.failure (on any status 4xx)
25
- # * <key>.error (on any status 5xx or when an exception is raised)
20
+ # * request.<key>.status-XXX (where XXX is the status code)
21
+ # * request.<key>.success (on any status 2XX)
22
+ # * request.<key>.unmodified (on status 304)
23
+ # * request.<key>.redirect (on any status 3XX)
24
+ # * request.<key>.failure (on any status 4xx)
25
+ # * request.<key>.error (on any status 5xx)
26
+ # * request.<key>.unhandled-exception (when an exception is raised that your application didn't handle)
26
27
  #
27
28
  # Timers (all measured from the middleware perspective):
28
29
  #
29
- # * <key> (request time)
30
- # * request.queue (queue time, depends on HTTP_X_QUEUE_START header)
30
+ # * request.<key>.runtime (request time)
31
+ # * request.queue (queue time, depends on HTTP_X_REQUEST_START header)
31
32
  #
32
33
  # To get accurate timers, the middleware should be as higher as
33
34
  # possible in your rack stack
@@ -35,25 +36,25 @@ module Statue
35
36
  class RackStatistics
36
37
  DEFAULT_PATH_NAME = lambda do |env|
37
38
  # Remove duplicate and trailing '/'
38
- path = env['REQUEST_PATH'].squeeze('/').chomp('/')
39
+ path = env['PATH_INFO'].squeeze('/').chomp('/')
39
40
  if path == ''
40
41
  'root'
41
42
  else
42
- # Skip leading '/'
43
+ # Skip leading '/' and replace statsd special characters by '-'
43
44
  env['REQUEST_PATH'][1..-1].tr('/,|', '-')
44
45
  end
45
46
  end
46
47
 
47
48
  def initialize(app, options = {})
48
49
  @app = app
49
- @path_name = options[:path_name] || DEFAULT_PATH_NAME
50
+ @path_name = options[:path_name] || DEFAULT_PATH_NAME
50
51
  end
51
52
 
52
53
  def call(env)
53
54
  report_header_metrics(env)
54
55
 
55
56
  response = nil
56
- duration = Statue.duration do
57
+ duration = Statue::Clock.duration_in_ms do
57
58
  response = @app.call(env)
58
59
  end
59
60
 
@@ -67,9 +68,9 @@ module Statue
67
68
  private
68
69
 
69
70
  def report_header_metrics(env)
70
- if start_header = env['HTTP_X_QUEUE_START']
71
+ if start_header = (env['HTTP_X_REQUEST_START'] || env['HTTP_X_QUEUE_START'])
71
72
  queue_start = start_header[/t=([\d\.]+)/, 1].to_f
72
- Statue.report_duration 'request.queue', Time.now.to_f - queue_start
73
+ Statue.report_duration 'request.queue', (Time.now.to_f - queue_start) * 1_000
73
74
  end
74
75
  end
75
76
 
@@ -77,14 +78,14 @@ module Statue
77
78
  metric_name = metric_name(env)
78
79
  status, _headers, _body = response
79
80
 
80
- Statue.report_duration metric_name, duration
81
+ Statue.report_duration "#{metric_name}.runtime", duration
81
82
 
82
83
  Statue.report_increment "#{metric_name}.status-#{status}"
83
84
  Statue.report_increment "#{metric_name}.#{status_group(status)}"
84
85
  end
85
86
 
86
87
  def report_exception(env, _exception)
87
- Statue.report_increment "#{metric_name(env)}.error"
88
+ Statue.report_increment "#{metric_name(env)}.unhandled-exception"
88
89
  end
89
90
 
90
91
  def metric_name(env)
@@ -4,12 +4,12 @@ module Statue
4
4
  def initialize(name, options = {})
5
5
  @name = name
6
6
  @reporter = options[:reporter] || Statue
7
- @start = @partial = options[:now] || clock_now
7
+ @start = @partial = options[:now] || Clock.now_in_ms
8
8
  end
9
9
 
10
10
  def partial(options = {})
11
11
  suffix = options.delete(:suffix)
12
- now = options.delete(:now) || clock_now
12
+ now = options.delete(:now) || Clock.now_in_ms
13
13
  previous, @partial = @partial, now
14
14
 
15
15
  @reporter.report_duration(metric_name(suffix || "runtime.partial"), @partial - previous, options)
@@ -17,7 +17,7 @@ module Statue
17
17
 
18
18
  def stop(options = {})
19
19
  suffix = options.delete(:suffix)
20
- now = options.delete(:now) || clock_now
20
+ now = options.delete(:now) || Clock.now_in_ms
21
21
  report_partial = options.delete(:report_partial) || false
22
22
 
23
23
  partial(options.merge(now: now, suffix: report_partial.is_a?(String) ? report_partial : nil)) if report_partial
@@ -28,7 +28,7 @@ module Statue
28
28
  end
29
29
 
30
30
  def reset(options = {})
31
- @start = @partial = options[:now] || clock_now
31
+ @start = @partial = options[:now] || Clock.now_in_ms
32
32
  end
33
33
 
34
34
  private
@@ -37,8 +37,5 @@ module Statue
37
37
  "#{@name}.#{suffix}"
38
38
  end
39
39
 
40
- def clock_now
41
- Statue.clock_now
42
- end
43
40
  end
44
41
  end
@@ -1,3 +1,3 @@
1
1
  module Statue
2
- VERSION = '0.2.7'
2
+ VERSION = '0.3.0'
3
3
  end
data/statue19.gemspec CHANGED
@@ -19,5 +19,7 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler", "~> 1.7"
21
21
  spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rack", "~> 1.6"
23
+ spec.add_development_dependency "rack-test", "~> 0.6.3"
22
24
  spec.add_development_dependency "minitest"
23
25
  end
@@ -0,0 +1,140 @@
1
+ require 'test_helper'
2
+ require 'statue/rack_statistics'
3
+ require 'rack/test'
4
+
5
+ describe Statue::RackStatistics do
6
+ include Rack::Test::Methods
7
+ def app
8
+ Statue::RackStatistics.new(App.new)
9
+ end
10
+
11
+ def find_metric(name)
12
+ Statue.backend.captures.find { |m| m.name == name }
13
+ end
14
+
15
+ class App
16
+ def call(env)
17
+ raise "Uncaught error" if env['raise_error']
18
+ [
19
+ env['status'] || 200,
20
+ {},
21
+ []
22
+ ]
23
+ end
24
+ end
25
+
26
+ after do
27
+ Statue.backend.captures.clear
28
+ end
29
+
30
+ describe "request statistics on normal processing" do
31
+
32
+ it "sends queue time" do
33
+ header "X-Request-Start", "t=#{Time.now.to_f - 1}"
34
+ get "/"
35
+
36
+ queue_time = find_metric("request.queue")
37
+ assert queue_time, "Didn't report queue time"
38
+ assert_equal "measure", queue_time.type_description
39
+
40
+ # Measured time can't be less than 1000 ms because we set it to 1 sec before now.
41
+ # Allow a range of 30ms for ruby to do processing and avoid false positives
42
+ assert_in_delta 1015, queue_time.value, 15 # within range 1000-1030
43
+ end
44
+
45
+ it "sends request runtime" do
46
+ get "/"
47
+
48
+ runtime_time = find_metric("request.GET.root.runtime")
49
+ assert runtime_time, "Didn't report request runtime"
50
+ assert_equal "measure", runtime_time.type_description
51
+ # Allow a range of 30ms for ruby to do processing and avoid false positives
52
+ assert_in_delta 15, runtime_time.value, 15 # within range 1000-1030
53
+ end
54
+
55
+ it "sends counter for status-xxx" do
56
+ get "/"
57
+
58
+ runtime_time = find_metric("request.GET.root.status-200")
59
+ assert runtime_time, "Didn't report status-200 counter"
60
+ assert_equal "increment", runtime_time.type_description
61
+ assert_equal 1, runtime_time.value
62
+ end
63
+
64
+ it "sends counter for status group" do
65
+ get "/"
66
+
67
+ runtime_time = find_metric("request.GET.root.success")
68
+ assert runtime_time, "Didn't report sucess counter"
69
+ assert_equal "increment", runtime_time.type_description
70
+ assert_equal 1, runtime_time.value
71
+ end
72
+
73
+ it "sends counter for other status codes" do
74
+ get "/", {}, { 'status' => 502 }
75
+
76
+ runtime_time = find_metric("request.GET.root.status-502")
77
+ assert runtime_time, "Didn't report status-502 counter"
78
+ assert_equal "increment", runtime_time.type_description
79
+ assert_equal 1, runtime_time.value
80
+ end
81
+
82
+ it "sends counter for other status groups" do
83
+ get "/", {}, { 'status' => 502 }
84
+
85
+ runtime_time = find_metric("request.GET.root.error")
86
+ assert runtime_time, "Didn't report error counter"
87
+ assert_equal "increment", runtime_time.type_description
88
+ assert_equal 1, runtime_time.value
89
+ end
90
+
91
+ it "sends all metrics and only those" do
92
+ header "X-Request-Start", "t=#{Time.now.to_f}"
93
+ get "/"
94
+
95
+ metrics = Statue.backend.captures.map(&:name)
96
+ expected_metrics = %w[
97
+ request.queue
98
+ request.GET.root.runtime
99
+ request.GET.root.status-200
100
+ request.GET.root.success
101
+ ]
102
+ missing = expected_metrics - metrics
103
+ extra = metrics - expected_metrics
104
+
105
+ assert missing.empty?, "expect not to be missing, but these were missing: #{missing.inspect}"
106
+ assert extra.empty?, "expected no other metric to be found, but found these: #{extra.inspect}"
107
+ end
108
+
109
+ end
110
+
111
+ describe "request statistics on normal processing" do
112
+
113
+ it "sends queue time" do
114
+ header "X-Request-Start", "t=#{Time.now.to_f - 1}"
115
+ assert_raises do
116
+ get "/", {}, { 'raise_error' => true }
117
+ end
118
+
119
+ queue_time = find_metric("request.queue")
120
+ assert queue_time, "Didn't report queue time"
121
+ assert_equal "measure", queue_time.type_description
122
+
123
+ # Measured time can't be less than 1000 ms because we set it to 1 sec before now.
124
+ # Allow a range of 30ms for ruby to do processing and avoid false positives
125
+ assert_in_delta 1015, queue_time.value, 15 # within range 1000-1030
126
+ end
127
+
128
+ it "sends counter for other status codes" do
129
+ assert_raises do
130
+ get "/", {}, { 'raise_error' => true }
131
+ end
132
+
133
+ runtime_time = find_metric("request.GET.root.unhandled-exception")
134
+ assert runtime_time, "Didn't report unhandled-exception counter"
135
+ assert_equal "increment", runtime_time.type_description
136
+ assert_equal 1, runtime_time.value
137
+ end
138
+
139
+ end
140
+ end
data/test/statue_test.rb CHANGED
@@ -24,8 +24,8 @@ describe Statue do
24
24
  describe ".report_duration" do
25
25
 
26
26
  it "adds a measure metric to the backend using the block call duration" do
27
- Statue.stub(:duration, 1.5) do
28
- result = Statue.report_duration("some.timer") { nil }
27
+ Statue::Clock.stub(:duration_in_ms, 1.5) do
28
+ _result = Statue.report_duration("some.timer") { nil }
29
29
 
30
30
  assert_equal 1, Statue.backend.captures.size
31
31
  assert_equal "some.timer:1.5|ms", Statue.backend.captures.first.to_s
@@ -39,7 +39,7 @@ describe Statue do
39
39
  end
40
40
 
41
41
  it "adds a measure metric to the backend using the fixed value" do
42
- result = Statue.report_duration("some.timer", 2.5)
42
+ _result = Statue.report_duration("some.timer", 2.5)
43
43
 
44
44
  assert_equal 1, Statue.backend.captures.size
45
45
  assert_equal "some.timer:2.5|ms", Statue.backend.captures.first.to_s
@@ -59,7 +59,7 @@ describe Statue do
59
59
  describe ".report_gauge" do
60
60
 
61
61
  it "adds a gauge metric to the backend using the fixed value" do
62
- result = Statue.report_gauge("some.gauge", 23)
62
+ _result = Statue.report_gauge("some.gauge", 23)
63
63
 
64
64
  assert_equal 1, Statue.backend.captures.size
65
65
  assert_equal "some.gauge:23|g", Statue.backend.captures.first.to_s
@@ -8,7 +8,7 @@ describe Statue::Stopwatch do
8
8
  describe "#partial" do
9
9
  it "reports the duration between start and the partial call" do
10
10
  stopwatch = Statue::Stopwatch.new("my_watch", now: 0)
11
- stopwatch.partial(now: 42)
11
+ stopwatch.partial(now: 42) # 42 milliseconds after
12
12
 
13
13
  assert_equal 1, Statue.backend.captures.size
14
14
  assert_equal "my_watch.runtime.partial:42|ms", Statue.backend.captures.first.to_s
@@ -47,7 +47,7 @@ describe Statue::Stopwatch do
47
47
  stopwatch.stop(now: 21)
48
48
 
49
49
  assert_equal 21, Statue.backend.captures.size
50
- *partials, total = Statue.backend.captures
50
+ *_partials, total = Statue.backend.captures
51
51
  assert_equal "my_watch.runtime.total:21|ms", total.to_s
52
52
  end
53
53
 
@@ -70,7 +70,7 @@ describe Statue::Stopwatch do
70
70
  stopwatch.stop(now: 21, report_partial: "runtime.final_lap")
71
71
 
72
72
  assert_equal 22, Statue.backend.captures.size
73
- *partials, special_partial, total = Statue.backend.captures
73
+ *_partials, special_partial, _total = Statue.backend.captures
74
74
  assert_equal "my_watch.runtime.final_lap:1|ms", special_partial.to_s
75
75
  end
76
76
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statue19
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Barreneche
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-18 00:00:00.000000000 Z
11
+ date: 2017-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.6.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.3
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: minitest
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +88,7 @@ extensions: []
60
88
  extra_rdoc_files: []
61
89
  files:
62
90
  - ".gitignore"
91
+ - ".travis.yml"
63
92
  - CHANGELOG.md
64
93
  - Gemfile
65
94
  - LICENSE.txt
@@ -72,11 +101,13 @@ files:
72
101
  - lib/statue/backends/logger.rb
73
102
  - lib/statue/backends/null.rb
74
103
  - lib/statue/backends/udp.rb
104
+ - lib/statue/clock.rb
75
105
  - lib/statue/metric.rb
76
106
  - lib/statue/rack_statistics.rb
77
107
  - lib/statue/stopwatch.rb
78
108
  - lib/statue/version.rb
79
109
  - statue19.gemspec
110
+ - test/rack_statistics_test.rb
80
111
  - test/statue_test.rb
81
112
  - test/stopwatch_test.rb
82
113
  - test/test_helper.rb
@@ -100,11 +131,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
131
  version: '0'
101
132
  requirements: []
102
133
  rubyforge_project:
103
- rubygems_version: 2.4.8
134
+ rubygems_version: 2.5.2
104
135
  signing_key:
105
136
  specification_version: 4
106
137
  summary: Easily track application metrics into Statsie
107
138
  test_files:
139
+ - test/rack_statistics_test.rb
108
140
  - test/statue_test.rb
109
141
  - test/stopwatch_test.rb
110
142
  - test/test_helper.rb
143
+ has_rdoc: