# rack-mini-profiler **Repository Path**: mirrors_Shopify/rack-mini-profiler ## Basic Information - **Project Name**: rack-mini-profiler - **Description**: Profiler for your development and production Ruby rack apps. - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-19 - **Last Updated**: 2026-01-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rack-mini-profiler [](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler) [](https://travis-ci.org/MiniProfiler/rack-mini-profiler) Middleware that displays speed badge for every html page. Designed to work both in production and in development. #### Features * Database profiling - Currently supports Mysql2, Postgres, Oracle (oracle_enhanced ~> 1.5.0) and Mongoid3 (with fallback support to ActiveRecord) * Call-stack profiling - Flame graphs showing time spent by gem * Memory profiling - Per-request memory usage, GC stats, and global allocation metrics #### Learn more * [Visit our community](http://community.miniprofiler.com) * [Watch the RailsCast](http://railscasts.com/episodes/368-miniprofiler) * [Read about Flame graphs in rack-mini-profiler](http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler) * [Read the announcement posts from 2012](http://samsaffron.com/archive/2012/07/12/miniprofiler-ruby-edition) ## rack-mini-profiler needs your help We have decided to restructure our repository so there is a central UI repo and the various language implementation have their own. **WE NEED HELP.** - Help [triage issues](https://www.codetriage.com/miniprofiler/rack-mini-profiler) [](https://www.codetriage.com/miniprofiler/rack-mini-profiler) If you feel like taking on any of this start an issue and update us on your progress. ## Installation Install/add to Gemfile in Ruby 2.3+ ```ruby gem 'rack-mini-profiler' ``` NOTE: Be sure to require rack_mini_profiler below the `pg` and `mysql` gems in your Gemfile. rack_mini_profiler will identify these gems if they are loaded to insert instrumentation. If included too early no SQL will show up. You can also include optional libraries to enable additional features. ```ruby # For memory profiling gem 'memory_profiler' # For call-stack profiling flamegraphs gem 'flamegraph' gem 'stackprof' ``` #### Rails All you have to do is to include the Gem and you're good to go in development. See notes below for use in production. #### Rails and manual initialization In case you need to make sure rack_mini_profiler initialized is after all other gems, or you want to execute some code before rack_mini_profiler required: ```ruby gem 'rack-mini-profiler', require: false ``` Note the `require: false` part - if omitted, it will cause the Railtie for the mini-profiler to be loaded outright, and an attempt to re-initialize it manually will raise an exception. Then run the generator which will set up rack-mini-profiler in development: ```bash bundle exec rails g rack_profiler:install ``` #### Rack Builder ```ruby require 'rack-mini-profiler' home = lambda { |env| [200, {'Content-Type' => 'text/html'}, ["
hello!"]] } builder = Rack::Builder.new do use Rack::MiniProfiler map('/') { run home } end run builder ``` #### Sinatra ```ruby require 'rack-mini-profiler' class MyApp < Sinatra::Base use Rack::MiniProfiler end ``` #### Hanami For working with hanami, you need to use rack integration. Also, you need to add `Hanami::View::Rendering::Partial#render` method for profile: ```ruby # config.ru require 'rack-mini-profiler' Rack::MiniProfiler.profile_method(Hanami::View::Rendering::Partial, :render) { "Render partial #{@options[:partial]}" } use Rack::MiniProfiler ``` #### Patching ActiveRecord A typical web application spends a lot of time querying the database. rack_mini_profiler will detect the ORM that is available and apply patches to properly collect query statistics. To make this work, declare the orm's gem before declaring `rack-mini-profiler` in the `Gemfile`: ```ruby gem 'pg' gem 'mongoid' gem 'rack-mini-profiler' ``` If you wish to override this behavior, the environment variable `RACK_MINI_PROFILER_PATCH` is available. ```bash export RACK_MINI_PROFILER_PATCH="pg,mongoid" # or export RACK_MINI_PROFILER_PATCH="false" # initializers/rack_profiler.rb: SqlPatches.patch %w(mongo) ``` ### Flamegraphs To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler): * add the [**flamegraph**](https://github.com/SamSaffron/flamegraph) gem to your Gemfile * visit a page in your app with `?pp=flamegraph` ### Memory Profiling Memory allocations can be measured (using the [memory_profiler](https://github.com/SamSaffron/memory_profiler) gem) which will show allocations broken down by gem, file location, and class and will also highlight `String` allocations. Add `?pp=profile-memory` to the URL of any request while Rack::MiniProfiler is enabled to generate the report. Additional query parameters can be used to filter the results. * `memory_profiler_allow_files` - filename pattern to include (default is all files) * `memory_profiler_ignore_files` - filename pattern to exclude (default is no exclusions) * `memory_profiler_top` - number of results per section (defaults to 50) The allow/ignore patterns will be treated as regular expressions. Example: `?pp=profile-memory&memory_profiler_allow_files=active_record|app` There are two additional `pp` options that can be used to analyze memory which do not require the `memory_profiler` gem * Use `?pp=profile-gc` to report on Garbage Collection statistics * Use `?pp=analyze-memory` to report on ObjectSpace statistics ## Access control in non-development environments rack-mini-profiler is designed with production profiling in mind. To enable that run `Rack::MiniProfiler.authorize_request` once you know a request is allowed to profile. ```ruby # inside your ApplicationController before_action do if current_user && current_user.is_admin? Rack::MiniProfiler.authorize_request end end ``` > If your production application is running on more than one server (or more than one dyno) you will need to configure rack mini profiler's storage to use Redis or Memcache. See [storage](#storage) for information on changing the storage backend. Note: Out-of-the-box we will initialize the `authorization_mode` to `:whitelist` in production. However, in some cases we may not be able to do it: - If you are running in development or test we will not enable whitelist mode - If you use `require: false` on rack_mini_profiler we are unlikely to be able to run the railtie - If you are running outside of rails we will not run the railtie In those cases use: ```ruby Rack::MiniProfiler.config.authorization_mode = :whitelist ``` When deciding to fully profile a page mini profiler consults with the `authorization_mode` By default in production we attempt to set the authorization mode to `:whitelist` meaning that end user will only be able to see requests where somewhere `Rack::MiniProfiler.authorize_request` is invoked. In development we run in the `:allow_all` authorization mode meaning every request is profiled and displayed to the end user. ## Configuration Various aspects of rack-mini-profiler's behavior can be configured when your app boots. For example in a Rails app, this should be done in an initializer: **config/initializers/mini_profiler.rb** ### Caching behavior To fix some nasty bugs with rack-mini-profiler showing the wrong data, the middleware will remove headers relating to caching (Date & Etag on responses, If-Modified-Since & If-None-Match on requests). This probably won't ever break your application, but it can cause some unexpected behavior. For example, in a Rails app, calls to `stale?` will always return true. To disable this behavior, use the following config setting: ```ruby # Do not let rack-mini-profiler disable caching Rack::MiniProfiler.config.disable_caching = false # defaults to true ``` ### Storage rack-mini-profiler stores its results so they can be shared later and aren't lost at the end of the request. There are 4 storage options: `MemoryStore`, `RedisStore`, `MemcacheStore`, and `FileStore`. `FileStore` is the default in Rails environments and will write files to `tmp/miniprofiler/*`. `MemoryStore` is the default otherwise. ```ruby # set MemoryStore Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore # set RedisStore if Rails.env.production? uri = URI.parse(ENV["REDIS_SERVER_URL"]) Rack::MiniProfiler.config.storage_options = { :host => uri.host, :port => uri.port, :password => uri.password } Rack::MiniProfiler.config.storage = Rack::MiniProfiler::RedisStore end ``` `MemoryStore` stores results in a processes heap - something that does not work well in a multi process environment. `FileStore` stores results in the file system - something that may not work well in a multi machine environment. `RedisStore`/`MemcacheStore` work in multi process and multi machine environments (`RedisStore` only saves results for up to 24 hours so it won't continue to fill up Redis). You will need to add `gem redis`/`gem dalli` respectively to your `Gemfile` to use these stores. Additionally you may implement an `AbstractStore` for your own provider. ### User result segregation MiniProfiler will attempt to keep all user results isolated, out-of-the-box the user provider uses the ip address: ```ruby Rack::MiniProfiler.config.user_provider = Proc.new{|env| Rack::Request.new(env).ip} ``` You can override (something that is very important in a multi-machine production setup): ```ruby Rack::MiniProfiler.config.user_provider = Proc.new{ |env| CurrentUser.get(env) } ``` The string this function returns should be unique for each user on the system (for anonymous you may need to fall back to ip address) ### Profiling specific methods You can increase the granularity of profiling by measuring the performance of specific methods. Add methods of interest to an initializer. ```ruby Rails.application.config.to_prepare do ::Rack::MiniProfiler.profile_singleton_method(User, :non_admins) { |a| "executing all_non_admins" } ::Rack::MiniProfiler.profile_method(User, :favorite_post) { |a| "executing favorite_post" } end ``` ### Profiling arbitrary block of code It is also possible to profile any arbitrary block of code by passing a block to `Rack::MiniProfiler.step(name, opts=nil)`. ```ruby Rack::MiniProfiler.step('Adding two elements') do result = 1 + 2 end ``` ### Using in SPA applications Single page applications built using Ember, Angular or other frameworks need some special care, as routes often change without a full page load. On route transition always call: ``` window.MiniProfiler.pageTransition(); ``` This method will remove profiling information that was related to previous page and clear aggregate statistics. #### MiniProfiler's speed badge on pages that are not generated via Rails You need to inject the following in your SPA to load MiniProfiler's speed badge ([extra details surrounding this script](https://github.com/MiniProfiler/rack-mini-profiler/issues/139#issuecomment-192880706)): ```html ``` _Note:_ The GUID (`data-version` and the `?v=` parameter on the `src`) will change with each release of `rack_mini_profiler`. The MiniProfiler's speed badge will continue to work, although you will have to change the GUID to expire the script to fetch the most recent version. #### Using MiniProfiler's built in route for apps without HTML responses MiniProfiler also ships with a `/rack-mini-profiler/requests` route that displays the speed badge on a blank HTML page. This can be useful when profiling an application that does not render HTML. ### Configuration Options You can set configuration options using the configuration accessor on `Rack::MiniProfiler`. For example: ```ruby Rack::MiniProfiler.config.position = 'bottom-right' Rack::MiniProfiler.config.start_hidden = true ``` The available configuration options are: Option|Default|Description -------|---|-------- pre_authorize_cb|Rails: dev only