tunemygc 1.0.34 → 1.0.35
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +29 -18
- data/lib/tunemygc/agent.rb +0 -2
- data/lib/tunemygc/cli.rb +9 -7
- data/lib/tunemygc/network.rb +8 -0
- data/lib/tunemygc/spies/action_controller.rb +12 -8
- data/lib/tunemygc/spies/active_job.rb +4 -9
- data/lib/tunemygc/spies/base.rb +5 -0
- data/lib/tunemygc/spies/minitest.rb +4 -9
- data/lib/tunemygc/spies/rspec.rb +4 -9
- data/lib/tunemygc/syncer.rb +3 -10
- data/lib/tunemygc/version.rb +1 -1
- data/test/test_syncer.rb +0 -6
- metadata +2 -3
- data/lib/tunemygc/configurator.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dee917a9ec1d9d1433370df607a9fffebf3770c2
|
4
|
+
data.tar.gz: 417022d4328e4efe72d6bffac93b57890288b5a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57b3e42ca8b6274972d1cd2dfa47fb20d100497d0238293b45589d83a2549fbcba234d8cec0d0906060922c8ad3c2938b4eaf6ba473a3630072a5dd9936ae7e7
|
7
|
+
data.tar.gz: be9de035273d60d524df9b1e57e5e81a5dbe4e00a572d4ae75109333627db574159541aad560e1fa219665e588eda613ecea81c325a5f5b76a39f4bb93458732
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -8,6 +8,8 @@ The Ruby garbage collector has been flagged as the crux of Ruby performance and
|
|
8
8
|
|
9
9
|
![tunemygc workflow diagram](https://raw.githubusercontent.com/bear-metal/tunemygc/master/assets/tunemygc-graphic2x-80dac1571cacc70d9b272bb62ae9f6df.png?token=AAABe8sM_ofiQkrCpNw7OYRbtHMLO9l5ks5UuQlYwA%3D%3D)
|
10
10
|
|
11
|
+
We also recently [blogged](http://bearmetal.eu/theden/2015-02-20-rails-garbage-collection-tuning-approaches) about how the product works.
|
12
|
+
|
11
13
|
## Benefits
|
12
14
|
|
13
15
|
* Faster boot times
|
@@ -33,6 +35,7 @@ Add to your Gemfile and run `bundle install`
|
|
33
35
|
``` sh
|
34
36
|
gem 'tunemygc'
|
35
37
|
```
|
38
|
+
|
36
39
|
This gem linterposes itself into the application and piggy backs off the new GC events in Ruby 2.x for introspection. Tuning recommendations are handled through a web service at `https://tunemygc.com`. You will need MRI Ruby `2.1`, or later. [Rails](http://www.rubyonrails.org) applications, background jobs, tests and any proprietary Ruby scripts and frameworks are supported.
|
37
40
|
|
38
41
|
## Getting started
|
@@ -52,6 +55,14 @@ For the above command sequences, to sample your app or script for tuning, run (i
|
|
52
55
|
RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails s
|
53
56
|
```
|
54
57
|
|
58
|
+
And after some profiling requests, when the process terminates, you can visit the given report URL for a config recommendation and some further insights:
|
59
|
+
|
60
|
+
``` sh
|
61
|
+
[TuneMyGC, pid: 70160] Syncing 688 snapshots
|
62
|
+
[TuneMyGC, pid: 70160] ==== Recommended GC configs for ActionController
|
63
|
+
[TuneMyGC, pid: 70160] Please visit https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818 to view your configuration and other Garbage Collector insights
|
64
|
+
```
|
65
|
+
|
55
66
|
The CLI interface supports retrieving configuration options for your application as well.
|
56
67
|
|
57
68
|
``` sh
|
@@ -81,12 +92,20 @@ Application registered. Use RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 in yo
|
|
81
92
|
|
82
93
|
Enables the interposer for taking a few lightweight snapshots of Rails requests and submitting them to `tunemygc.com`. Without this environment variable set, it won't interpose itself.
|
83
94
|
|
84
|
-
For the above command sequences, to sample
|
95
|
+
For the above command sequences, to sample a Rails app for tuning, run:
|
85
96
|
|
86
97
|
``` sh
|
87
98
|
RUBY_GC_TOKEN=08de9e8822c847244b31290cedfc1d51 RUBY_GC_TUNE=1 bundle exec rails s
|
88
99
|
```
|
89
100
|
|
101
|
+
And after some profiling requests, when the process terminates, you can visit the given report URL for a config recommendation and some further insights:
|
102
|
+
|
103
|
+
``` sh
|
104
|
+
[TuneMyGC, pid: 70160] Syncing 688 snapshots
|
105
|
+
[TuneMyGC, pid: 70160] ==== Recommended GC configs for ActionController
|
106
|
+
[TuneMyGC, pid: 70160] Please visit https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818 to view your configuration and other Garbage Collector insights
|
107
|
+
```
|
108
|
+
|
90
109
|
#### Advanced
|
91
110
|
|
92
111
|
* `RUBY_GC_SPY=action_controller` (Spy on the GC for this type of processing. `action_controller`, `active_job`, `minitest` or `rspec` are supported)
|
@@ -107,26 +126,16 @@ Controls the interposer lifetime for sampling a [minitest](https://github.com/se
|
|
107
126
|
|
108
127
|
## How do I use this?
|
109
128
|
|
110
|
-
This gem is only a lightweight agent and designed to not get in your way.
|
129
|
+
This gem is only a lightweight agent and designed to not get in your way. It samples your application during runtime, syncs data with our web service when it terminates and we provide a report URL where you can view a suggested GC configuration and additional tips and insights.
|
111
130
|
|
112
|
-
#### Interpreting
|
131
|
+
#### Interpreting results
|
113
132
|
|
114
|
-
An instrumented process dumps a reccommended config to the Rails logger.
|
133
|
+
An instrumented process dumps a report URL with a reccommended config to the Rails logger.
|
115
134
|
|
116
135
|
``` sh
|
117
|
-
[TuneMyGC] Syncing 688 snapshots
|
118
|
-
[TuneMyGC] ==== Recommended GC configs
|
119
|
-
[TuneMyGC]
|
120
|
-
[TuneMyGC] export RUBY_GC_HEAP_FREE_SLOTS=603850
|
121
|
-
[TuneMyGC] export RUBY_GC_HEAP_GROWTH_FACTOR=1.2
|
122
|
-
[TuneMyGC] export RUBY_GC_HEAP_GROWTH_MAX_SLOTS=301925
|
123
|
-
[TuneMyGC] export RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=2.0
|
124
|
-
[TuneMyGC] export RUBY_GC_MALLOC_LIMIT=35818030
|
125
|
-
[TuneMyGC] export RUBY_GC_MALLOC_LIMIT_MAX=42981636
|
126
|
-
[TuneMyGC] export RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.32
|
127
|
-
[TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT=32782669
|
128
|
-
[TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT_MAX=49174003.5
|
129
|
-
[TuneMyGC] export RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
|
136
|
+
[TuneMyGC, pid: 70160] Syncing 688 snapshots
|
137
|
+
[TuneMyGC, pid: 70160] ==== Recommended GC configs for ActionController
|
138
|
+
[TuneMyGC, pid: 70160] Please visit https://tunemygc.com/configs/d739119e4abc38d42e183d1361991818 to view your configuration and other Garbage Collector insights
|
130
139
|
```
|
131
140
|
|
132
141
|
We're still in the process of building tools and a launcher shim around this. You can also retrieve the last known configuration for you app via the CLI interface:
|
@@ -148,9 +157,11 @@ export RUBY_GC_OLDMALLOC_LIMIT_MAX=49174003.5
|
|
148
157
|
export RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=1.2
|
149
158
|
```
|
150
159
|
|
160
|
+
We're busy working on adding tips on the report URLs for some common problem contexts.
|
161
|
+
|
151
162
|
#### Heroku and 12 factor
|
152
163
|
|
153
|
-
We have a [Heroku](http://www.heroku.com) addon in Alpha testing and the Ruby GC lends itself well to tuning through 12 factor principles as it's designed around environment variables.
|
164
|
+
We have a [Heroku](http://www.heroku.com) addon in Alpha testing and the Ruby GC lends itself well to tuning through [12 factor](http://12factor.net) principles as it's designed around environment variables.
|
154
165
|
|
155
166
|
## Security and privacy concerns
|
156
167
|
|
data/lib/tunemygc/agent.rb
CHANGED
@@ -48,8 +48,6 @@ module TuneMyGc
|
|
48
48
|
require "tunemygc/syncer"
|
49
49
|
syncer = TuneMyGc::Syncer.new
|
50
50
|
config = syncer.sync(snapshotter)
|
51
|
-
require "tunemygc/configurator"
|
52
|
-
TuneMyGc::Configurator.new(config).configure
|
53
51
|
end
|
54
52
|
rescue Exception => e
|
55
53
|
log "Config reccommendation error (#{e.message})"
|
data/lib/tunemygc/cli.rb
CHANGED
@@ -5,7 +5,7 @@ require 'optparse'
|
|
5
5
|
|
6
6
|
module TuneMyGc
|
7
7
|
class CLI
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :client, :options
|
9
9
|
|
10
10
|
def self.start(args)
|
11
11
|
args = ["-h"] if args.empty?
|
@@ -29,12 +29,14 @@ module TuneMyGc
|
|
29
29
|
|
30
30
|
def initialize(options)
|
31
31
|
@options = options
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
@client = TuneMyGc.http_client
|
33
|
+
if options[:email]
|
34
|
+
register
|
35
|
+
elsif options[:config]
|
36
|
+
fetch_config
|
37
|
+
else
|
38
|
+
raise ArgumentError, "Invalid CLI argument: you can either register or retrieve your last known GC config"
|
39
|
+
end
|
38
40
|
end
|
39
41
|
|
40
42
|
def register
|
data/lib/tunemygc/network.rb
CHANGED
@@ -6,4 +6,12 @@ require 'timeout'
|
|
6
6
|
|
7
7
|
module TuneMyGc
|
8
8
|
NETWORK_TIMEOUT = 30 #seconds
|
9
|
+
|
10
|
+
def self.http_client
|
11
|
+
uri = URI("https://#{TuneMyGc::HOST}")
|
12
|
+
client = Net::HTTP.new(uri.host, uri.port)
|
13
|
+
client.use_ssl = true
|
14
|
+
client.read_timeout = NETWORK_TIMEOUT
|
15
|
+
client
|
16
|
+
end
|
9
17
|
end
|
@@ -32,14 +32,13 @@ module TuneMyGc
|
|
32
32
|
attr_reader :subscriptions
|
33
33
|
|
34
34
|
def initialize
|
35
|
+
super
|
35
36
|
@subscriptions = []
|
36
|
-
@requests_processed = 0
|
37
|
-
@requests_limit = nil
|
38
37
|
end
|
39
38
|
|
40
39
|
def install
|
41
|
-
|
42
|
-
|
40
|
+
subscription(/^start_processing.action_controller$/, TuneMyGc::StartRequestSubscriber.new)
|
41
|
+
subscription(/^process_action.action_controller$/, TuneMyGc::EndRequestSubscriber.new)
|
43
42
|
TuneMyGc.log "hooked: action_controller"
|
44
43
|
end
|
45
44
|
|
@@ -53,14 +52,19 @@ module TuneMyGc
|
|
53
52
|
|
54
53
|
def check_uninstall
|
55
54
|
if ENV["RUBY_GC_TUNE_REQUESTS"]
|
56
|
-
@
|
57
|
-
@
|
58
|
-
if @
|
55
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_REQUESTS"])
|
56
|
+
@processed += 1
|
57
|
+
if @processed == @limit
|
59
58
|
uninstall
|
60
|
-
TuneMyGc.log "kamikaze after #{@
|
59
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} requests"
|
61
60
|
end
|
62
61
|
end
|
63
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def subscription(pattern, handler)
|
66
|
+
@subscriptions << ActiveSupport::Notifications.subscribe(pattern, handler)
|
67
|
+
end
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
@@ -5,11 +5,6 @@ require 'active_job'
|
|
5
5
|
module TuneMyGc
|
6
6
|
module Spies
|
7
7
|
class ActiveJob < TuneMyGc::Spies::Base
|
8
|
-
def initialize
|
9
|
-
@jobs_processed = 0
|
10
|
-
@jobs_limit = nil
|
11
|
-
end
|
12
|
-
|
13
8
|
def install
|
14
9
|
::ActiveJob::Base.__send__(:include, hooks_module)
|
15
10
|
TuneMyGc.log "hooked: active_job"
|
@@ -24,11 +19,11 @@ module TuneMyGc
|
|
24
19
|
|
25
20
|
def check_uninstall
|
26
21
|
if ENV["RUBY_GC_TUNE_JOBS"]
|
27
|
-
@
|
28
|
-
@
|
29
|
-
if @
|
22
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_JOBS"])
|
23
|
+
@processed += 1
|
24
|
+
if @processed == @limit
|
30
25
|
uninstall
|
31
|
-
TuneMyGc.log "kamikaze after #{@
|
26
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} jobs"
|
32
27
|
end
|
33
28
|
end
|
34
29
|
end
|
data/lib/tunemygc/spies/base.rb
CHANGED
@@ -5,11 +5,6 @@ require 'minitest'
|
|
5
5
|
module TuneMyGc
|
6
6
|
module Spies
|
7
7
|
class Minitest < TuneMyGc::Spies::Base
|
8
|
-
def initialize
|
9
|
-
@tests_processed = 0
|
10
|
-
@tests_limit = nil
|
11
|
-
end
|
12
|
-
|
13
8
|
def install
|
14
9
|
MiniTest::Unit::TestCase.__send__(:include, hooks_module)
|
15
10
|
TuneMyGc.log "hooked: minitest"
|
@@ -24,11 +19,11 @@ module TuneMyGc
|
|
24
19
|
|
25
20
|
def check_uninstall
|
26
21
|
if ENV["RUBY_GC_TUNE_TESTS"]
|
27
|
-
@
|
28
|
-
@
|
29
|
-
if @
|
22
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
|
23
|
+
@processed += 1
|
24
|
+
if @processed == @limit
|
30
25
|
uninstall
|
31
|
-
TuneMyGc.log "kamikaze after #{@
|
26
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} tests"
|
32
27
|
end
|
33
28
|
end
|
34
29
|
end
|
data/lib/tunemygc/spies/rspec.rb
CHANGED
@@ -9,11 +9,6 @@ end
|
|
9
9
|
module TuneMyGc
|
10
10
|
module Spies
|
11
11
|
class Rspec < TuneMyGc::Spies::Base
|
12
|
-
def initialize
|
13
|
-
@tests_processed = 0
|
14
|
-
@tests_limit = nil
|
15
|
-
end
|
16
|
-
|
17
12
|
def install
|
18
13
|
RSpec::Core.__send__(:include, hooks_module)
|
19
14
|
TuneMyGc.log "hooked: rspec"
|
@@ -28,11 +23,11 @@ module TuneMyGc
|
|
28
23
|
|
29
24
|
def check_uninstall
|
30
25
|
if ENV["RUBY_GC_TUNE_TESTS"]
|
31
|
-
@
|
32
|
-
@
|
33
|
-
if @
|
26
|
+
@limit ||= Integer(ENV["RUBY_GC_TUNE_TESTS"])
|
27
|
+
@processed += 1
|
28
|
+
if @processed == @limit
|
34
29
|
uninstall
|
35
|
-
TuneMyGc.log "kamikaze after #{@
|
30
|
+
TuneMyGc.log "kamikaze after #{@processed} of #{@limit} tests"
|
36
31
|
end
|
37
32
|
end
|
38
33
|
end
|
data/lib/tunemygc/syncer.rb
CHANGED
@@ -6,13 +6,10 @@ module TuneMyGc
|
|
6
6
|
class Syncer
|
7
7
|
ENVIRONMENT = [ENV['RUBY_GC_TOKEN'], RUBY_VERSION, TuneMyGc.rails_version, ENV.select {|k,v| k =~ /RUBY_GC_/ }, TuneMyGc::VERSION, GC::OPTS, GC::INTERNAL_CONSTANTS].freeze
|
8
8
|
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :client
|
10
10
|
|
11
11
|
def initialize(host = TuneMyGc::HOST)
|
12
|
-
@
|
13
|
-
@client = Net::HTTP.new(@uri.host, @uri.port)
|
14
|
-
@client.use_ssl = (uri.port == 443)
|
15
|
-
@client.read_timeout = NETWORK_TIMEOUT
|
12
|
+
@client = TuneMyGc.http_client
|
16
13
|
end
|
17
14
|
|
18
15
|
def sync(snapshotter)
|
@@ -58,7 +55,7 @@ module TuneMyGc
|
|
58
55
|
payload << snapshot
|
59
56
|
end
|
60
57
|
data = ActiveSupport::JSON.encode(payload)
|
61
|
-
response = client.post(
|
58
|
+
response = client.post('/ruby', data, TuneMyGc::HEADERS)
|
62
59
|
snapshotter.unit_of_work = false
|
63
60
|
if Net::HTTPNotFound === response
|
64
61
|
TuneMyGc.log "Invalid application token. Please generate one with 'bundle exec tunemygc <a_valid_email_address>' and set the RUBY_GC_TOKEN environment variable"
|
@@ -94,11 +91,7 @@ module TuneMyGc
|
|
94
91
|
|
95
92
|
def process_config_callback(response)
|
96
93
|
report_url = response.body.gsub(/\.json$/, '')
|
97
|
-
config = client.get(URI(response.body).path)
|
98
|
-
ActiveSupport::JSON.decode(config.body).merge('report' => report_url)
|
99
|
-
rescue Exception => e
|
100
94
|
TuneMyGc.log "Please visit #{report_url} to view your configuration and other Garbage Collector insights"
|
101
|
-
return false
|
102
95
|
end
|
103
96
|
end
|
104
97
|
end
|
data/lib/tunemygc/version.rb
CHANGED
data/test/test_syncer.rb
CHANGED
@@ -3,12 +3,6 @@
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'helper')
|
4
4
|
|
5
5
|
class TestSyncer < TuneMyGcTestCase
|
6
|
-
def test_uri
|
7
|
-
syncer = TuneMyGc::Syncer.new
|
8
|
-
assert_equal "tunemygc.com", syncer.uri.host
|
9
|
-
assert_equal 443, syncer.uri.port
|
10
|
-
end
|
11
|
-
|
12
6
|
def test_client
|
13
7
|
syncer = TuneMyGc::Syncer.new
|
14
8
|
assert_instance_of Net::HTTP, syncer.client
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tunemygc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.35
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bear Metal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: certified
|
@@ -139,7 +139,6 @@ files:
|
|
139
139
|
- lib/tunemygc.rb
|
140
140
|
- lib/tunemygc/agent.rb
|
141
141
|
- lib/tunemygc/cli.rb
|
142
|
-
- lib/tunemygc/configurator.rb
|
143
142
|
- lib/tunemygc/interposer.rb
|
144
143
|
- lib/tunemygc/network.rb
|
145
144
|
- lib/tunemygc/railtie.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TuneMyGc
|
4
|
-
class Configurator
|
5
|
-
attr_reader :config
|
6
|
-
|
7
|
-
def initialize(config)
|
8
|
-
@config = config
|
9
|
-
end
|
10
|
-
|
11
|
-
def configure
|
12
|
-
if Hash === config && !config.empty?
|
13
|
-
TuneMyGc.log "==== Recommended GC configs for #{TuneMyGCc::Spies.current}: #{config.delete("report")}"
|
14
|
-
write_env("Speed")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def write_env(strategy)
|
20
|
-
config.delete(strategy).each do |var,val|
|
21
|
-
TuneMyGc.log "export #{var}=#{val}"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|