Skip to content

speedshop/gvl_metrics_middleware

Repository files navigation

GVL Metrics Middleware

gvl_metrics_middleware is a Ruby gem that provides middleware for monitoring and gathering metrics on Global VM Lock ( GVL) in multi-threaded Ruby applications. This gem leverages the gvl_timing gem to measure time spent in the GVL and invokes a provided callback with the collected metrics data.

Installation

Add the gem to your application’s Gemfile, and run bundle install to install the gem:

gem 'gvl_metrics_middleware', git: "https://github.com/speedshop/gvl_metrics_middleware.git"

Usage

The gvl_metrics_middleware automatically inserts the nessecary middleware into your application’s stack. To get started, configure a callback to handle the GVL metrics. Place the following configuration in your application’s config/initializersdirectory:

# config/initializers/gvl_metrics_middleware.rb
GvlMetricsMiddleware.configure do |config|
  config.rack do |total, running, io_wait, gvl_wait|
    # Your code here...
  end

  config.sidekiq do |total, running, io_wait, gvl_wait|
    # Your code here...
  end
end

For example, if you would like to record the GVL metrics in New Relic, you can use the following configuration.

# config/initializers/gvl_metrics_middleware.rb
GvlMetricsMiddleware.configure do |config|
  config.rack do |total, running, io_wait, gvl_wait|
    NewRelic::Agent.record_metric("Custom/Rack/GVL/total", total)
    NewRelic::Agent.record_metric("Custom/Rack/GVL/running", running)
    NewRelic::Agent.record_metric("Custom/Rack/GVL/io_wait", io_wait)
    NewRelic::Agent.record_metric("Custom/Rack/GVL/gvl_wait", gvl_wait)
  end

  config.sidekiq do |total, running, io_wait, gvl_wait|
    NewRelic::Agent.record_metric("Custom/Sidekiq/GVL/total", total)
    NewRelic::Agent.record_metric("Custom/Sidekiq/GVL/running", running)
    NewRelic::Agent.record_metric("Custom/Sidekiq/GVL/io_wait", io_wait)
    NewRelic::Agent.record_metric("Custom/Sidekiq/GVL/gvl_wait", gvl_wait)
  end
end

After configuring, you should be able to set up custom charts in New Relic to visualize the GVL metrics. Here is an example chart:

Screenshot of the GVL metrics chart on New Relic

Available Metrics

The gvl_metrics_middleware reports the following metrics.

  • total: The total duration of the request processing time, which is the sum of running, io_wait, and gvl_wait. This corresponds to the returned value from the value returned by the GVLTiming::Timer#duration method in gvl_timing.
  • running: The time a thread held the GVL and performed work (a.k.a CPU time). This corresponds to the value returned by the GVLTiming::Timer#cpu_duration method.
  • io_wait: The time spent waiting for I/O operations after releasing the GVL. This corresponds to the value returned by the GVLTiming::Timer#idle_duration method.
  • gvl_wait: The time spent waiting to acquire the GVL. This corresponds to the value returned by the GVLTiming::Timer#stalled_duration method.

Performance Overhead

The overhead introduced by gvl_metrics_middleware is minimal. Benchmarking has shown only a 1% difference in response times between scenarios with and without GVL metrics collection. This result has been validated through an A/A test, where both the control and experiment groups ran identical code, and the difference remained at 1%. This 1% overhead is consistent with those reported in Shopify's gvltools, where the overhead was measured at 1-5% in a production environment.

As stated in the README of gvltools`, the exact overhead is not yet known. However, unless you observe an immediate, significant jump in response times after deployment, the overhead is negligible and should not impact application performance. This makes the middleware a reliable choice for tracking GVL metrics in production environments.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/speedshop/gvl_metrics_middleware. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the GvlMetricsMiddleware project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

About

No description, website, or topics provided.

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published