Giter VIP home page Giter VIP logo

rails_performance's Introduction

Rails Performance

Tests RailsJazz https://www.patreon.com/igorkasyanchuk Listed on OpenSource-Heroes.com

A self-hosted tool to monitor the performance of your Ruby on Rails application.

This is a simple and free alternative to the New Relic APM, Datadog or other similar services.

Demo

It allows you to track:

  • real-time monitoring on the Recent tab
  • monitor slow requests
  • throughput report (see amount of RPM (requests per minute))
  • an average response time
  • the slowest controllers & actions
  • total duration of time spent per request, views rendering, DB
  • SQL queries, rendering logs in "Recent Requests" section
  • simple 500-crashes reports
  • Sidekiq jobs
  • Delayed Job jobs
  • Grape API inside Rails app
  • Rake tasks performance
  • Custom events wrapped with RailsPerformance.measure do .. end block
  • works with Rails 4.2+ (and probably 4.1, 4.0 too) and Ruby 2.2+

All data are stored in local Redis and not sent to any 3rd party servers.

Production

Gem is production-ready. At least on my 2 applications with ~800 unique users per day it works perfectly.

Just don't forget to protect performance dashboard with http basic auth or check of current_user.

Usage

1. Add gem to the Gemfile (in appropriate group if needed)
2. Start rails server
3. Make a few requests to your app
4. open localhost:3000/rails/performance
5. Tune the configuration and deploy to production

Default configuration is listed below. But you can override it.

Create config/initializers/rails_performance.rb in your app:

RailsPerformance.setup do |config|
  config.redis    = Redis::Namespace.new("#{Rails.env}-rails-performance", redis: Redis.new)
  config.duration = 4.hours

  config.debug    = false # currently not used>
  config.enabled  = true

  # configure Recent tab (time window and limit of requests)
  # config.recent_requests_time_window = 60.minutes
  # config.recent_requests_limit = nil # or 1000

  # configure Slow Requests tab (time window, limit of requests and threshold)
  # config.slow_requests_time_window = 4.hours # time window for slow requests
  # config.slow_requests_limit = 500 # number of max rows
  # config.slow_requests_threshold = 500 # number of ms

  # default path where to mount gem,
  # alternatively you can mount the RailsPerformance::Engine in your routes.rb
  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 && controller.current_user.admin? }

  # store custom data for the request
  # config.custom_data_proc = proc do |env|
  #   request = Rack::Request.new(env)
  #   {
  #     email: request.env['warden'].user&.email, # if you are using Devise for example
  #     user_agent: request.env['HTTP_USER_AGENT']
  #   }
  # end

  # config home button link
  config.home_link = '/'

  config.skipable_rake_tasks = ['webpacker:compile']
end if defined?(RailsPerformance)

Installation

Add this line to your application's Gemfile:

gem 'rails_performance'

# or

group :development, :production do
  gem 'rails_performance'
end

And then execute:

$ bundle

Create default configuration file:

$ rails generate rails_performance:install

Have a look at config/initializers/rails_performance.rb and adjust the configuration to your needs.

You must also have installed Redis server, because this gem is storing data into it.

After installation and configuration, start your Rails application, make a few requests, and open https://localhost:3000/rails/performance URL.

Alternative: Mounting the engine yourself

If you, for whatever reason (company policy, devise, ...) need to mount RailsPerformance yourself, feel free to do so by using the following snippet as inspiration. You can skip the mount_at and http_basic_authentication_* configurations then, if you like.

# config/routes.rb
Rails.application.routes.draw do
  ...
  # example for usage with Devise
  authenticate :user, -> (user) { user.admin? } do
    mount RailsPerformance::Engine, at: 'rails/performance'
  end
end

Custom data

You need to configure config.custom_data_proc. And you can capture current_user, HTTP User Agent, etc. This proc is executed inside middleware, and you have access to Rack "env".

Custom Data

Custom events

RailsPerformance.measure("some label", "some namespace") do
   # your code
end

How it works

Schema

In addition it's wrapping gems internal methods and collecting performance information. See ./lib/rails_performance/gems/* for more information.

Limitations

  • it doesn't track params of POST/PUT requests
  • it doesn't track Redis/ElasticSearch or other apps
  • it can't compare historical data
  • depending on your load you may need to reduce time of for how long you store data, because all calculations are done in memory and it could take some time for high-load apps

Redis

Gem is using Redis. This is the only one dependency.

All information is stored into Redis. The default expiration time is set to config.duration from the configuration.

Development & Testing

Just clone the repo, setup dummy app (rails db:migrate).

After this:

  • rails s
  • rake test

Like a regular web development.

