### Install Stackprof Gem Source: https://github.com/tmm1/stackprof/blob/master/README.md Instructions for adding Stackprof to a Ruby project via Gemfile or manual installation. ```ruby gem 'stackprof' ``` ```bash $ bundle install $ gem install stackprof ``` -------------------------------- ### Run Stackprof Profiler Source: https://github.com/tmm1/stackprof/blob/master/README.md Examples for running the profiler directly in Ruby code or via Rack middleware. ```ruby StackProf.run(mode: :cpu, out: 'tmp/stackprof-cpu-myapp.dump') do #... end ``` ```ruby use StackProf::Middleware, enabled: true, mode: :cpu, interval: 1000, save_every: 5 ``` -------------------------------- ### StackProf Text Report Example Source: https://github.com/tmm1/stackprof/blob/master/README.md Provides an example output format for StackProf's text reporting mode. It displays profiling data including total samples, percentage, and frame information. ```text TOTAL (pct) SAMPLES (pct) FRAME 91 (48.4%) 91 (48.4%) A#pow 58 (30.9%) 58 (30.9%) A.newobj 34 (18.1%) 34 (18.1%) block in A#math 188 (100.0%) 3 (1.6%) block (2 levels) in
185 (98.4%) 1 (0.5%) A#initialize 35 (18.6%) 1 (0.5%) A#math 188 (100.0%) 0 (0.0%)
188 (100.0%) 0 (0.0%) block in
188 (100.0%) 0 (0.0%)
``` -------------------------------- ### Use StackProf Command Line Interface Source: https://context7.com/tmm1/stackprof/llms.txt Provides examples of using the `stackprof` command-line tool to run profiled Ruby scripts and analyze existing profile dump files. It covers running scripts with various options, generating different report formats (text, flamegraph, Graphviz), and filtering results. ```bash # Run a Ruby script with profiling enabled stackprof run --mode cpu --interval 1000 --out profile.dump -- ruby myapp.rb stackprof run --mode wall --raw -- ruby server.rb # Analyze profile dumps with text output (default) stackprof profile.dump --text --limit 20 stackprof profile.dump --text --sort-total # Filter results by file or method name stackprof profile.dump --select-files /app/models --limit 30 stackprof profile.dump --reject-files /gems --reject-names /initialize/ stackprof profile.dump --select-names /process|handle/ # Zoom into specific method with callers/callees stackprof profile.dump --method 'User#save' stackprof profile.dump --method 'User#save' --walk # Interactive navigation # View annotated source code stackprof profile.dump --file app/models/user.rb # Generate flamegraph (requires raw: true during collection) stackprof --flamegraph profile.dump > flamegraph.js stackprof --flamegraph-viewer=flamegraph.js # Print command to open viewer # Generate D3-based flamegraph HTML stackprof --d3-flamegraph profile.dump > flamegraph.html # Generate graphviz diagram stackprof profile.dump --graphviz --limit 50 --node-fraction 0.01 > profile.dot dot -Tpng profile.dot -o profile.png ``` -------------------------------- ### StackProf.run Source: https://context7.com/tmm1/stackprof/llms.txt Profiles a block of Ruby code by starting the profiler, executing the block, and returning the results as a hash. ```APIDOC ## StackProf.run ### Description Executes a block of code while profiling it, then returns the captured profile data. ### Method Ruby Method Call ### Parameters - **mode** (Symbol) - Required - Profiling mode: :wall, :cpu, :object, or :custom. - **interval** (Integer) - Optional - Sampling interval in microseconds (or allocations for :object mode). - **raw** (Boolean) - Optional - Whether to collect raw data for flamegraphs. - **out** (String) - Optional - File path to save the profile dump. - **ignore_gc** (Boolean) - Optional - Whether to ignore garbage collection frames. ### Request Example StackProf.run(mode: :cpu, interval: 1000) { ... } ### Response - **samples** (Integer) - Total number of samples collected. - **mode** (Symbol) - The profiling mode used. - **frames** (Hash) - Captured call stack frames. ``` -------------------------------- ### Manual profiling control with start, stop, and results Source: https://context7.com/tmm1/stackprof/llms.txt Manual control methods allow for granular profiling across multiple code sections. Results accumulate until retrieved via StackProf.results, which clears the data upon access. ```ruby require 'stackprof' StackProf.start(mode: :wall, interval: 1000) process_batch_1() StackProf.stop StackProf.start(mode: :wall, interval: 1000) process_batch_2() StackProf.stop # Retrieve accumulated results profile = StackProf.results('/tmp/profile.dump') ``` -------------------------------- ### Manual Profiler Control Source: https://github.com/tmm1/stackprof/blob/master/README.md Starts and stops the profiler manually to accumulate results across multiple code execution segments. ```ruby StackProf.running? # => false StackProf.start(mode: :cpu) StackProf.running? # => true StackProf.stop StackProf.results('/tmp/some.file') ``` -------------------------------- ### Manual Profiling Control Source: https://context7.com/tmm1/stackprof/llms.txt Methods to manually start, stop, and retrieve results from the profiler across multiple code sections. ```APIDOC ## StackProf.start / StackProf.stop / StackProf.results ### Description Allows granular control over the profiling lifecycle. Results accumulate until retrieved via StackProf.results. ### Methods - **StackProf.start(options)**: Starts the profiler. - **StackProf.stop**: Stops the profiler. - **StackProf.results(path)**: Returns results as a hash or saves to a file. ### Request Example StackProf.start(mode: :wall, interval: 1000) # ... code ... StackProf.stop profile = StackProf.results ``` -------------------------------- ### Load and Analyze StackProf Profiles Source: https://context7.com/tmm1/stackprof/llms.txt Shows how to load profile data from a file using `StackProf::Report.from_file` or create a report from in-memory profile data collected by `StackProf.run`. It covers generating text summaries, filtering results by file paths, and analyzing specific methods. ```ruby require 'stackprof' # Load profile from file (supports both Marshal and JSON formats) report = StackProf::Report.from_file('tmp/stackprof-cpu.dump') # Or create from in-memory profile data profile = StackProf.run(mode: :cpu) { expensive_work() } report = StackProf::Report.new(profile) # Text summary output report.print_text # ================================== # Mode: cpu(1000) # Samples: 1234 (0.50% miss rate) # GC: 45 (3.65%) # ================================== # TOTAL (pct) SAMPLES (pct) FRAME # 500 (40.5%) 450 (36.5%) String#gsub # 300 (24.3%) 300 (24.3%) Array#map # Text with sorting and limits report.print_text(true, 10) # Sort by total, limit to 10 entries # Filter by file paths report.print_text(false, nil, ['/app/models'], ['/gems']) # Analyze specific method report.print_method('String#gsub') # String#gsub (/path/to/file.rb:42) # samples: 450 self (36.5%) / 500 total (40.5%) # callers: # 200 ( 40.0%) MyClass#process # callees (50 total): # 30 ( 60.0%) String#match # code: # | 42 | def process # 450 (36.5% / 90.0%) | 43 | text.gsub(/pattern/, 'replacement') # Interactive method walking report.walk_method('MyClass#process') # Navigate callers/callees interactively # File-level analysis report.print_files(true, 20) # Sort by total, limit 20 report.print_file('app/models/user.rb') # Annotated source ``` -------------------------------- ### Generate StackProf Reports in Various Formats Source: https://context7.com/tmm1/stackprof/llms.txt Demonstrates how to generate profile reports in different formats suitable for various analysis tools. This includes JSON for web viewers, Graphviz DOT for diagrams, Callgrind for kcachegrind, Stackcollapse for flamegraphs, and timeline/D3 flamegraphs. ```ruby require 'stackprof' # Collect profile with raw data for flamegraph support profile = StackProf.run(mode: :cpu, raw: true) do complex_operation() end report = StackProf::Report.new(profile) # JSON output for web viewers File.open('profile.json', 'w') { |f| report.print_json(f) } # Graphviz DOT format (use with `dot -Tpng profile.dot -o profile.png`) File.open('profile.dot', 'w') do |f| report.print_graphviz({ limit: 50, node_fraction: 0.01 }, f) end # Callgrind format (use with kcachegrind) File.open('profile.callgrind', 'w') { |f| report.print_callgrind(f) } # Stackcollapse format (use with flamegraph.pl) File.open('profile.collapsed', 'w') { |f| report.print_stackcollapse } # Timeline flamegraph (JavaScript viewer) File.open('flamegraph.js', 'w') { |f| report.print_timeline_flamegraph(f) } # D3 flamegraph (standalone HTML) File.open('flamegraph.html', 'w') { |f| report.print_d3_flamegraph(f) } # Combine multiple profiles report1 = StackProf::Report.from_file('profile1.dump') report2 = StackProf::Report.from_file('profile2.dump') combined = report1 + report2 combined.print_text ``` -------------------------------- ### StackProf.run Options Source: https://github.com/tmm1/stackprof/blob/master/README.md Configuration options for the StackProf.run method. ```APIDOC ## StackProf.run Options `StackProf.run` accepts an options hash to configure profiling. The following options are recognized: ### Options Table | Option | Meaning | |-------------|-------------------------------------------------------------------------| | `mode` | Mode of sampling: `:cpu`, `:wall`, `:object`, or `:custom` | | `out` | The target file path for the profile data. This file will be overwritten. | | `interval` | Mode-relative sample rate. | | `ignore_gc` | If true, garbage collection frames will be ignored during profiling. | | `aggregate` | Defaults to `true`. If `false`, disables aggregation of results. | | `raw` | Defaults to `false`. If `true`, collects extra data for flamegraph reports. | | `metadata` | A `Hash` containing metadata associated with this profile. Defaults to `{}`. | | `save_every`| (Rack middleware only) Saves the target file after this many requests. | ### Todo * File/ISEQ blacklist support. * Restore signal handlers on stop. ``` -------------------------------- ### Analyze Profile Dumps via CLI Source: https://context7.com/tmm1/stackprof/llms.txt Use the stackprof command-line interface to convert dump files into formats compatible with external visualization tools like KCachegrind or FlameGraph. ```bash stackprof profile.dump --callgrind > profile.callgrind kcachegrind profile.callgrind stackprof profile1.dump profile2.dump profile3.dump --text stackprof profile.dump --json > profile.json stackprof profile.dump --stackcollapse | flamegraph.pl > flamegraph.svg ``` -------------------------------- ### Implement custom sampling with StackProf.sample Source: https://context7.com/tmm1/stackprof/llms.txt The :custom mode allows developers to trigger samples manually at specific points in the execution flow. This is useful for event-driven profiling or complex conditional logic. ```ruby require 'stackprof' StackProf.start(mode: :custom) def process_item(item) StackProf.sample if item.expensive? StackProf.sample heavy_computation(item) end end StackProf.stop profile = StackProf.results ``` -------------------------------- ### StackProf Run with CPU Sampling Source: https://github.com/tmm1/stackprof/blob/master/README.md Executes StackProf in CPU time sampling mode. This mode profiles the CPU activity within the given block and saves the output. The interval is set in microseconds, with a default of 1000 for 1 millisecond. ```ruby StackProf.run(mode: :cpu, out: 'tmp/stackprof.dump', interval: 1000) do #... end ``` -------------------------------- ### StackProf Run with Wall Sampling Source: https://github.com/tmm1/stackprof/blob/master/README.md Executes StackProf in wall clock time sampling mode. It profiles the execution of the block, saving the results to a specified file. The interval parameter controls the frequency of sampling in microseconds. ```ruby StackProf.run(mode: :wall, out: 'tmp/stackprof.dump', interval: 1000) do #... end ``` -------------------------------- ### Configure Autorun Profiling Source: https://context7.com/tmm1/stackprof/llms.txt Enable automatic profiling for Ruby scripts without modifying source code by using the stackprof/autorun library or environment variables. ```ruby require 'stackprof/autorun' ``` ```bash STACKPROF_MODE=cpu STACKPROF_INTERVAL=1000 ruby -r stackprof/autorun myapp.rb STACKPROF_MODE=wall STACKPROF_OUT=profile.dump ruby -r stackprof/autorun app.rb STACKPROF_MODE=cpu STACKPROF_RAW=1 ruby -r stackprof/autorun benchmark.rb ``` -------------------------------- ### Generate Flamegraphs Source: https://github.com/tmm1/stackprof/blob/master/README.md Commands to generate flamegraph data and visualize it using the CLI viewer or D3 flame graph. ```bash $ stackprof --flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph $ stackprof --flamegraph-viewer=tmp/flamegraph $ stackprof --d3-flamegraph tmp/stackprof-cpu-myapp.dump > flamegraph.html ``` -------------------------------- ### Integrate Rack middleware for web profiling Source: https://context7.com/tmm1/stackprof/llms.txt StackProf::Middleware enables automated profiling for Rack-based applications. It supports conditional profiling and periodic saving of profile dumps. ```ruby require 'stackprof' # Basic usage in config.ru or Rails initializer use StackProf::Middleware, enabled: true, mode: :cpu, interval: 1000, save_every: 5 # Conditional profiling based on request header use StackProf::Middleware, enabled: ->(env) { env['HTTP_X_STACKPROF'] == 'true' }, mode: :wall, interval: 1000 ``` -------------------------------- ### Manually Save StackProf Middleware Profile Source: https://context7.com/tmm1/stackprof/llms.txt Demonstrates how to manually trigger a save of the currently accumulated profile data from the StackProf middleware. This is useful for capturing a profile at a specific point in time. ```ruby StackProf::Middleware.save # Saves current accumulated profile ``` -------------------------------- ### Profile Ruby code blocks with StackProf.run Source: https://context7.com/tmm1/stackprof/llms.txt The StackProf.run method provides a convenient way to profile a specific block of code. It supports various modes like :cpu, :wall, and :object, and allows configuration of sampling intervals and output destinations. ```ruby require 'stackprof' # Profile CPU usage with 1ms sampling interval profile = StackProf.run(mode: :cpu, interval: 1000) do 1_000_000.times { "hello" * 100 } end # Profile with raw data collection for flamegraph generation profile = StackProf.run(mode: :wall, interval: 1000, raw: true) do expensive_operation() end # Save profile directly to file StackProf.run(mode: :cpu, out: 'tmp/stackprof-cpu.dump') do MyApp.process_request end # Profile object allocations profile = StackProf.run(mode: :object, interval: 1) do 10_000.times { Object.new } end ``` -------------------------------- ### StackProf Aggregation Pseudo-code Source: https://github.com/tmm1/stackprof/blob/master/README.md Illustrates the core logic for aggregating profiling samples into a call graph. It shows how each sample contributes to the 'samples', 'total_samples', 'lines', and 'edges' metadata for the frames involved. ```ruby trap('PROF') do top, *rest = caller top.samples += 1 top.lines[top.lineno] += 1 top.total_samples += 1 prev = top rest.each do |frame| frame.edges[prev] += 1 frame.total_samples += 1 prev = frame end end ``` -------------------------------- ### Run Profiler with Block Source: https://github.com/tmm1/stackprof/blob/master/README.md Executes a block of code while the profiler is running, returning a profile hash containing sampling data. ```ruby profile = StackProf.run(mode: :cpu, interval: 1000) do MyCode.execute end ``` -------------------------------- ### StackProf Run with Object Allocation Sampling Source: https://github.com/tmm1/stackprof/blob/master/README.md Executes StackProf in object allocation sampling mode. This mode profiles the number of objects allocated within the block. The interval parameter here refers to the number of allocations between samples, with a default of 1. ```ruby StackProf.run(mode: :object, out: 'tmp/stackprof.dump', interval: 1) do #... end ``` -------------------------------- ### StackProf::Middleware Source: https://context7.com/tmm1/stackprof/llms.txt Rack middleware to automatically profile web requests in Ruby web applications. ```APIDOC ## StackProf::Middleware ### Description Integrates profiling into Rack-based applications (e.g., Rails, Sinatra) to profile incoming HTTP requests. ### Parameters - **enabled** (Boolean/Proc) - Required - Whether to enable profiling. - **mode** (Symbol) - Optional - Profiling mode. - **save_every** (Integer) - Optional - Frequency of saving profile dumps. - **path** (String) - Optional - Directory for saving dump files. ### Request Example use StackProf::Middleware, enabled: true, mode: :cpu, interval: 1000 ``` -------------------------------- ### Configure StackProf Middleware in Rails Source: https://context7.com/tmm1/stackprof/llms.txt Integrates StackProf into a Rails application using middleware. It allows enabling profiling in development environments, specifying profiling mode (wall or CPU time), sampling interval, and output path. Options for saving profiles at exit or periodically are also supported. ```ruby config.middleware.use StackProf::Middleware, enabled: Rails.env.development?, mode: :wall, interval: 1000, path: 'tmp/stackprof/', save_every: 10, save_at_exit: true, metadata: { app: 'myapp' } ``` ```ruby use StackProf::Middleware, enabled: true, mode: :cpu, path: 'tmp/profiles/' # Creates stackprof-cpu-PID-TIMESTAMP.dump ``` -------------------------------- ### Generate Graphviz Report Source: https://github.com/tmm1/stackprof/blob/master/README.md Generates a Graphviz DOT format representation of the profile data to visualize call relationships and sample weights. ```dot digraph profile { 70346498324780 [size=23.5531914893617] [fontsize=23.5531914893617] [shape=box] [label="A#pow\n91 (48.4%)\r"]; 70346498324680 [size=18.638297872340424] [fontsize=18.638297872340424] [shape=box] [label="A.newobj\n58 (30.9%)\r"]; 70346498324480 [size=15.063829787234042] [fontsize=15.063829787234042] [shape=box] [label="block in A#math\n34 (18.1%)\r"]; 70346498324220 [size=10.446808510638299] [fontsize=10.446808510638299] [shape=box] [label="block (2 levels) in
\n3 (1.6%)\rof 188 (100.0%)\r"]; 70346498324220 -> 70346498324900 [label="185"]; 70346498324900 [size=10.148936170212766] [fontsize=10.148936170212766] [shape=box] [label="A#initialize\n1 (0.5%)\rof 185 (98.4%)\r"]; 70346498324900 -> 70346498324780 [label="91"]; 70346498324900 -> 70346498324680 [label="58"]; 70346498324900 -> 70346498324580 [label="35"]; 70346498324580 [size=10.148936170212766] [fontsize=10.148936170212766] [shape=box] [label="A#math\n1 (0.5%)\rof 35 (18.6%)\r"]; 70346498324580 -> 70346498324480 [label="34"]; 70346497983360 [size=10.0] [fontsize=10.0] [shape=box] [label="
\n0 (0.0%)\rof 188 (100.0%)\r"]; 70346497983360 -> 70346498325080 [label="188"]; 70346498324300 [size=10.0] [fontsize=10.0] [shape=box] [label="block in
\n0 (0.0%)\rof 188 (100.0%)\r"]; 70346498324300 -> 70346498324220 [label="188"]; 70346498325080 [size=10.0] [fontsize=10.0] [shape=box] [label="
\n0 (0.0%)\rof 188 (100.0%)\r"]; 70346498325080 -> 70346498324300 [label="188"]; } ``` -------------------------------- ### Dynamic Data Loader Source: https://github.com/tmm1/stackprof/blob/master/lib/stackprof/flamegraph/viewer.html Parses URL query parameters to extract a data source and dynamically injects a script tag into the document body to load the flamegraph data. ```javascript var queryDict = {}; location.search.substr(1).split("&").forEach(function(item) { queryDict[item.split("=")[0]] = decodeURIComponent(item.split("=")[1]); }); if (queryDict.data) { var s = document.createElement('script'); s.setAttribute('src', queryDict.data); document.body.appendChild(s); } ``` -------------------------------- ### Access and Inspect Profile Data Source: https://context7.com/tmm1/stackprof/llms.txt Programmatically access the profile hash returned by StackProf.run to analyze frames, edges, and raw sample data. ```ruby profile = StackProf.run(mode: :cpu, interval: 1000, raw: true) do 100_000.times { [1,2,3].map(&:to_s) } end # Accessing frames and edges profile[:frames].each do |frame_id, frame_info| puts "Frame: #{frame_info[:name]}" if frame_info[:edges] frame_info[:edges].each { |callee_id, count| puts " -> #{profile[:frames][callee_id][:name]}: #{count} calls" } end end # Saving to disk File.open('profile.dump', 'wb') { |f| f.write(Marshal.dump(profile)) } ``` -------------------------------- ### Flamegraph CSS Styling Source: https://github.com/tmm1/stackprof/blob/master/lib/stackprof/flamegraph/viewer.html Defines the visual layout, typography, and interaction states for the flamegraph container, including the overview viewport and legend components. ```css body { margin: 0; padding: 0; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 10pt; } .overview-container { position: relative; } .overview { cursor: col-resize; } .overview-viewport-overlay { position: absolute; top: 0; left: 0; width: 1; height: 1; background-color: rgba(0, 0, 0, 0.25); transform-origin: top left; cursor: -moz-grab; cursor: -webkit-grab; cursor: grab; } .moving { cursor: -moz-grabbing; cursor: -webkit-grabbing; cursor: grabbing; } .info { display: block; height: 40px; margin: 3px 6px; margin-right: 206px; padding: 3px 6px; line-height: 18px; } .legend { display: block; float: right; width: 195px; max-height: 100%; overflow-y: scroll; } .legend > div { padding: 6px; clear: right; } .legend > div span { opacity: 0.75; display: block; text-align: right; } .legend > div .name { max-width: 70%; word-wrap: break-word; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.