GithubHelp home page GithubHelp logo

rubyatscale / singed Goto Github PK

View Code? Open in Web Editor NEW
384.0 7.0 9.0 60 KB

Get a flamegraph anywhere in your code base. Powered by stackprof, rbspy, and speedscope

License: MIT License

Ruby 99.35% Shell 0.65%
flamegraphs rails ruby

singed's Introduction

Singed

Singed makes it easy to get a flamegraph anywhere in your code base. It wraps profiling your code with stackprof or rbspy, and then launching speedscope to view it.

Installation

Add to Gemfile:

gem "singed"

Then run bundle install

Then run npm install -g speedscope

Usage

Simplest is calling with a block:

flamegraph {
  # your code here
}

Flamegraphs are saved for later review to Singed.output_directory, which is tmp/speedscope on Rails. You can adjust this like:

Singed.output_directory = "tmp/slowness-exploration"

Blockage

If you are calling it in a loop, or with different variations, you can include a label on the filename:

flamegraph("rspec") {
  # your code here
}

You can also skip opening speedscope automatically:

flamegraph(open: false) {
  # your code here
}

RSpec

If you are using RSpec, you can use the flamegraph metadata to capture it for you.

# make sure this is required at somepoint, like in a spec/support file!
require 'singed/rspec' 

RSpec.describe YourClass do
  it "is slow :(", flamegraph: true do
    # your code here
  end
end

Controllers

If you want to capture a flamegraph of a controller action, you can call it like:

class EmployeesController < ApplicationController
  flamegraph :show

  def show
    # your code here
  end
end

This won't catch the entire request though, just once it's been routed to controller and a response has been served (ie no middleware).

Rack/Rails requests

To capture the whole request, there is a middleware which checks for the X-Singed header to be 'true'. With curl, you can do this like:

curl -H 'X-Singed: true' https://localhost:3000

PROTIP: use Chrome Developer Tools to record network activity, and copy requests as a curl command. Add -H 'X-Singed: true' to it, and you get flamegraphs!

This can also be enabled to always run by setting SINGED_MIDDLEWARE_ALWAYS_CAPTURE=1 in the environment.

Command Line

There is a singed command line you can use that will record a flamegraph from the entirety of a command run:

$ bundle binstub singed # if you want to be able to call it like bin/singed
$ bundle exec singed -- bin/rails runner 'Model.all.to_a'

The flamegraph is opened afterwards.

Limitations

When using the auto-opening feature, it's assumed that you are have a browser available on the same host you are profiling code.

The open is expected to be available.

Alternatives

  • using rbspy directly
  • using stackprof (a dependency of singed) directly

singed's People

Contributors

aesthetikx avatar berkos avatar jean-francois-labbe avatar joeljunstrom avatar ngan avatar professor avatar technicalpickles 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

singed's Issues

Automate releasing

Right now, it's me manually pulling and running rake release. Ideally, this happens automatically on main when the gemspec version changes, or if it is manually run.

Tried this, but without luck so far:

It is currently failing with:

singed 0.2.2 built to pkg/singed-0.2.2.gem.
rake aborted!
There are files that need to be committed first.
/home/runner/work/singed/singed/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/opt/hostedtoolcache/Ruby/3.1.4/x64/bin/bundle:25:in `load'
/opt/hostedtoolcache/Ruby/3.1.4/x64/bin/bundle:25:in `<main>'
Tasks: TOP => release => release:guard_clean
(See full trace by running task with --trace)

I thought it could be the cache step, but I've added vendor/bundler to .gitignore . It's unfortunate it doesn't tell you what is uncommitted.

My next thought is to add a git status to the build, but that might not trigger in the right place. If that doesn't show it, then I think it's a matter of adding rake tasks to do git status before various steps ๐Ÿค”

Add License to gemspec

License scanners indicate this gem license is "Unknown" since it's not in the gemspec.

Gem::Specification.new do |spec|
  spec.name          = 'singed'

  spec.version       = '0.2.0'
  spec.authors       = ['Josh Nichols']
  spec.email         = ['[email protected]']
+ spec.licenses = 'MIT'

`label` cannot be provided as a keyword

The readme mentions:

If you are calling it in a loop, or with different variations, you can include a label on the filename:

flamegraph(label: "rspec") {
  # your code here
}

This is not accurate, as it results in:

     ArgumentError:
       unknown keyword: :label

If the library wants to support both a normal parameter and a keyword arg, it could use:

def flamegraph(_label = nil, label: _label, open: true, ignore_gc: false, interval: 1000, &block)

Running in project with rspec

It needs to clarify at README that in projects with rspec, the gem 'singed' needs to be at same group as rspecgem in your Gemfile.

Otherwise you get this:

bundle exec singed -- bin/rails runner 'User.all.to_a'
You can remove `require 'dalli/cas/client'` as this code has been rolled into the standard 'dalli/client'.
bundler: failed to load command: singed (/Users/kivanio/.rbenv/versions/3.2.1/bin/singed)
/Users/kivanio/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/singed-0.1.1/lib/singed/rspec.rb:3:in `<main>': undefined method `configure' for RSpec:Module (NoMethodError)

RSpec.configure do |config|
     ^^^^^^^^^^

Received NoMethodError: undefined method `print_json'

(this is probably an edge case)

My project had stackprof on 0.2.12 in the Gemfile.lock. It turns out print_json is not defined in this version. It might help someone in the future if you update your gemspec to ensure a supported version of stackprof is installed:

spec.add_dependency 'stackprof', '>= 0.2.13'

Need to create folder tmp/speedscope before using CLI

I needed to run mkdir tmp/speedscope to make it work

bundle exec singed -- bin/rails runner 'User.all.to_a'
You can remove `require 'dalli/cas/client'` as this code has been rolled into the standard 'dalli/client'.
๐Ÿ”ฅ๐Ÿ“ˆ Singed needs to run as root, but will drop permissions back to your user. Prompting with sudo now...
Password:
$ sudo --preserve-env rbspy record --format speedscope --file tmp/speedscope/speedscope-cli-20230309144106.json --silent -- bin/rails runner User.all.to_a
Dropping permissions: running Ruby command as user kivanio
rbspy is recording traces. Press Ctrl+C to stop.
You can remove `require 'dalli/cas/client'` as this code has been rolled into the standard 'dalli/client'.
Wrote raw data to /Users/kivanio/Library/Caches/rbspy/2023-03-09-lxTiyfen4D.raw.gz
Wrote formatted output to tmp/speedscope/speedscope-cli-20230309144106.json
Something went wrong while rbspy was sampling the process. Here's what we know:
- Failed to create output file tmp/speedscope/speedscope-cli-20230309144106.json
- No such file or directory (os error 2)
bundler: failed to load command: singed (/Users/kivanio/.rbenv/versions/3.2.1/bin/singed)
/Users/kivanio/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/singed-0.1.1/lib/singed/cli.rb:147:in `system': Command failed with exit 1: sudo (RuntimeError)

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.