corn 0.5.6 → 0.5.7.beta1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2128d61b559f2364bb060b87e258069ed0573622
4
- data.tar.gz: 84dadacc4a71ad7b6c33209ef3cf1c5829e91936
3
+ metadata.gz: 8cd2ed0bc9b102eca18ed7e80ea7a9313702fc02
4
+ data.tar.gz: 6ce6d074da698b05112110f83635b497f8453735
5
5
  SHA512:
6
- metadata.gz: fa94880e60a3bf2e53e8901fc13e62d74424708c67d1f0c9848bbc63bcf825fc5c286298ca3ea0da847a315cc516fbb075ead74f4f1fd881ce17d4d3ee5a1ac0
7
- data.tar.gz: 7791a5595a58ac89cf35ec041112ee78999e14f17665f8adf168f8f32b3bb78f28b75d2e3dc7f46ac58f7a4ecad7a612f88a4bc5ebe105a57c3c3857d46a9713
6
+ metadata.gz: 07ad76f726b438be79b29f51144c913fd1f413abbd221c2c0beff3c9453db7a439441de4080bc4ebb111c330ef5c6c7f727709f8605b0aeca26925f3920eb22e
7
+ data.tar.gz: 5d216ec62d5c8d3ccc111d7aee67b3740a3b1c4899023479ed725b27fe3855fd6c27afbaa8322d673d321c28d94471aa2590a65592532d190ad96ce84e6311d6
data/lib/corn.rb CHANGED
@@ -33,9 +33,12 @@ module Corn
33
33
  :rack_middleware => Rack::SlowRequestProfiler,
34
34
  :rack_slow_request_profiler => Rack::SlowRequestProfiler,
35
35
  :slow_request_threshold => 5,
36
+ :fast_request_threshold => lambda { [Corn.sampling_interval * 5, Corn.slow_request_threshold.to_f / 5].max },
36
37
  :profiling => true,
37
38
  :sampling_interval => 0.1,
38
- :post_interval => 2
39
+ :post_interval => 2,
40
+ :post_fast_request_interval => 60, #seconds
41
+ :fast_request_sampling_limit => 1024 * 1024 * 2 #2MB
39
42
  })
40
43
 
41
44
  module_function
data/lib/corn/post.rb CHANGED
@@ -5,9 +5,12 @@ require 'time'
5
5
 
6
6
  module Corn
7
7
  class Post
8
- def initialize(interval)
8
+ def initialize(interval, sampling_limit, sampling_time)
9
9
  @queue = Queue.new
10
10
  @thread = start_post_thread(interval)
11
+ @sampling_limit = sampling_limit
12
+ @sampling_time = sampling_time
13
+ reset_sampling
11
14
  end
12
15
 
13
16
  def terminate
@@ -24,8 +27,21 @@ module Corn
24
27
  Thread.start do
25
28
  begin
26
29
  loop do
27
- http_post(@queue.pop)
28
- sleep interval
30
+ d = @queue.pop
31
+ case d[:action]
32
+ when :post
33
+ http_post([d])
34
+ sleep interval
35
+ when :sampling
36
+ @sampling << d
37
+ if Time.now - @sampling_start > @sampling_time
38
+ http_post(@sampling.items, :sampling)
39
+ reset_sampling
40
+ sleep interval
41
+ end
42
+ else
43
+ Corn.logger.info("Corn: Ignore unknown action: #{d[:action]}")
44
+ end
29
45
  end
30
46
  rescue => e
31
47
  Corn.logger.error("Corn post thread stopped by error #{e.message}\n#{e.backtrace.join("\n")}")
@@ -34,14 +50,25 @@ module Corn
34
50
  end
35
51
 
36
52
  def enqueue(data)
37
- return if data.nil?
53
+ return if data.nil? || data.empty?
38
54
  @queue << data
39
55
  end
40
56
 
41
- def http_post(data)
57
+ def http_post(reports, type=nil)
42
58
  uri = URI.parse(submit_url)
43
59
  req = Net::HTTP::Post.new(uri.path)
44
- req.set_form_data(data.merge('client_id' => Corn.client_id))
60
+ form_data = [['client_id', Corn.client_id]]
61
+ if type
62
+ form_data << ['type', type]
63
+ end
64
+ reports.each_with_index do |rep, i|
65
+ [:name, :start_at, :end_at, :data].each do |k|
66
+ if v = rep[k]
67
+ form_data << ["reports[][#{k}]", v]
68
+ end
69
+ end
70
+ end
71
+ req.set_form_data(form_data)
45
72
 
46
73
  http = Net::HTTP.new(uri.host, uri.port)
47
74
  if uri.scheme == 'https'
@@ -55,7 +82,7 @@ module Corn
55
82
  end
56
83
  end
57
84
  res = http.request(req)
58
- Corn.logger.info("Corn report submitted to #{submit_url}")
85
+ Corn.logger.info("Corn reports(#{reports.size}) submitted to #{submit_url}")
59
86
  unless res.is_a?(Net::HTTPSuccess)
60
87
  Corn.logger.error("Post failed: #{res.message}(#{res.code}), response body: \n#{res.body}")
61
88
  end
@@ -66,5 +93,11 @@ module Corn
66
93
  def submit_url
67
94
  Corn.submit_url
68
95
  end
