Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterate on REAMDE #25

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI Test
name: Specs
on: [ push ]
jobs:
build:
Expand Down
File renamed without changes.
46 changes: 37 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# Singed


[![Gem Version](https://badge.fury.io/rb/singed.svg)](https://badge.fury.io/rb/singed) ![CI](https://github.com/rubyatscale/singed/actions/workflows/specs.yaml/badge.svg?event=push) ![Lint](https://github.com/rubyatscale/singed/actions/workflows/standard.yaml/badge.svg?event=push)


Singed makes it easy to get a flamegraph anywhere in your code base. It wraps profiling your code with [stackprof](https://github.com/tmm1/stackprof) or [rbspy](https://github.com/rbspy/rbspy), and then launching [speedscope](https://github.com/jlfwong/speedscope) to view it.

But why would you want to do this? At least a couple of reasons:

- you have code that you either feel, think, or KNOW is slow
- you are curious about how some code actually runs

## Installation

Add to `Gemfile`:
Expand All @@ -16,7 +25,7 @@ Then run `npm install -g speedscope`

## Usage

Simplest is calling with a block:
The simplest way is to wrap your code with a block

```ruby
flamegraph {
Expand All @@ -30,7 +39,7 @@ Flamegraphs are saved for later review to `Singed.output_directory`, which is `t
Singed.output_directory = "tmp/slowness-exploration"
```

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

```ruby
Expand All @@ -39,17 +48,30 @@ flamegraph("rspec") {
}
```

You can also skip opening speedscope automatically:
You can also skip opening speedscope in a browser automatically:

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

### RSpec
##### Options

`flamegraph` takes some of the options that [stackprof]() does:

If you are using RSpec, you can use the `flamegraph` metadata to capture it for you.
- `ignore_gc: true`: if your profiled code is very memory heavy, the garbage collection can make it harder to read. ignoring gc can make it more readable, but it's also a sign to use [memory_profiler](https://github.com/SamSaffron/memory_profiler).
- `interval: 1000` (in ms): how frequently to sample. for very small

Plus some of its own:

- `label: "your-description"`: a label to include in the filename
- `open: false`: don't try to `open` the flamegraph in a browser
- `io: File.open("your-output")` where to write the output, defaults to `$stdout`

#### RSpec

If you are using RSpec, you can use the `flamegraph` metadata to capture it for you. This [RSpec::Core::Hooks#around](https://rubydoc.info/gems/rspec-core/RSpec%2FCore%2FHooks:around), so focuses only on code inside the example block.

```ruby
# make sure this is required at somepoint, like in a spec/support file!
Expand All @@ -62,7 +84,7 @@ RSpec.describe YourClass do
end
```

### Controllers
#### Controllers

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

Expand All @@ -76,9 +98,9 @@ class EmployeesController < ApplicationController
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).
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
#### 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:

Expand All @@ -90,7 +112,7 @@ PROTIP: use Chrome Developer Tools to record network activity, and copy requests

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

### Command Line
#### Command Line

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

Expand All @@ -101,6 +123,12 @@ $ bundle exec singed -- bin/rails runner 'Model.all.to_a'

The flamegraph is opened afterwards.

## How to read a flamegraph

You've generated a flamegraph, now what? That's a great question. Here's some resources for getting started:

- [technicalpickles/flamegraph-lighting-talk](https://github.com/technicalpickles/flamegraph-lighting-talk)
- [Pairin' with Aaron: Flamegraphs and App Performance - YouTube](https://www.youtube.com/watch?v=9nvX3OHykGQ)

## Limitations

Expand Down
Loading