rack-mini-profiler

repository·master·Indexed 23 days ago

https://github.com/miniprofiler/rack-mini-profiler

A middleware for Ruby web applications that provides real-time performance profiling. It displays a speed badge on HTML pages and offers deep dives into database queries (Mysql2, Postgres, Oracle, Mongoid3), call-stack profiling via flamegraphs using stackprof, and memory profiling using memory_profiler. It supports integration with Rack, Sinatra, and Hanami, and includes features like snapshots sampling and multiple storage backends including Redis and Memcache.

Tokens
7.3K
Snippets
13
Records
62
Agent score
86%

What's inside rack-mini-profiler

  1. Overview of rack-mini-profiler

    master
    rack-mini-profiler is a middleware that displays a speed badge on every HTML page. It provides insights into application performance, including database profiling, call-stack profiling via flamegraphs, and memory profiling. It is designed to be used in both development and production environments.
  2. Generate Flamegraphs

    master

    To use flamegraphs, add the stackprof gem to your Gemfile. You can then view flamegraphs using these methods:

    1. Direct HTML response: Append ?pp=flamegraph to the URL or add the header X-Rack-Mini-Profiler: flamegraph.
    2. Async Flamegraphs: Append ?pp=async-flamegraph to the URL. This returns your normal response (useful for JSON/XHR) and stores the data for later viewing via the 'flamegraph' link in the MiniProfiler UI or the X-MiniProfiler-Flamegraph-Path header.
  3. Upgrade speedscope assets

    master

    To upgrade the speedscope files and assets used by rack-mini-profiler to the latest version, run the speedscope_upgrade rake task from the root directory of the repository. This task performs the following actions:

    1. Downloads the latest speedscope release ZIP file from GitHub.
    2. Removes existing files in the lib/html/speedscope directory.
    3. Extracts the new ZIP file into lib/html/speedscope.
    4. Modifies index.html to replace external Google Fonts links with local copies from the fonts directory, ensuring compatibility with intranet environments that lack third-party internet access.
    bundle exec rake speedscope_upgrade
  4. Implement access control for rack-mini-profiler in production

    master

    To use rack-mini-profiler in production environments, you must explicitly authorize requests to prevent unauthorized users from seeing profiling data. Use Rack::MiniProfiler.authorize_request within your application logic (e.g., in a controller callback) once you have verified the user's identity and permissions.

    Warning: If your production application runs on multiple servers or dynos, you must configure the storage backend to use Redis or Memcache to ensure consistent profiling data across nodes.

    # inside your ApplicationController
    
    before_action do
      if current_user && current_user.is_admin?
        Rack::MiniProfiler.authorize_request
      end
    end
  5. Perform Memory Profiling

    master

    Add the memory_profiler gem to your Gemfile. To generate a report, append ?pp=profile-memory to your request URL.

    You can use the following query parameters to filter results (using regular expressions):

    • memory_profiler_allow_files: Filename pattern to include (default: all).
    • memory_profiler_ignore_files: Filename pattern to exclude (default: none).
    • memory_profiler_top: Number of results per section (default: 50).

    Example: ?pp=profile-memory&memory_profiler_allow_files=active_record|app

    Alternative memory tools (no extra gem required):

    • ?pp=profile-gc: Report Garbage Collection statistics.
    • ?pp=analyze-memory: Report ObjectSpace statistics.
  6. Integrate MiniProfiler with Single Page Applications (SPA)

    master

    SPAs (Ember, Angular, etc.) require manual handling because routes change without full page loads.

    1. On route transition: Call window.MiniProfiler.pageTransition() to clear old profiling data and statistics.
    2. Inject Speed Badge: Manually inject the MiniProfiler <script> tag into your application. Note that the data-version GUID and the ?v= parameter must match the current release of rack_mini_profiler to ensure the latest assets are fetched.
    // Call this on every SPA route transition
    if (window.MiniProfiler !== undefined) {
      window.MiniProfiler.pageTransition();
    }
  7. Integrate rack-mini-profiler with Rack, Sinatra, or Hanami

    master

    Rack Builder

    require 'rack-mini-profiler'
    use Rack::MiniProfiler

    Sinatra

    require 'rack-mini-profiler'
    class MyApp < Sinatra::Base
      use Rack::MiniProfiler
    end

    Hanami

    For Hanami, use Rack integration and manually register the rendering method to be profiled:

    # config.ru
    require 'rack-mini-profiler'
    Rack::MiniProfiler.profile_method(Hanami::View::Rendering::Partial, :render) { "Render partial" }
    use Rack::MiniProfiler
  8. Configure MiniProfiler for Heroku Redis

    master

    When using Heroku Redis in production, you may need to configure storage_options with specific SSL parameters to avoid connection issues.

    if Rails.env.production?
      Rack::MiniProfiler.config.storage_options = {
        url: ENV["REDIS_URL"],
        ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }
      }
      Rack::MiniProfiler.config.storage = Rack::MiniProfiler::RedisStore
    end
  9. Install rack-mini-profiler

    master

    Add rack-mini-profiler to your Gemfile for Ruby 3.2+.

    Important: To ensure SQL instrumentation works, you must require rack_mini_profiler below your database gems (like pg or mysql2) in the Gemfile.

    To enable advanced profiling features, include these optional gems:

    • Memory profiling: gem 'memory_profiler'
    • Call-stack flamegraphs: gem 'stackprof'
    gem 'rack-mini-profiler'
  10. Use Snapshots Sampling to detect rare performance issues

    master

    Snapshots sampling enables invisible profiling on one request every $N$ requests to capture performance metrics for later review.

    Configuration

    • Set snapshot_every_n_requests to a value $> 0$.
    • View collected snapshots at /mini-profiler-resources/snapshots (or your configured base_url_path).
    • Snapshots are grouped by HTTP method/path (or controller#action in Rails).

    Snapshots Transporter

    You can aggregate snapshots from multiple sources by configuring a transporter:

    • snapshots_transport_destination_url: The destination URL.
    • snapshots_transport_auth_key: The secure key for authorization (sent via Mini-Profiler-Transport-Auth header).
    • snapshots_transport_gzip_requests: Set to true to enable gzip compression.

    Adding Custom Fields to Snapshots

    Use the following method to attach application-specific metadata (like user ID or app version) to a snapshot: Rack::MiniProfiler.add_snapshot_custom_field(<key>, <value>)