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 money motivation

Opscomplete powered by makandra brand

Save money by migrating from AWS to our fully managed hosting in Germany.

  • Trusted by over 100 customers
  • Ready to use with Ruby, Node.js, PHP
  • Proactive management by operations experts
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)