stackprof-route_middleware 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 93270cfc54a37b370613a770cd325d4986a6008718264fff0986938c129562c9
4
+ data.tar.gz: 802f0efb4202cd3e1e8ba96b80ddfb96427d1f23059a1865ca3b6098cb04a472
5
+ SHA512:
6
+ metadata.gz: f91e8c04fac2d7a9cd29ae569c7f0caa6f163f2aa0ed694ba2976fbccf38765c891beb1bd72309d96692a8005983f217ee62d8ea5260cb5f4b41e9919b0a922b
7
+ data.tar.gz: 54f68f9d3af105c4ff52054b2bc5096858eca1e6ee80684cffd84fe209d25ab126a82d1562617c846a796f59a38dc01b6eeb7c24debfb7cedb3a095b34bdda26
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/testdouble/standard
3
+ ruby_version: 3.0
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in stackprof-route_middleware.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "standard", "~> 1.3"
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ stackprof-route_middleware (0.1.0)
5
+ stackprof
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ diff-lcs (1.5.0)
12
+ json (2.7.1)
13
+ language_server-protocol (3.17.0.3)
14
+ lint_roller (1.1.0)
15
+ parallel (1.24.0)
16
+ parser (3.2.2.4)
17
+ ast (~> 2.4.1)
18
+ racc
19
+ racc (1.7.3)
20
+ rainbow (3.1.1)
21
+ rake (13.1.0)
22
+ regexp_parser (2.8.3)
23
+ rexml (3.2.6)
24
+ rspec (3.12.0)
25
+ rspec-core (~> 3.12.0)
26
+ rspec-expectations (~> 3.12.0)
27
+ rspec-mocks (~> 3.12.0)
28
+ rspec-core (3.12.2)
29
+ rspec-support (~> 3.12.0)
30
+ rspec-expectations (3.12.3)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.12.0)
33
+ rspec-mocks (3.12.6)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.12.0)
36
+ rspec-support (3.12.1)
37
+ rubocop (1.59.0)
38
+ json (~> 2.3)
39
+ language_server-protocol (>= 3.17.0)
40
+ parallel (~> 1.10)
41
+ parser (>= 3.2.2.4)
42
+ rainbow (>= 2.2.2, < 4.0)
43
+ regexp_parser (>= 1.8, < 3.0)
44
+ rexml (>= 3.2.5, < 4.0)
45
+ rubocop-ast (>= 1.30.0, < 2.0)
46
+ ruby-progressbar (~> 1.7)
47
+ unicode-display_width (>= 2.4.0, < 3.0)
48
+ rubocop-ast (1.30.0)
49
+ parser (>= 3.2.1.0)
50
+ rubocop-performance (1.20.1)
51
+ rubocop (>= 1.48.1, < 2.0)
52
+ rubocop-ast (>= 1.30.0, < 2.0)
53
+ ruby-progressbar (1.13.0)
54
+ stackprof (0.2.25)
55
+ standard (1.33.0)
56
+ language_server-protocol (~> 3.17.0.2)
57
+ lint_roller (~> 1.0)
58
+ rubocop (~> 1.59.0)
59
+ standard-custom (~> 1.0.0)
60
+ standard-performance (~> 1.3)
61
+ standard-custom (1.0.2)
62
+ lint_roller (~> 1.0)
63
+ rubocop (~> 1.50)
64
+ standard-performance (1.3.0)
65
+ lint_roller (~> 1.1)
66
+ rubocop-performance (~> 1.20.1)
67
+ unicode-display_width (2.5.0)
68
+
69
+ PLATFORMS
70
+ arm64-darwin-21
71
+ arm64-darwin-22
72
+
73
+ DEPENDENCIES
74
+ rake (~> 13.0)
75
+ rspec (~> 3.0)
76
+ stackprof-route_middleware!
77
+ standard (~> 1.3)
78
+
79
+ BUNDLED WITH
80
+ 2.3.15
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Yusuke Sangenya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # StackProf::RouteMiddleware
2
+
3
+ Yet another `StackProf::Middleware` which saves dump files by each application route.
4
+
5
+ ## Usage
6
+
7
+ ### Sinatra
8
+
9
+ Sample configuration:
10
+
11
+ ```ruby
12
+ use StackProf::RouteMiddleware,
13
+ enabled: true,
14
+ mode: :wall,
15
+ interval: 1000,
16
+ raw: true,
17
+ route_calculator: proc { |env| env['sinatra.route'] }
18
+ ```
19
+
20
+ Results in:
21
+
22
+ ```bash
23
+ $ ls -alh tmp/
24
+ $ ls -alh tmp | head
25
+ total 24632
26
+ drwxr-xr-x@ 2261 sangenya staff 71K 1 1 22:48 .
27
+ drwxr-xr-x 16 sangenya staff 512B 1 1 22:57 ..
28
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-GET__api_chair__id-wall-97768-1704116922.dump
29
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-GET__api_chair__id-wall-97768-1704116923.dump
30
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-GET__api_chair__id-wall-97768-1704116924.dump
31
+ ...
32
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-POST__api_estate_req_doc__id-wall-97783-1704116920.dump
33
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-POST__api_estate_req_doc__id-wall-97783-1704116921.dump
34
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-POST__api_estate_req_doc__id-wall-97783-1704116922.dump
35
+ -rw-r--r-- 1 sangenya staff 109B 1 1 22:48 stackprof-POST__api_estate_req_doc__id-wall-97783-1704116923.dump
36
+ ```
37
+
38
+ So you can analyze a specific route:
39
+
40
+ ```bash
41
+ $ bundle exec stackprof tmp/stackprof-GET__api_estate_low_priced-wall-* --limit 5
42
+ ==================================
43
+ Mode: wall(1000)
44
+ Samples: 85 (1.16% miss rate)
45
+ GC: 2 (2.35%)
46
+ ==================================
47
+ TOTAL (pct) SAMPLES (pct) FRAME
48
+ 71 (83.5%) 71 (83.5%) Mysql2::Client#_query
49
+ 4 (4.7%) 3 (3.5%) JSON::Ext::Generator::GeneratorMethods::Hash#to_json
50
+ 3 (3.5%) 3 (3.5%) Mysql2::Result#each
51
+ 2 (2.4%) 1 (1.2%) App#camelize_keys_for_estate
52
+ 82 (96.5%) 1 (1.2%) Sinatra::Base#route!
53
+ ```
54
+
55
+ ### Ruby on Rails
56
+
57
+ Sample configuration:
58
+
59
+ ```ruby
60
+ use StackProf::RouteMiddleware,
61
+ enabled: true,
62
+ mode: :wall,
63
+ interval: 1000,
64
+ raw: true,
65
+ route_calculator: proc { |env| "#{env['REQUEST_METHOD']}_#{env['action_dispatch.route_uri_pattern']}" }
66
+ ```
67
+
68
+ Results in:
69
+
70
+ ```bash
71
+ $ ls -alh tmp/stackprof-*
72
+ -rw-r--r-- 1 sangenya staff 109B 1 1 23:36 tmp/stackprof-GET_-wall-3323-1704119802.dump
73
+ -rw-r--r-- 1 sangenya staff 207K 1 1 23:36 tmp/stackprof-GET__users___format_-wall-3323-1704119801.dump
74
+ -rw-r--r-- 1 sangenya staff 43K 1 1 23:36 tmp/stackprof-GET__users___format_-wall-3323-1704119805.dump
75
+ -rw-r--r-- 1 sangenya staff 41K 1 1 23:36 tmp/stackprof-GET__users___format_-wall-3323-1704119812.dump
76
+ -rw-r--r-- 1 sangenya staff 54K 1 1 23:36 tmp/stackprof-GET__users__id___format_-wall-3323-1704119804.dump
77
+ -rw-r--r-- 1 sangenya staff 41K 1 1 23:36 tmp/stackprof-GET__users__id___format_-wall-3323-1704119807.dump
78
+ -rw-r--r-- 1 sangenya staff 39K 1 1 23:36 tmp/stackprof-GET__users__id___format_-wall-3323-1704119810.dump
79
+ -rw-r--r-- 1 sangenya staff 51K 1 1 23:36 tmp/stackprof-GET__users__id_edit___format_-wall-3323-1704119809.dump
80
+ -rw-r--r-- 1 sangenya staff 59K 1 1 23:36 tmp/stackprof-GET__users_new___format_-wall-3323-1704119806.dump
81
+ -rw-r--r-- 1 sangenya staff 40K 1 1 23:36 tmp/stackprof-PATCH__users__id___format_-wall-3323-1704119810.dump
82
+ -rw-r--r-- 1 sangenya staff 53K 1 1 23:36 tmp/stackprof-POST__users___format_-wall-3323-1704119807.dump
83
+ ```
84
+
85
+ ## Installation
86
+
87
+ Add this line to your Gemfile:
88
+
89
+ ```ruby
90
+ gem 'stackprof-route_middleware'
91
+ ```
92
+
93
+ ## Development
94
+
95
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
96
+
97
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
98
+
99
+ ## Contributing
100
+
101
+ Bug reports and pull requests are welcome on GitHub at https://github.com/genya0407/stackprof-route_middleware.
102
+
103
+ ## License
104
+
105
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[spec standard]
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StackProf
4
+ class RouteMiddleware
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stackprof"
4
+ require_relative "route_middleware/version"
5
+
6
+ module StackProf
7
+ class RouteMiddleware
8
+ def initialize(app, options = {})
9
+ @app = app
10
+ @options = options
11
+
12
+ self.class.mode = options[:mode] || :cpu
13
+ self.class.interval = options[:interval] || 1000
14
+ self.class.raw = options[:raw] || false
15
+ self.class.enabled = options[:enabled]
16
+ options[:path] = "tmp/" if options[:path].to_s.empty?
17
+ self.class.path = options[:path]
18
+ self.class.metadata = options[:metadata] || {}
19
+ self.class.route_calculator = options[:route_calculator]
20
+
21
+ warn "StackProf::RouteMiddleware does not support save_every option. It regards save_every is 1." if options[:save_every] && options[:save_every] != 1
22
+ warn "StackProf::RouteMiddleware does not support save_at_exit option." if options[:save_at_exit]
23
+ end
24
+
25
+ def call(env)
26
+ enabled = self.class.enabled?(env)
27
+ if enabled
28
+ StackProf.start(
29
+ mode: self.class.mode,
30
+ interval: self.class.interval,
31
+ raw: self.class.raw,
32
+ metadata: self.class.metadata
33
+ )
34
+ end
35
+ @app.call(env)
36
+ ensure
37
+ if enabled
38
+ StackProf.stop
39
+ self.class.save(env)
40
+ end
41
+ end
42
+
43
+ class << self
44
+ attr_accessor :enabled, :mode, :interval, :raw, :path, :metadata, :route_calculator
45
+
46
+ def enabled?(env)
47
+ if enabled.respond_to?(:call)
48
+ enabled.call(env)
49
+ else
50
+ enabled
51
+ end
52
+ end
53
+
54
+ def save(env)
55
+ results = StackProf.results
56
+ return unless results
57
+
58
+ raise "Expected path to be directory" if path == path.chomp("/")
59
+
60
+ route = route_calculator.call(env)
61
+ return unless route
62
+
63
+ filename = "stackprof-#{route.gsub(/\W/, "_")}-#{results[:mode]}-#{Process.pid}-#{Time.now.to_i}.dump"
64
+
65
+ FileUtils.mkdir_p(path)
66
+ File.binwrite(File.join(path, filename), Marshal.dump(results))
67
+ filename
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/stackprof/route_middleware/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "stackprof-route_middleware"
7
+ spec.version = StackProf::RouteMiddleware::VERSION
8
+ spec.authors = ["Yusuke Sangenya"]
9
+ spec.email = ["longinus.eva@gmail.com"]
10
+
11
+ spec.summary = "Rack middleware to profile each route using StackProf"
12
+ spec.homepage = "https://github.com/genya0407/stackprof-route_middleware"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 3.0"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/genya0407/stackprof-route_middleware"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
+ end
25
+ end
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "stackprof"
29
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stackprof-route_middleware
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yusuke Sangenya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: stackprof
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email:
29
+ - longinus.eva@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rspec"
35
+ - ".standard.yml"
36
+ - Gemfile
37
+ - Gemfile.lock
38
+ - LICENSE.txt
39
+ - README.md
40
+ - Rakefile
41
+ - lib/stackprof/route_middleware.rb
42
+ - lib/stackprof/route_middleware/version.rb
43
+ - stackprof-route_middleware.gemspec
44
+ homepage: https://github.com/genya0407/stackprof-route_middleware
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ homepage_uri: https://github.com/genya0407/stackprof-route_middleware
49
+ source_code_uri: https://github.com/genya0407/stackprof-route_middleware
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '3.0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.5.3
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Rack middleware to profile each route using StackProf
69
+ test_files: []