active-profiling 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f519cf88d1010c707548ab98932d88d81f2c837
4
+ data.tar.gz: f192a78d710d21019043f58dbe0fe5ba653b616d
5
+ SHA512:
6
+ metadata.gz: f978d65cb2a40cfd1bd50202bb9e1b90ac5d7d16d1aca8e82a4e8d991c6b1dca0784203d93ae79bb2ebbfbc49d21afdbcfa6bea1af000e58b4aa34d579b2d750
7
+ data.tar.gz: c2eb4490ad875b06886b81f4185f7851212243b3977029f8ee6c5fa331fe6049f76d7e83b7526625b15ae441cf5576952d048be289652d55d9d8641d3a6efc59
@@ -1,22 +1,22 @@
1
- Copyright (c) 2012 J Smith <dark.panda@gmail.com>
2
-
3
- Permission is hereby granted, free of charge, to any person
4
- obtaining a copy of this software and associated documentation
5
- files (the "Software"), to deal in the Software without
6
- restriction, including without limitation the rights to use,
7
- copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the
9
- Software is furnished to do so, subject to the following
10
- conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2012-2017 J Smith <dark.panda@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.description = "A Rails profiling suite."
12
12
  s.summary = s.description
13
13
  s.email = "dark.panda@gmail.com"
14
+ s.license = "MIT"
14
15
  s.extra_rdoc_files = [
15
16
  "README.rdoc"
16
17
  ]
@@ -1,6 +1,4 @@
1
1
 
2
- require 'digest/md5'
3
-
4
2
  module ActionController
5
3
  module ActionProfiling
6
4
  extend ActiveSupport::Concern
@@ -9,17 +7,23 @@ module ActionController
9
7
  include ActiveProfiling::RubyProfiler
10
8
  include ActiveProfiling::GCStatistics
11
9
 