96
+
97
+ private
98
+ def reset_sampling
99
+ @sampling = ReservoirSampling.new(@sampling_limit)
100
+ @sampling_start = Time.now
101
+ end
69
102
  end
70
103
  end
data/lib/corn/profiler.rb CHANGED
@@ -3,8 +3,9 @@ require 'sampling_prof'
3
3
 
4
4
  module Corn
5
5
  class Profiler
6
- def initialize(post_interval, sampling_interval)
7
- @post = Post.new(post_interval)
6
+ def initialize(post_interval, post_sampling_limit, post_sampling_time,
7
+ sampling_interval)
8
+ @post = Post.new(post_interval, post_sampling_limit, post_sampling_time)
8
9
  @prof = SamplingProf.new(sampling_interval)
9
10
  at_exit { terminate }
10
11
  end
@@ -31,9 +31,9 @@ module Corn
31
31
  name = "#{name}?#{@env[:query_string]}"
32
32
  end
33
33
  {
34
- 'report[name]' => name,
35
- 'report[start_at]' => @env[:start_time].iso8601,
36
- 'report[end_at]' => end_at.iso8601
34
+ :name => name,
35
+ :start_at => @env[:start_time].iso8601,
36
+ :end_at => end_at.iso8601
37
37
  }
38
38
  end
39
39
  end
@@ -1,4 +1,6 @@
1
+ require 'thread'
1
2
  require 'corn/profiler'
3
+ require 'corn/reservoir_sampling'
2
4
  require 'corn/rack/request_env'
3
5
 
4
6
  module Corn
@@ -7,8 +9,11 @@ module Corn
7
9
  class ProfilingApp
8
10
  def initialize(app)
9
11
  @@prof ||= Profiler.new(Corn.post_interval,
12
+ Corn.fast_request_sampling_limit,
13
+ Corn.post_fast_request_interval,
10
14
  Corn.sampling_interval)
11
15
  @app = app
16
+
12
17
  Corn.logger.info("Corn sampling interval: #{Corn.sampling_interval}")
13
18
  Corn.logger.info("Corn slow request threshold: #{Corn.slow_request_threshold}")
14
19
  end
@@ -29,11 +34,20 @@ module Corn
29
34
  def output_handler(env)
30
35
  request_env = RequestEnv.new(env)
31
36
  lambda do |data|
32
- if request_env.time > Corn.slow_request_threshold
33
- request_env.to_report.merge("data" => data)
37
+ t = request_env.time
38
+ if t < fast_request_threshold || t > slow_request_threshold
39
+ action = t > Corn.slow_request_threshold ? :post : :sampling
40
+ request_env.to_report.merge(:data => data, :action => action)
34
41
  end
35
42
  end
36
43
  end
44
+
45
+ def fast_request_threshold
46
+ @frt ||= Corn.fast_request_threshold
47
+ end
48
+ def slow_request_threshold
49
+ @srt ||= Corn.slow_request_threshold
50
+ end
37
51
  end
38
52
 
39
53
  def initialize(app)
@@ -44,6 +58,7 @@ module Corn
44
58
  @app.call(env)
45
59
  end
46
60
 
61
+ # for test
47
62
  def terminate
48
63
  @app.terminate if @app.respond_to?(:terminate)
49
64
  end
@@ -0,0 +1,29 @@
1
+ module Corn
2
+ class ReservoirSampling
3
+ attr_reader :items
4
+ def initialize(limit)
5
+ @limit = limit
6
+ @items = []
7
+ @size = -1
8
+ @count = 0
9
+ end
10
+
11
+ def <<(item)
12
+ @count += 1
13
+ if @size < 0 && bytesize < @limit
14
+ items << item
15
+ else
16
+ @size = items.size
17
+ j = rand(@count).to_i
18
+ if j < @size
19
+ items[j] = item
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+ def bytesize
26
+ items.map{|d|d[:data].bytesize}.reduce(:+) || 0
27
+ end
28
+ end
29
+ end
@@ -56,7 +56,7 @@ Corn.config({
56
56
  # called. So you can also use it to turn on profiling by a request parameter.
57
57
  # For example: Corn.config(:profiling => lambda {|env| env["QUERY_STRING"] =~ /corn_profiling=true/ })
58
58
  # This configuration will be checked for every request, so don't do anything
59
- # expense here.
59
+ # expensive here.
60
60
  # :profiling => true,
61
61
  })
62
62
  # Install corn rack middleware for profiling slow requests
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.5.7.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xiao Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-10 00:00:00.000000000 Z
11
+ date: 2014-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sampling_prof
@@ -38,6 +38,7 @@ files:
38
38
  - lib/corn/post.rb
39
39
  - lib/corn/profiler.rb
40
40
  - lib/corn/rack.rb
41
+ - lib/corn/reservoir_sampling.rb
41
42
  - lib/corn/rack/request_env.rb
42
43
  - lib/corn/rack/slow_request_profiler.rb
43
44
  - lib/generators/corn/config/config_generator.rb
@@ -56,9 +57,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
57
  version: '0'
57
58
  required_rubygems_version: !ruby/object:Gem::Requirement
58
59
  requirements:
59
- - - '>='
60
+ - - '>'
60
61
  - !ruby/object:Gem::Version
61
- version: '0'
62
+ version: 1.3.1
62
63
  requirements: []
63
64
  rubyforge_project:
64
65
  rubygems_version: 2.1.9