igorkasyanchuk / rails_performance Goto Github PK
View Code? Open in Web Editor NEWMonitor performance of you Rails applications (self-hosted and free)
Home Page: https://www.railsjazz.com/
License: MIT License
Monitor performance of you Rails applications (self-hosted and free)
Home Page: https://www.railsjazz.com/
License: MIT License
Heya,
I just deployed this gem an hour or so ago and it was working fine initially but now it's giving me the following exception:
A Redis::CommandError occurred in rails_performance#index:
ERR too many keys to fetch, please use SCAN
Any clue what this means?
I was performing some load test on my website, and I submitted 2K requests on it. The Recent Requests tab stuck when I open it because of the huge list of requests it loads. How to configure the default number of requests it loads on the beginning?
In such case, ActionDispatch::Static
does not exist, causing an exception in https://github.com/igorkasyanchuk/rails_performance/blob/master/lib/rails_performance/engine.rb#L16.
Not sure if conditionally using Rack::Sendfile
when appropriate or using insert_before Rack::Lock
would make more sense.
Hi,
Thanks for your work! I found it does not work with Grape, when I run many requests of Grape's Api, there is none one of them.
We followed the basic installation. Redis is running (we use it for other process and they are fine) but we see no data in the dashboard. Is there any way to debug what is going on?
It seems the debug flag, which turns on logging, doesn't matter because nothing logs that I can find.
By making rails a dependency, any app adding this gem will inherit all the Rails gems such as activerecord, actioncable, actionmailer, activestorage etc., even if it is not using these optional dependencies itself.
By changing the dependency to just railties, no optional Rails dependencies are forced upon apps.
The helper methods used in this file override methods in our own app.
For example, when when calling the method icon
, instead of our own my implementation, the method from this gem is called.
Does it make sense to just give each helper method in this gem a prefix, so that it won't override any methods of the main app? for e.g. renaming icon
to rails_performance_icon
.
Hi,
I've configured this in my API, which uses Grape to manage most endpoints. Individual requests sent to grape endpoints are shown under /rails/performance/grape
, but these grape endpoints aren't shown under /rails/performance/requests
. Is this intended functionality at this stage, or is something misconfigured on my side or in the gem?
I'm trying to find out how frequently each of my endpoints are being hit, which I would be able to do with the Requests
column of the /requests
page.
Versions:
Thanks!
I installed rails_performance on a rails 6.x application and ran a number of page requests. "Recent Requests" included everything as expected. However, the trace info for every request via TraceReport data section was blank.
My rails application uses rails_semantic_logger, which replaces the default ActionView::LogSubscriber
and ActiveRecord::LogSubscriber
. This prevented rails_performance from tracking the logsubscriber events.
I was able to resolve this by appending the RailsPerformance::Extensions::Db module to the appropriate RailsSemanticLogger LogSubscriber class.
Since ActiveSupport::LogSubscriber is just a logger specific ActiveSupport::Notifications subscriber, why doesn't RailsPerformance just bypass the LogSubscriber altogether and use ActiveSupport::Notifications directly?
If RailsPerformance can use the Notifications directly, would you be comfortable accepting an outside PR?
Hey @igorkasyanchuk I've tried this Gem and to be honest I find it really useful so far. I'm using DD on prod but for developing I feel this tool is a great tool. So first thanks for the 💎
I was wondering if it is to complex to add traces to custom event
RailsPerformance.measure("some label", "some namespace") do
# your code
end
So you can wrap a piece of code on the block and check queries happening there. I can make a PR for this feature, but first want you POV on the feasibility off this.
Thanks
Hello. Love this gem and have been using it on my rails app (AnkiAchievements.com) which is open source at github.com/jac241/spaced_rep_achievements . Unfortunately, I noticed an issue relating to thread safety and your middleware. Users were reporting becoming logged in as another user while using the app - i.e. the headers and responses for the two different requests were either being swapped or the first was being overwritten by the second. I looked back through the logs and saw that this would occur when two requests exactly overlapped. I use a common, threaded webserver (puma).
I think setting @status, @headers, @response = @app.call(env)
and then returning those instance variables makes the middleware not thread safe and could be the source of my problems. I am not a puma expert, but I think it only instantiates the middlewares once and then shares the single instances with each thread, so setting/updating an instance variable could overwrite one set by a different thread.
Hi,
in the last version I get an error on startup on
/.rvm/gems/ruby-3.0.5/gems/rails_performance-1.0.5.1/config/routes.rb:2:in block in <top (required)>': undefined method devise_for' for #<ActionDispatch::Routing::Mapper:0x00007fa76a9c1d50 @set=#<ActionDispatch::Routing::RouteSet:0x00007fa771bd90c8>, @draw_paths=[#<Pathname:/.rvm/gems/ruby-3.0.5/gems/rails_performance-1.0.5.1/config/routes>], @scope=#<ActionDispatch::Routing::Mapper::Scope:0x00007fa76a9c1cd8 @hash={:path_names=>{:new=>"new", :edit=>"edit"}}, @parent=#<ActionDispatch::Routing::Mapper::Scope:0x00007fa7691490e8 @hash=nil, @parent=nil, @scope_level=nil>, @scope_level=nil>, @concerns={}> (NoMethodError)
I see in the confi/routes.rb file this new line devise_for :users
that is causing the error.
Why it was introduced?
Thanks for the help
Hello, I'm testing out this gem to use in production. I'm curious to understand how storage of the data works.
After deploying I watched the Redis memory increase from 0% to 100% during 30 minutes. Once it hit 100% I expected to see an OOM message, however it appears to still be collecting requests.
Does the gem discard expensive information about older requests, or is my traffic somehow fitting just inside the available Redis memory?
My setup:
Config file:
# initializer/rails_performance.rb
RailsPerformance.setup do |config|
redis_url = ENV.fetch("REDIS_URL")
config.redis = Redis::Namespace.new("#{ENV.fetch('APP_NAMESPACE')}-rails-performance", redis: Redis.new(url: "#{redis_url}/1"))
config.duration = 4.hours
config.debug = true # currently not used>
config.enabled = Rails.application.config.rails_performance_enabled
# default path where to mount gem,
# alternatively you can mount the RailsPerformance::Engine in your routes.rb
config.mount_at = '/monitoring/performance'
# protect your Performance Dashboard with HTTP BASIC password
config.http_basic_authentication_enabled = true
config.http_basic_authentication_user_name = Rails.application.config.rails_performance_http_basic_authentication_user_name
config.http_basic_authentication_password = Rails.application.config.rails_performance_http_basic_authentication_password
# if you need an additional rules to check user permissions
# config.verify_access_proc = proc { |controller| true }
# for example when you have `current_user`
# config.verify_access_proc = proc { |controller| controller.current_user && controller.current_user.admin? }
end if defined?(RailsPerformance)
And I have an error when visiting the page /monitoring/performance
:
Full trace :
rails_performance (1.0.1) app/views/rails_performance/rails_performance/index.html.erb:3
actionview (6.1.1) lib/action_view/base.rb:247:in `public_send'
actionview (6.1.1) lib/action_view/base.rb:247:in `_run'
actionview (6.1.1) lib/action_view/template.rb:154:in `block in render'
activesupport (6.1.1) lib/active_support/notifications.rb:205:in `instrument'
actionview (6.1.1) lib/action_view/template.rb:345:in `instrument_render_template'
actionview (6.1.1) lib/action_view/template.rb:152:in `render'
actionview (6.1.1) lib/action_view/renderer/template_renderer.rb:61:in `block (2 levels) in render_template'
activesupport (6.1.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.1) lib/active_support/notifications.rb:203:in `instrument'
actionview (6.1.1) lib/action_view/renderer/template_renderer.rb:56:in `block in render_template'
actionview (6.1.1) lib/action_view/renderer/template_renderer.rb:71:in `block in render_with_layout'
activesupport (6.1.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.1) lib/active_support/notifications.rb:203:in `instrument'
actionview (6.1.1) lib/action_view/renderer/template_renderer.rb:70:in `render_with_layout'
actionview (6.1.1) lib/action_view/renderer/template_renderer.rb:55:in `render_template'
actionview (6.1.1) lib/action_view/renderer/template_renderer.rb:11:in `render'
actionview (6.1.1) lib/action_view/renderer/renderer.rb:61:in `render_template_to_object'
actionview (6.1.1) lib/action_view/renderer/renderer.rb:29:in `render_to_object'
actionview (6.1.1) lib/action_view/rendering.rb:117:in `block in _render_template'
actionview (6.1.1) lib/action_view/base.rb:273:in `in_rendering_context'
actionview (6.1.1) lib/action_view/rendering.rb:116:in `_render_template'
actionpack (6.1.1) lib/action_controller/metal/streaming.rb:218:in `_render_template'
actionview (6.1.1) lib/action_view/rendering.rb:103:in `render_to_body'
actionpack (6.1.1) lib/action_controller/metal/rendering.rb:52:in `render_to_body'
actionpack (6.1.1) lib/action_controller/metal/renderers.rb:142:in `render_to_body'
actionpack (6.1.1) lib/abstract_controller/rendering.rb:25:in `render'
actionpack (6.1.1) lib/action_controller/metal/rendering.rb:36:in `render'
actionpack (6.1.1) lib/action_controller/metal/instrumentation.rb:46:in `block (2 levels) in render'
/usr/local/lib/ruby/2.7.0/benchmark.rb:308:in `realtime'
activesupport (6.1.1) lib/active_support/core_ext/benchmark.rb:14:in `ms'
actionpack (6.1.1) lib/action_controller/metal/instrumentation.rb:46:in `block in render'
actionpack (6.1.1) lib/action_controller/metal/instrumentation.rb:86:in `cleanup_view_runtime'
activerecord (6.1.1) lib/active_record/railties/controller_runtime.rb:39:in `cleanup_view_runtime'
actionpack (6.1.1) lib/action_controller/metal/instrumentation.rb:45:in `render'
actionpack (6.1.1) lib/action_controller/metal/implicit_render.rb:35:in `default_render'
actionpack (6.1.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.1.1) lib/abstract_controller/base.rb:228:in `process_action'
actionpack (6.1.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.1.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport (6.1.1) lib/active_support/callbacks.rb:117:in `block in run_callbacks'
actiontext (6.1.1) lib/action_text/rendering.rb:20:in `with_renderer'
actiontext (6.1.1) lib/action_text/engine.rb:55:in `block (4 levels) in <class:Engine>'
activesupport (6.1.1) lib/active_support/callbacks.rb:126:in `instance_exec'
activesupport (6.1.1) lib/active_support/callbacks.rb:126:in `block in run_callbacks'
activesupport (6.1.1) lib/active_support/callbacks.rb:137:in `run_callbacks'
actionpack (6.1.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (6.1.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (6.1.1) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
activesupport (6.1.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.1) lib/active_support/notifications.rb:203:in `instrument'
actionpack (6.1.1) lib/action_controller/metal/instrumentation.rb:33:in `process_action'
actionpack (6.1.1) lib/action_controller/metal/params_wrapper.rb:249:in `process_action'
activerecord (6.1.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (6.1.1) lib/abstract_controller/base.rb:165:in `process'
actionview (6.1.1) lib/action_view/rendering.rb:39:in `process'
actionpack (6.1.1) lib/action_controller/metal.rb:190:in `dispatch'
actionpack (6.1.1) lib/action_controller/metal.rb:254:in `dispatch'
actionpack (6.1.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
actionpack (6.1.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack (6.1.1) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (6.1.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.1.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.1.1) lib/action_dispatch/routing/route_set.rb:842:in `call'
railties (6.1.1) lib/rails/engine.rb:539:in `call'
railties (6.1.1) lib/rails/railtie.rb:207:in `public_send'
railties (6.1.1) lib/rails/railtie.rb:207:in `method_missing'
actionpack (6.1.1) lib/action_dispatch/routing/mapper.rb:20:in `block in <class:Constraints>'
actionpack (6.1.1) lib/action_dispatch/routing/mapper.rb:49:in `serve'
actionpack (6.1.1) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (6.1.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.1.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.1.1) lib/action_dispatch/routing/route_set.rb:842:in `call'
sentry-rails (4.4.0) lib/sentry/rails/rescued_exception_interceptor.rb:12:in `call'
warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
warden (1.2.9) lib/warden/manager.rb:34:in `catch'
warden (1.2.9) lib/warden/manager.rb:34:in `call'
config/initializers/mountapi.rb:165:in `rescue in call'
config/initializers/mountapi.rb:162:in `call'
rack (2.2.3) lib/rack/etag.rb:27:in `call'
rack (2.2.3) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.3) lib/rack/head.rb:12:in `call'
activerecord (6.1.1) lib/active_record/migration.rb:601:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.1.1) lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack (6.1.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/debug_exceptions.rb:29:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (6.1.1) lib/rails/rack/logger.rb:37:in `call_app'
railties (6.1.1) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (6.1.1) lib/active_support/tagged_logging.rb:99:in `block in tagged'
activesupport (6.1.1) lib/active_support/tagged_logging.rb:37:in `tagged'
activesupport (6.1.1) lib/active_support/tagged_logging.rb:99:in `tagged'
railties (6.1.1) lib/rails/rack/logger.rb:26:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.3) lib/rack/runtime.rb:22:in `call'
activesupport (6.1.1) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/static.rb:24:in `call'
sentry-ruby-core (4.4.2) lib/sentry/rack/capture_exceptions.rb:23:in `block in call'
sentry-ruby-core (4.4.2) lib/sentry/hub.rb:56:in `with_scope'
sentry-ruby-core (4.4.2) lib/sentry-ruby.rb:165:in `with_scope'
sentry-ruby-core (4.4.2) lib/sentry/rack/capture_exceptions.rb:14:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/static.rb:24:in `call'
rack (2.2.3) lib/rack/sendfile.rb:110:in `call'
actionpack (6.1.1) lib/action_dispatch/middleware/host_authorization.rb:98:in `call'
rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'
railties (6.1.1) lib/rails/engine.rb:539:in `call'
rack (2.2.3) lib/rack/static.rb:161:in `call'
puma (5.1.1) lib/puma/configuration.rb:246:in `call'
puma (5.1.1) lib/puma/request.rb:76:in `block in handle_request'
puma (5.1.1) lib/puma/thread_pool.rb:337:in `with_force_shutdown'
puma (5.1.1) lib/puma/request.rb:75:in `handle_request'
puma (5.1.1) lib/puma/server.rb:431:in `process_client'
puma (5.1.1) lib/puma/thread_pool.rb:145:in `block in spawn_thread'
Hello @igorkasyanchuk,
Thanks for your work on this Gem!
I would like to work on this task in the TODO : CI for tests
.
Which CI app did you have in mind? I see there is already a .travis.yml file in the project root.
Let me know if you had something in particular in mind please :)
I just tried the gem in a legacy project using ruby 2.2/rails 4.2, it looks promising, but in rails/performance/requests
I got a SyntaxError
:
rails_performance-0.9.5/app/views/rails_performance/rails_performance/requests.html.erb:29: syntax error, unexpected ',', expecting :: or '[' or '.'
..._eq: a, format_eq: groups[1]}), remote: true );@output_buffe...
... ^:
and that's because of the safe navigation operator &
, introduced in ruby 2.3.
As I see very unlikely in the short term to upgrade this legacy stack, I'm planning to change those to .try
in a fork, see if it works and hopefully don't find any other issue.
But anyway, do you have any plans about minimal ruby version to support?
I tried using this gem with redis cluster, and get error in this method
def Utils.fetch_from_redis(query)
#puts "\n\n [REDIS QUERY] --> #{query}\n\n"
keys = RP.redis.keys(query)
return [] if keys.blank?
values = RP.redis.mget(keys)
[keys, values]
end
Redis::CommandError (CROSSSLOT Keys in request don't hash to the same slot)
then I change to this and all work
def Utils.fetch_from_redis(query)
#puts "\n\n [REDIS QUERY] --> #{query}\n\n"
keys = RP.redis.keys(query)
return [] if keys.blank?
values = keys.collect { |k| RP.redis.get(k) }
[keys, values]
end
Error on rails s
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/rails_performance-0.9.2/lib/rails_performance/engine.rb:10:in <class:Engine>': uninitialized constant ActionDispatch::Executor (NameError) .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/rails_performance-0.9.2/lib/rails_performance/engine.rb:6:in
module:RailsPerformance'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/rails_performance-0.9.2/lib/rails_performance/engine.rb:5:in <top (required)>' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/rails_performance-0.9.2/lib/rails_performance.rb:61:in
<top (required)>'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:81:in require' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:81:in
block (2 levels) in require'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:76:in each' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:76:in
block in require'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:65:in each' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:65:in
require'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/bundler-1.17.3/lib/bundler.rb:114:in require' ruby/motorsw-web/config/application.rb:8:in
<top (required)>'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/railties-4.2.8/lib/rails/commands/commands_tasks.rb:78:in require' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/railties-4.2.8/lib/rails/commands/commands_tasks.rb:78:in
block in server'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/railties-4.2.8/lib/rails/commands/commands_tasks.rb:75:in tap' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/railties-4.2.8/lib/rails/commands/commands_tasks.rb:75:in
server'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/railties-4.2.8/lib/rails/commands/commands_tasks.rb:39:in run_command!' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/railties-4.2.8/lib/rails/commands.rb:17:in
<top (required)>'
ruby/motorsw-web/bin/rails:9:in require' ruby/motorsw-web/bin/rails:9:in
<top (required)>'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/lib/spring/client/rails.rb:28:in load' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/lib/spring/client/rails.rb:28:in
call'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/lib/spring/client/command.rb:7:in call' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/lib/spring/client.rb:30:in
run'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/bin/spring:49:in <top (required)>' .rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/lib/spring/binstub.rb:31:in
load'
.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/gems/spring-2.0.0/lib/spring/binstub.rb:31:in <top (required)>' .rbenv/versions/2.4.7/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:68:in
require'
.rbenv/versions/2.4.7/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:68:in require' from /ruby/motorsw-web/bin/spring:13:in
<top (required)>'
from bin/rails:3:in load' from bin/rails:3:in
Would it make sense to wrap the rails_performance
notification subscriber code branch with a Thread
or Concurrent::Future
so it can handle the payload prepearing redis writing on another thread?
Do you have any statistics on how much overhead of this gem on production, as in milliseconds or memory usage?
Not sure why this isn't working. When I go to /rails/performance I get the above error. App is Rails 6.1.3.1, Ruby 2.7.2
I tried adding the code for the missing method to my own app's ApplicationHelper but this didn't work.
Here's my config file:
RailsPerformance.setup do |config|
config.redis = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new)
config.duration = 7.days
config.debug = false # currently not used>
config.enabled = true
# default path where to mount gem
config.mount_at = '/rails/performance'
# protect your Performance Dashboard with HTTP BASIC password
# config.http_basic_authentication_enabled = false
# config.http_basic_authentication_user_name = 'rails_performance'
# config.http_basic_authentication_password = 'password12'
# if you need an additional rules to check user permissions
# config.verify_access_proc = proc { |controller| true }
# for example when you have `current_user`
config.verify_access_proc = proc { |controller| controller.current_user&.admin? }
# You can ignore endpoints with Rails standard notation controller#action
# config.ignored_endpoints = ['HomeController#contact']
end if defined?(RailsPerformance)
And the backtrace for the error:
rails_performance (1.0.1) app/views/rails_performance/stylesheets/_stylesheets.html.erb:1
actionview (6.1.3.1) lib/action_view/base.rb:247:in `public_send'
actionview (6.1.3.1) lib/action_view/base.rb:247:in `_run'
actionview (6.1.3.1) lib/action_view/template.rb:154:in `block in render'
activesupport (6.1.3.1) lib/active_support/notifications.rb:205:in `instrument'
actionview (6.1.3.1) lib/action_view/template.rb:345:in `instrument_render_template'
actionview (6.1.3.1) lib/action_view/template.rb:152:in `render'
actionview (6.1.3.1) lib/action_view/renderer/partial_renderer.rb:285:in `block in render_partial_template'
activesupport (6.1.3.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.3.1) lib/active_support/notifications.rb:203:in `instrument'
actionview (6.1.3.1) lib/action_view/renderer/partial_renderer.rb:280:in `render_partial_template'
actionview (6.1.3.1) lib/action_view/renderer/partial_renderer.rb:271:in `render'
actionview (6.1.3.1) lib/action_view/renderer/renderer.rb:81:in `render_partial_to_object'
actionview (6.1.3.1) lib/action_view/renderer/renderer.rb:53:in `render_partial'
actionview (6.1.3.1) lib/action_view/helpers/rendering_helper.rb:45:in `render'
haml (5.2.1) lib/haml/helpers/action_view_mods.rb:15:in `render'
rails_performance (1.0.1) app/views/rails_performance/layouts/rails_performance.html.erb:9
actionview (6.1.3.1) lib/action_view/base.rb:247:in `public_send'
actionview (6.1.3.1) lib/action_view/base.rb:247:in `_run'
actionview (6.1.3.1) lib/action_view/template.rb:154:in `block in render'
activesupport (6.1.3.1) lib/active_support/notifications.rb:205:in `instrument'
actionview (6.1.3.1) lib/action_view/template.rb:345:in `instrument_render_template'
actionview (6.1.3.1) lib/action_view/template.rb:152:in `render'
actionview (6.1.3.1) lib/action_view/renderer/template_renderer.rb:72:in `block in render_with_layout'
activesupport (6.1.3.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.3.1) lib/active_support/notifications.rb:203:in `instrument'
actionview (6.1.3.1) lib/action_view/renderer/template_renderer.rb:70:in `render_with_layout'
actionview (6.1.3.1) lib/action_view/renderer/template_renderer.rb:55:in `render_template'
actionview (6.1.3.1) lib/action_view/renderer/template_renderer.rb:11:in `render'
actionview (6.1.3.1) lib/action_view/renderer/renderer.rb:61:in `render_template_to_object'
actionview (6.1.3.1) lib/action_view/renderer/renderer.rb:29:in `render_to_object'
actionview (6.1.3.1) lib/action_view/rendering.rb:117:in `block in _render_template'
actionview (6.1.3.1) lib/action_view/base.rb:273:in `in_rendering_context'
actionview (6.1.3.1) lib/action_view/rendering.rb:116:in `_render_template'
actionpack (6.1.3.1) lib/action_controller/metal/streaming.rb:218:in `_render_template'
actionview (6.1.3.1) lib/action_view/rendering.rb:103:in `render_to_body'
actionpack (6.1.3.1) lib/action_controller/metal/rendering.rb:52:in `render_to_body'
actionpack (6.1.3.1) lib/action_controller/metal/renderers.rb:142:in `render_to_body'
actionpack (6.1.3.1) lib/abstract_controller/rendering.rb:25:in `render'
actionpack (6.1.3.1) lib/action_controller/metal/rendering.rb:36:in `render'
actionpack (6.1.3.1) lib/action_controller/metal/instrumentation.rb:46:in `block (2 levels) in render'
benchmark (0.1.1) lib/benchmark.rb:308:in `realtime'
activesupport (6.1.3.1) lib/active_support/core_ext/benchmark.rb:14:in `ms'
actionpack (6.1.3.1) lib/action_controller/metal/instrumentation.rb:46:in `block in render'
actionpack (6.1.3.1) lib/action_controller/metal/instrumentation.rb:86:in `cleanup_view_runtime'
activerecord (6.1.3.1) lib/active_record/railties/controller_runtime.rb:34:in `cleanup_view_runtime'
actionpack (6.1.3.1) lib/action_controller/metal/instrumentation.rb:45:in `render'
wicked_pdf (1.1.0) lib/wicked_pdf/pdf_helper.rb:42:in `render_with_wicked_pdf'
wicked_pdf (1.1.0) lib/wicked_pdf/pdf_helper.rb:27:in `render'
actionpack (6.1.3.1) lib/action_controller/metal/implicit_render.rb:35:in `default_render'
actionpack (6.1.3.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `block in send_action'
actionpack (6.1.3.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `tap'
actionpack (6.1.3.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.1.3.1) lib/abstract_controller/base.rb:228:in `process_action'
actionpack (6.1.3.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.1.3.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport (6.1.3.1) lib/active_support/callbacks.rb:117:in `block in run_callbacks'
actiontext (6.1.3.1) lib/action_text/rendering.rb:20:in `with_renderer'
actiontext (6.1.3.1) lib/action_text/engine.rb:55:in `block (4 levels) in <class:Engine>'
activesupport (6.1.3.1) lib/active_support/callbacks.rb:126:in `instance_exec'
activesupport (6.1.3.1) lib/active_support/callbacks.rb:126:in `block in run_callbacks'
react-rails (2.6.0) lib/react/rails/controller_lifecycle.rb:31:in `use_react_component_helper'
activesupport (6.1.3.1) lib/active_support/callbacks.rb:126:in `block in run_callbacks'
activesupport (6.1.3.1) lib/active_support/callbacks.rb:137:in `run_callbacks'
actionpack (6.1.3.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (6.1.3.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (6.1.3.1) lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
activesupport (6.1.3.1) lib/active_support/notifications.rb:203:in `block in instrument'
activesupport (6.1.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.1.3.1) lib/active_support/notifications.rb:203:in `instrument'
actionpack (6.1.3.1) lib/action_controller/metal/instrumentation.rb:33:in `process_action'
actionpack (6.1.3.1) lib/action_controller/metal/params_wrapper.rb:249:in `process_action'
activerecord (6.1.3.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (6.1.3.1) lib/abstract_controller/base.rb:165:in `process'
actionview (6.1.3.1) lib/action_view/rendering.rb:39:in `process'
actionpack (6.1.3.1) lib/action_controller/metal.rb:190:in `dispatch'
actionpack (6.1.3.1) lib/action_controller/metal.rb:254:in `dispatch'
actionpack (6.1.3.1) lib/action_dispatch/routing/route_set.rb:50:in `dispatch'
actionpack (6.1.3.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack (6.1.3.1) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (6.1.3.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.1.3.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.1.3.1) lib/action_dispatch/routing/route_set.rb:842:in `call'
railties (6.1.3.1) lib/rails/engine.rb:539:in `call'
railties (6.1.3.1) lib/rails/railtie.rb:207:in `public_send'
railties (6.1.3.1) lib/rails/railtie.rb:207:in `method_missing'
actionpack (6.1.3.1) lib/action_dispatch/routing/mapper.rb:20:in `block in <class:Constraints>'
actionpack (6.1.3.1) lib/action_dispatch/routing/mapper.rb:49:in `serve'
actionpack (6.1.3.1) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (6.1.3.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.1.3.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.1.3.1) lib/action_dispatch/routing/route_set.rb:842:in `call'
warden (1.2.8) lib/warden/manager.rb:36:in `block in call'
warden (1.2.8) lib/warden/manager.rb:34:in `catch'
warden (1.2.8) lib/warden/manager.rb:34:in `call'
rack (2.2.3) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.3) lib/rack/etag.rb:27:in `call'
rack (2.2.3) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.3) lib/rack/head.rb:12:in `call'
actionpack (6.1.3.1) lib/action_dispatch/http/permissions_policy.rb:22:in `call'
actionpack (6.1.3.1) lib/action_dispatch/http/content_security_policy.rb:18:in `call'
rack (2.2.3) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.3) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/cookies.rb:689:in `call'
activerecord (6.1.3.1) lib/active_record/migration.rb:601:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.1.3.1) lib/active_support/callbacks.rb:98:in `run_callbacks'
actionpack (6.1.3.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/actionable_exceptions.rb:18:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/debug_exceptions.rb:29:in `call'
web-console (4.1.0) lib/web_console/middleware.rb:132:in `call_app'
web-console (4.1.0) lib/web_console/middleware.rb:28:in `block in call'
web-console (4.1.0) lib/web_console/middleware.rb:17:in `catch'
web-console (4.1.0) lib/web_console/middleware.rb:17:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (6.1.3.1) lib/rails/rack/logger.rb:37:in `call_app'
railties (6.1.3.1) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (6.1.3.1) lib/active_support/tagged_logging.rb:99:in `block in tagged'
activesupport (6.1.3.1) lib/active_support/tagged_logging.rb:37:in `tagged'
activesupport (6.1.3.1) lib/active_support/tagged_logging.rb:99:in `tagged'
railties (6.1.3.1) lib/rails/rack/logger.rb:26:in `call'
sprockets-rails (3.2.2) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
request_store (1.5.0) lib/request_store/middleware.rb:19:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.3) lib/rack/method_override.rb:24:in `call'
rack (2.2.3) lib/rack/runtime.rb:22:in `call'
rails_performance (1.0.1) lib/rails_performance/rails/middleware.rb:42:in `call!'
rails_performance (1.0.1) lib/rails_performance/rails/middleware.rb:38:in `call'
rails_performance (1.0.1) lib/rails_performance/rails/middleware.rb:17:in `call!'
rails_performance (1.0.1) lib/rails_performance/rails/middleware.rb:9:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/static.rb:24:in `call'
rack (2.2.3) lib/rack/sendfile.rb:110:in `call'
actionpack (6.1.3.1) lib/action_dispatch/middleware/host_authorization.rb:98:in `call'
rack-mini-profiler (2.3.0) lib/mini_profiler/profiler.rb:373:in `call'
webpacker (4.2.2) lib/webpacker/dev_server_proxy.rb:23:in `perform_request'
rack-proxy (0.6.5) lib/rack/proxy.rb:57:in `call'
railties (6.1.3.1) lib/rails/engine.rb:539:in `call'
puma (3.12.6) lib/puma/configuration.rb:227:in `call'
puma (3.12.6) lib/puma/server.rb:706:in `handle_request'
puma (3.12.6) lib/puma/server.rb:476:in `process_client'
puma (3.12.6) lib/puma/server.rb:334:in `block in run'
puma (3.12.6) lib/puma/thread_pool.rb:135:in `block in spawn_thread'
app uses:
App has disabled RailsPerformance in initialization file but still includes it as dependency in Gemfile scope.
What i originally posted as the cause of the issue was wrong ... because i was talking about RailsPerformance code that I added to the gem while debugging this :)
The rake task extension never checks to see if RailsPerformance is enable ... so it will always run and capture data.
This should respect the apps config settings.
When adding this to a Rails app that does not require ActiveRecord, I get this error:
13:53:33 web.1 | .../ruby/3.2.0/lib/ruby/gems/3.2.0/gems/rails_performance-1.1.0/lib/rails_performance/engine.rb:58:in `block in <class:Engine>': uninitialized constant RailsPerformance::Engine::ActiveRecord (NameError)
13:53:33 web.1 |
13:53:33 web.1 | ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db
13:53:33 web.1 | ^^^^^^^^^^^^^^^
13:53:33 web.1 | Did you mean? ActiveModel
Noted the readme states works with Rails 4.2+ (and probably 4.1, 4.0 too) and Ruby 2.2+
. Does it work with Rails 5 and beyond?
I have tried to install this on Rails 6.1 and I am getting no data showing in the dashboard:
We have tried the following to resolve:
gem 'rails_performance', github: 'igorkasyanchuk/rails_performance'
I was wonderring if there are any plans to support p99 beside the average latency.
how to use solid_cache replace redis?
What could the redis interfere with the devise session?
Because today I went up in production to monitor, and I have about 200 customers that use the system, burst with everyone's session, one user see data from another user, who has no relationship, what he implied was that he changed the session without no reason. I almost had a heart attack, and I had to remove the gem :(
We have /health_check
requests which are being used by Docker Swarm to check if the container is healthy. We would like to ignore these requests in performance matrix. Is it possible to ignore certain requests based on URL or controller/action?
Thank you!
These lines do not re-raise the error. This causes Sidekiq to fail to invoke its error handlers and error monitoring (like sentry) fail.
Should be as simple as adding raise ex
in there 😄
How to reproduce :
mount RailsPerformance::Engine
in routes.rb to a specific route (let's say /dashboard/performance
)config.mount_at
line in initializer/rails/performance
and /dashboard/performance
Looks like to culprit is
rails_performance/config/routes.rb
Line 21 in 624f829
A proposed fix could be to not set the default for @@mount_at
or to interpret config.mount_at = false
or config.mount_at = nil
as a switch to disable auto mounting.
Of course it would also be needed to fix all calls to rails_performance_path
.
I could do a pull request to implement either of these solutions if it suits your needs, or let me know if I missed anything 😄
Have a great day
When using Docker, this gem always runs invoke rake command in lib/rails_performance/gems/rake_ext.rb:30
before the version is created. This makes it cannot read the Redis configuration specified in the envar config, so it always return the default host and port.
Redis::CannotConnectError: Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:398:in `rescue in establish_connection'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:379:in `establish_connection'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:117:in `block in connect'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:344:in `with_reconnect'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:116:in `connect'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:417:in `ensure_connected'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:269:in `block in process'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:356:in `logging'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:268:in `process'
/usr/local/bundle/gems/redis-4.5.1/lib/redis/client.rb:162:in `call'
/usr/local/bundle/gems/redis-4.5.1/lib/redis.rb:861:in `block in set'
/usr/local/bundle/gems/redis-4.5.1/lib/redis.rb:72:in `block in synchronize'
/usr/local/bundle/gems/redis-4.5.1/lib/redis.rb:72:in `synchronize'
/usr/local/bundle/gems/redis-4.5.1/lib/redis.rb:857:in `set'
/usr/local/bundle/gems/redis-namespace-1.8.1/lib/redis/namespace.rb:476:in `call_with_namespace'
/usr/local/bundle/gems/redis-namespace-1.8.1/lib/redis/namespace.rb:352:in `block (2 levels) in <class:Namespace>'
/usr/local/bundle/gems/rails_performance-1.0.1/lib/rails_performance/utils.rb:33:in `save_to_redis'
/usr/local/bundle/gems/rails_performance-1.0.1/lib/rails_performance/models/rake_record.rb:44:in `save'
/usr/local/bundle/gems/rails_performance-1.0.1/lib/rails_performance/gems/rake_ext.rb:22:in `invoke_with_rails_performance'
/usr/local/bundle/gems/rails_performance-1.0.1/lib/rails_performance/gems/rake_ext.rb:30:in `invoke'
I suspect the code in https://github.com/igorkasyanchuk/rails_performance/blob/master/lib/rails_performance/engine.rb#L60-L62 that caused this.
config.after_initialize do
next unless RailsPerformance.enabled
ActionView::LogSubscriber.send :prepend, RailsPerformance::Extensions::View
ActiveRecord::LogSubscriber.send :prepend, RailsPerformance::Extensions::Db
if defined?(::Rake::Task)
require_relative './gems/rake_ext.rb'
RailsPerformance::Gems::RakeExt.init
end
end
My workaround is to read an envar config to enable this gem before any other config like so:
RailsPerformance.setup do |config|
config.enabled = ENV['RAILS_PERFORMANCE_ENABLED'] == 'true'
# Other config
end
And inject the ENV['RAILS_PERFORMANCE_ENABLED']
after the Docker finish creating the version and start the rails server like so.
RAILS_PERFORMANCE_ENABLED=true bundle exec rails server -b 0.0.0.0 -p 80 -e production
If this issue is not a priority right now or cannot be fixed at the moment, it would be great if my solution can be included in the docs to help anyone that faces the same issue.
Disabled rails_performance accumulates many hashes in memory Sidekiq, which are not cleaned up by the garbage collector
{:group=>:db, :duration=>0.09, :sql=>"SELECT "product_prices".* FROM "product_prices" WHERE "product_prices"."subject_id" = $1 AND "product_prices"."subject_type" = $2 AND ("product_prices"."price_cents" IS NOT NULL) AND "product_prices"."price_kind_id" = 12630 LIMIT $3", :time=>1606909208}....
I think hashes are accumulating here
Thread.current[:rp_current_request].storage
and Sidekiq does not call cleanup after finishing work
Hi all,
When redis is out of memory the rails performance gem seems giving an unhandled exception that break the api calls.
The exception is the Redis::OutOfMemoryError but I don't have any other info.
I can reproduce it filling the whole cache and trying to make a call.
thanks a lot for the help
Hello, I wanted to ask if such a feature exists and suggest it if it doesn't, a feature to capture incrementor metrics and render them to some graphs in the rails performance dashboard.
Something like what this statsd
client offers perhaps https://github.com/reinh/statsd
$statsd.increment 'some_custom_metric'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.