Please note that to simplify integration with other apps all CSS/JS are bundled inside, and delivered in body of the request. This is to avoid integration with assets pipeline or webpacker.

For UI changes you need to use Bulma CSS (https://bulma.io/documentation).

Why

The idea of this gem grew from curiosity how many RPM my app receiving per day. Later it evolved to something more powerful.

TODO

  • documentation in Readme?
  • capture stacktrace of 500 errors and show in side panel
  • time/zone config?
  • connected charts on dashboard, when zoom, when hover?
  • ability to zoom to see requests withing specific datetime range
  • better hints?
  • export to csv
  • better stats tooltip, do not show if nothing to show
  • dark mode toggle? save to the cookies?
  • integration with elastic search? or other?
  • monitor active job?
  • better logo?
  • number of requests last 24 hours, hour, etc.
  • collect deprecation.rails
  • fix misspellings?
  • show "loading banner" until jquery is loaded?
  • better UI on smaller screens? Recent requests when URL's are long? Truncate with CSS?
  • rules for highlighting durations? how many ms to show warning, alert
  • elastic search
  • searchkiq
  • sinatra?
  • tests to check what is actually stored in redis db after request

Contributing

You are welcome to contribute. I've a big list of TODO.

If "schema" how records are stored i Redis is changed, and this is a breaking change, update: RailsPerformance::SCHEMA to a newer value.

Big thanks to contributors

License

The gem is available as open source under the terms of the MIT License.

rails_performance's People

Contributors

alagos avatar carl-printreleaf avatar d1ceward avatar dependabot[bot] avatar haffla avatar hfvmarques avatar igorkasyanchuk avatar klondaiker avatar langalex avatar olleolleolle avatar pedroaugustoramalhoduarte avatar salzig avatar synth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rails_performance's Issues

question: why append RailsPerformance::Extensions to LogSubscriber instead of integrating with Rails notifications directly

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?

Feature Request - Handle logging on another thread

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?

ERR too many keys to fetch, please use SCAN

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?

Compatibility with Rails 6

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:

image

We have tried the following to resolve:

  • Confirming that we have the default (unchanged) config file.
  • We have tried to install the latest release by using gem 'rails_performance', github: 'igorkasyanchuk/rails_performance'
  • Confirming Redis is running, have tried restarting redis
  • Have tried running in debug mode, and can see the data appears to be going into Redis

Add traces to custom_events

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

No Data...how to debug?

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.

undefined method `default?' for nil:NilClass

My setup:

  • ruby 2.7.2p137
  • rails 6.1.1
  • Redis server v=6.2.1
  • postgres 9.6

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:

image

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'

Using with redis cluster

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

RailsPerformance::Rails::Middleware maybe not thread safe

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.

When using Docker, the config always initiated before version created resulting cannot read envar config

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.

REDIS + DEVISE

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 :(

Cannot skip setting `config.mount_at` when using `mount RailsPerformance::Engine` in routes.rb

How to reproduce :

  1. Install gem
  2. Follow README and put mount RailsPerformance::Engine in routes.rb to a specific route (let's say /dashboard/performance)
  3. Comment config.mount_at line in initializer
  4. Restart app
  5. Rails performance is both mounted at /rails/performance and /dashboard/performance

Looks like to culprit is

@@mount_at = "/rails/performance"

as it always sets a default that is then used by
mount RailsPerformance::Engine => RailsPerformance.mount_at, as: 'rails_performance'

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

undefined method `insert_css_file' for #<ActionView::Base:0x0000000005cc88>

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' 

Basic Incrementor Metrics

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'

helper methods in this gem collide with own helper methods

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.

Grape requests not showing in 'Requests Analysis' page

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:

  • rails_performance: 1.2.0
  • grape: 1.7.1
  • redis: 4.8.1

Thanks!

rake tasks causing errors when redis is not available even when RailsPerformance.setup config has `enabled = false`

app uses:

  • rails_performance v1.0.0
  • rails v6.0.3.x app
  • bundler v2.2.16
  • ruby 2.7.2

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.

Specify minimal ruby version compatible

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?

Ignore monitoring of some requests

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!

[PR] CI for tests

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 :)

Error on ruby '2.4.7' and 'rails', '4.2.8'

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

'

seems to not work with Grape

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.

Stops working after awhile

The gem worked well initially but then just stopped displaying any metrics. I tried restarting puma but still no metrics, and the recent requests tab remains empty. Attaching a screenshot of what I see when I visit the metrics page.

image

Sidekiq Memory Leak

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

undefined method `devise_for' in new version 1.0.5.1

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

handle case when redis is out of memory - Redis::OutOfMemoryError

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

depend on ralties instead of rails

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.

How does storage work?

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?

Does not work without ActiveRecord

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.