12
- around_filter :action_profiler, :if => proc {
10
+ around_filter_method = if ActionController::Base.respond_to?(:around_action)
11
+ :around_action
12
+ else
13
+ :around_filter
14
+ end
15
+
16
+ send around_filter_method, :action_profiler, :if => proc {
13
17
  Rails.application.config.active_profiling.profiler.enabled && ActiveProfiling.ruby_prof?
14
18
  }
15
19
 
16
- around_filter :action_gc_statistics, :if => proc {
20
+ send around_filter_method, :action_gc_statistics, :if => proc {
17
21
  Rails.application.config.active_profiling.gc_statistics.enabled && ActiveProfiling.gc_statistics?
18
22
  }
19
23
  end
20
24
 
21
25
  def action_profiler(*args)
22
- ruby_profiler do
26
+ ruby_profiler(:name => "#{controller_name}.#{action_name}") do
23
27
  yield
24
28
  end
25
29
  end
@@ -1,4 +1,6 @@
1
1
 
2
+ require 'active-profiling/ruby_profiler/output'
3
+
2
4
  module ActiveProfiling
3
5
  module RubyProfiler
4
6
  extend ActiveSupport::Concern
@@ -9,103 +11,8 @@ module ActiveProfiling
9
11
  #
10
12
  # For details on the various options, see the default options located in
11
13
  # ActiveProfiling::Railtie::DEFAULT_PROFILER_OPTIONS.
12
- def ruby_profiler(*args)
13
- options = Rails.application.config.active_profiling.profiler.merge(args.extract_options!)
14
-
15
- printer_class = case options[:printer]
16
- when :flat_with_line_numbers
17
- RubyProf::FlatPrinterWithLineNumbers
18
- else
19
- RubyProf.const_get("#{options[:printer].to_s.camelize}Printer")
20
- end
21
-
22
- output = if options[:output]
23
- options[:output]
24
- else
25
- case options[:printer]
26
- when :call_tree, :call_stack, :graph_html, :dot
27
- :file
28
- else
29
- :log
30
- end
31
- end
32
-
33
- return yield if output == :log && !ActiveProfiling::LogSubscriber.logger
34
-
35
- RubyProf.measure_mode = RubyProf.const_get(options[:measure_mode].to_s.upcase)
36
- GC.disable if options[:disable_gc]
37
-
38
- result = nil
39
- exception = nil
40
- profiler_result = RubyProf.profile do
41
- begin
42
- result = yield
43
- rescue
44
- exception = $!
45
- end
46
- end
47
-
48
- case output
49
- when :stdout
50
- printer_class.new(profiler_result).print($stdout, options.printer_options)
51
- when :log
52
- str = StringIO.new
53
- printer_class.new(profiler_result).print(str, options.printer_options)
54
- str.rewind
55
-
56
- ActiveSupport::Notifications.instrument('profiler_output.active_profiling', {
57
- :profiler_output => str.read,
58
- :title => options[:title] || args.first
59
- })
60
- when :file
61
- path, file_name = if args.first
62
- [ File.dirname(args.first), args.first ]
63
- elsif options[:file_name]
64
- [ File.dirname(options[:file_name]), options[:file_name] ]
65
- else
66
- time = Time.now.strftime('%Y-%m-%d-%H:%M:%S')
67
- hash = Digest::MD5.hexdigest(rand.to_s)[0..6]
68
- path = Rails.root.join('log/profiling', self.class.name.underscore)
69
- ext = case options[:printer]
70
- when :graph_html, :call_stack
71
- 'html'
72
- when :dot
73
- 'dot'
74
- else
75
- 'log'
76
- end
77
-
78
- file_name = [
79
- self.action_name,
80
- options[:measure_mode],
81
- options[:printer],
82
- time,
83
- hash,
84
- ext
85
- ].join('.')
86
-
87
- if options[:printer] == :call_tree && !options[:call_tree_prefix].blank?
88
- file_name = "#{options[:call_tree_prefix]}#{file_name}"
89
- end
90
-
91
- [ path.to_s, path.join(file_name) ]
92
- end
93
-
94
- ActiveSupport::Notifications.instrument('profiler_output_to_file.active_profiling', {
95
- :file_name => file_name
96
- })
97
-
98
- FileUtils.mkdir_p(path)
99
- printer_class.new(profiler_result).print(File.open(file_name, 'w'), options[:printer_options])
100
- end
101
-
102
- if exception
103
- raise exception
104
- else
105
- result
106
- end
107
- ensure
108
- GC.enable if options[:disable_gc]
14
+ def ruby_profiler(*args, &block)
15
+ Output.new(*args).run(&block)
109
16
  end
110
17
  end
111
18
 
@@ -0,0 +1,171 @@
1
+
2
+ module ActiveProfiling
3
+ module RubyProfiler
4
+ class Output
5
+ def initialize(*args)
6
+ @options = Rails.application.config.active_profiling.profiler.merge(args.extract_options!)
7
+ @path = args.first
8
+
9
+ @output = if @options[:output]
10
+ @options[:output]
11
+ else
12
+ case @options[:printer]
13
+ when :call_tree, :call_stack, :graph_html, :dot
14
+ :file
15
+ else
16
+ :log
17
+ end
18
+ end
19
+ end
20
+
21
+ def run
22
+ return yield if @output == :log && !ActiveProfiling::ActionController::LogSubscriber.logger
23
+
24
+ RubyProf.measure_mode = RubyProf.const_get(@options[:measure_mode].to_s.upcase)
25
+ GC.disable if @options[:disable_gc]
26
+
27
+ result = nil
28
+ exception = nil
29
+ @profiler_result = RubyProf.profile do
30
+ begin
31
+ result = yield
32
+ rescue
33
+ exception = $!
34
+ end
35
+ end
36
+
37
+ case @output
38
+ when :stdout
39
+ write_to_stdout
40
+ when :log
41
+ write_to_log
42
+ when :file
43
+ write_to_file_or_path
44
+ end
45
+
46
+ if exception
47
+ raise exception
48
+ else
49
+ result
50
+ end
51
+ ensure
52
+ GC.enable if @options[:disable_gc]
53
+ end
54
+
55
+ private
56
+
57
+ def printer_class
58
+ @printer_class ||= case @options[:printer]
59
+ when :flat_with_line_numbers
60
+ RubyProf::FlatPrinterWithLineNumbers
61
+ else
62
+ RubyProf.const_get("#{@options[:printer].to_s.camelize}Printer")
63
+ end
64
+ end
65
+
66
+ def path_and_file_name
67
+ return @path_and_file_name if defined?(@path_and_file_name)
68
+
69
+ if @path.present?
70
+ { path: File.dirname(@path), file_name: @path }
71
+ elsif @options[:file_name]
72
+ { path: File.dirname(options[:file_name]), file_name: @options[:file_name] }
73
+ else
74
+ time = Time.now.strftime('%Y-%m-%d-%H:%M:%S')
75
+ hash = Digest::MD5.hexdigest(rand.to_s)[0..6]
76
+ path = Rails.root.join('log/profiling')
77
+ ext = case @options[:printer]
78
+ when :graph_html, :call_stack
79
+ 'html'
80
+ when :dot
81
+ 'dot'
82
+ else
83
+ 'log'
84
+ end
85
+
86
+ file_name = [
87
+ @options[:name],
88
+ @options[:measure_mode],
89
+ @options[:printer],
90
+ time,
91
+ hash,
92
+ ext
93
+ ].join('.')
94
+
95
+ @path_and_file_name = {
96
+ path: path.to_s,
97
+ file_name: path.join(file_name)
98
+ }
99
+ end
100
+ end
101
+
102
+ def write_to_stdout
103
+ printer_class.new(@profiler_result).print($stdout, @options)
104
+ end
105
+
106
+ def write_to_log
107
+ str = StringIO.new
108
+ printer_class.new(@profiler_result).print(str, @options[:printer_options])
109
+ str.rewind
110
+
111
+ ActiveSupport::Notifications.instrument('profiler_output.active_profiling', {
112
+ :profiler_output => str.read,
113
+ :title => @options[:title] || @path
114
+ })
115
+ end
116
+
117
+ def write_to_file_or_path
118
+ if call_tree_printer_file_output?
119
+ write_to_path
120
+ else
121
+ write_to_file
122
+ end
123
+ end
124
+
125
+ def write_to_file
126
+ ActiveSupport::Notifications.instrument('profiler_output_to_file.active_profiling', {
127
+ :file_name => path_and_file_name[:file_name]
128
+ })
129
+
130
+ FileUtils.mkdir_p(path_and_file_name[:path])
131
+ printer_class.new(@profiler_result).print(File.open(path_and_file_name[:file_name], 'w'), @options[:printer_options])
132
+ end
133
+
134
+ def write_to_path
135
+ ActiveSupport::Notifications.instrument('profiler_output_to_file.active_profiling', {
136
+ :file_name => path_and_file_name[:path]
137
+ })
138
+
139
+ FileUtils.mkdir_p(path_and_file_name[:path])
140
+ printer_class.new(@profiler_result).print(merged_printer_options(path_and_file_name))
141
+ end
142
+
143
+ def call_tree_prefix_option
144
+ # XXX - Bit of a hack here -- newer versions of RubyProf have changed
145
+ # the method signature of CallTreePrinter#print and changed how the
146
+ # generated files are prefixed. To accomodate call tree viewers like
147
+ # [KQ]CacheGrind, we need to hack in an appropriate file prefix.
148
+ if call_tree_printer_file_output?
149
+ @options[:call_tree_prefix].try(:gsub, /\.$/, '')
150
+ else
151
+ @options[:call_tree_prefix]
152
+ end
153
+ end
154
+
155
+ def merged_printer_options(path_and_file_name)
156
+ if @options[:printer] == :call_tree && @output == :file
157
+ @options[:printer_options].merge(
158
+ profile: call_tree_prefix_option,
159
+ path: path_and_file_name[:path]
160
+ )
161
+ else
162
+ @options[:printer_options]
163
+ end
164
+ end
165
+
166
+ def call_tree_printer_file_output?
167
+ printer_class.instance_method(:print).arity == -1 && printer_class == RubyProf::CallTreePrinter
168
+ end
169
+ end
170
+ end
171
+ end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module ActiveProfiling
3
- VERSION = "0.1.0"
3
+ VERSION = '0.1.1'.freeze
4
4
  end
metadata CHANGED
@@ -1,32 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active-profiling
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.0
4
+ version: 0.1.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - J Smith
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-03 00:00:00.000000000 Z
11
+ date: 2017-04-17 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rails
16
- type: :runtime
17
15
  requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '3.0'
22
- none: false
20
+ type: :runtime
21
+ prerelease: false
23
22
  version_requirements: !ruby/object:Gem::Requirement
24
23
  requirements:
25
- - - ! '>='
24
+ - - ">="
26
25
  - !ruby/object:Gem::Version
27
26
  version: '3.0'
28
- none: false
29
- prerelease: false
30
27
  description: A Rails profiling suite.
31
28
  email: dark.panda@gmail.com
32
29
  executables: []
@@ -34,7 +31,7 @@ extensions: []
34
31
  extra_rdoc_files:
35
32
  - README.rdoc
36
33
  files:
37
- - .gitignore
34
+ - ".gitignore"
38
35
  - Gemfile
39
36
  - MIT-LICENSE
40
37
  - README.rdoc
@@ -49,32 +46,30 @@ files:
49
46
  - lib/active-profiling/gc_statistics.rb
50
47
  - lib/active-profiling/railtie.rb
51
48
  - lib/active-profiling/ruby_profiler.rb
49
+ - lib/active-profiling/ruby_profiler/output.rb
52
50
  - lib/active-profiling/version.rb
53
51
  homepage: http://github.com/dark-panda/active-profiling
54
- licenses: []
52
+ licenses:
53
+ - MIT
54
+ metadata: {}
55
55
  post_install_message:
56
56
  rdoc_options: []
57
57
  require_paths:
58
58
  - lib
59
59
  required_ruby_version: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ! '>='
61
+ - - ">="
62
62
  - !ruby/object:Gem::Version
63
- segments:
64
- - 0
65
- hash: 1112450418277949513
66
63
  version: '0'
67
- none: false
68
64
  required_rubygems_version: !ruby/object:Gem::Requirement
69
65
  requirements:
70
- - - ! '>='
66
+ - - ">="
71
67
  - !ruby/object:Gem::Version
72
68
  version: '0'
73
- none: false
74
69
  requirements: []
75
70
  rubyforge_project:
76
- rubygems_version: 1.8.24
71
+ rubygems_version: 2.6.11
77
72
  signing_key:
78
- specification_version: 3
73
+ specification_version: 4
79
74
  summary: A Rails profiling suite.
80
75
  test_files: []