Read more

Debug file system access in a Rails application

Tobias Kraze
May 06, 2022Software engineer at makandra GmbH

It might sometimes be useful to check whether your Rails application accesses the file system unnecessarily, for example if your file system access is slow because it goes over the network.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

The culprit might be a library like carrierwave that checks file existence or modification times, whereas your application could determine all this from your database.

Introducing strace

One option it to use strace for this, which logs all system calls performed by a process.

To do this, start your rails server using something like

DISABLE_SPRING=1 strace -e trace=file -f bin/rails s

The -e trace=file hides all non-file-system related calls. The -f instructs strace to also monitor forks.

You will now see your Rails log interwoven with the system calls, for example:

  Video Load (0.0ms)  SELECT  "images".* FROM "images" WHERE "image"."id" = $1 LIMIT $2  [["id", 975], ["LIMIT", 1]]
[pid 264211] stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2326, ...}) = 0
[pid 264211] stat("~/app/public/system/development/images/001/thumbnail.jpg", {st_mode=S_IFREG|0644, st_size=363471, ...}) = 0
  Rendered frontend/images/_thumbnail.haml (2.2ms)

In this example, some code in the _thumbnail.haml partial checks for the presence of the thumbnail.jpg, even though there was actually validation logic for it anyways.

Reducing noise

To reduce the amount of noise in the output, I recommend to change your development settings:

# config/environments/development.rb

Rails.application.configure do
  # ...
  
  config.cache_classes = true
  config.action_view.cache_template_loading = true

  config.after_initialize do
    # only necessary if you use haml-rails
    ActiveSupport.on_load(:after_initialize) do
      ActionView::Resolver.caching = true
    end
  end
  
  # ...
end
Posted by Tobias Kraze to makandra dev (2022-05-06 13:01)