Post

Rails log monitoring - tutorial and home-made example

What is log monitoring

“Log monitoring” means tracking warnings and bugs. And put a backtrace history in a file accessible to the team. Locally, you don’t need this because each error will be printed in the console, and will blow in the current tab of your browser. It’s okay because you’re the developer, but you probably don’t want the final user to see any backtrace - and, in a shiny, ideal world, not any bug.

So you have to handle exceptions for your user in the most comfortable way possible, and you should try to monitor what happened in order to correct the bug afterward.

Correcting bugs afterward is not something to be targeted, but, in the other way, we have to humbly admit that bugs will arise, even if we did everything to avoid them.

To catch bugs as soon as possible, developers often drop a monitoring solution right before the 1st day of live production of your app.

No “Rails way” available

The “Rails way” is some kind of philosophy. Simplicity, convention over configuration, readability. It could be viewed as a “Zen” philosophy for coders (or Hakuna matata, pick your poison).

The use of ActiveRecord in Rails is often recognized as “the Rails way” to access data : intuitive, straightforward, readable, etc.

There’s no such thing alas for monitoring.

Teams tend to use external apps for such features, but here we will rely on the incredible abilities of Rails to integrate 3rd party tools to save a few bucks.

Enter logster

logster is a Rails gem that will track bugs and their stacktrace. Perfect for in-house monitoring. Take time to view their GitHub repository, the main screenshot should be clear enough

Prerequisites for this tutorial

Check that you have at least the following versions. You need Redis to be installed and running.

1
2
3
4
5
6
7
8
9
10
11
12
$> ruby -v
ruby 3.1.2p20 // you need at least version 3 here
$> bundle -v
Bundler version 2.2.11
$> npm -v
8.3.0 // you need at least version 7.1 here
$> yarn -v
1.22.10
$> redis-cli -v
redis-cli 6.0.5
$> redis-cli PING
PONG

How fun is the last command ? It’s just saying that Redis is running. Now let’s go back to work ;)

Install minimalistic Ruby-on-Rails app (no monitoring so far)

Type in your shell :

1
2
3
4
5
mkdir logmonitor && cd logmonitor 
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'rails', '~> 7.0.0'" >> Gemfile
bundle install
bundle exec rails new . --force -d=postgresql --minimal

If you want to know more about the last command, you can read this tutorial about the “rails new” options

If you have git installed, maybe it’s time here to do a first commit git add . && git commit -m 'firstcommit' so that you can track progress.

Continue in your shell by typing- or just copy/paste :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  # Create a default controller
  echo "class HomeController < ApplicationController" > app/controllers/home_controller.rb
  echo "end" >> app/controllers/home_controller.rb

  # Create another controller
  echo "class OtherController < ApplicationController" > app/controllers/other_controller.rb
  echo "end" >> app/controllers/other_controller.rb

  # Create routes
  echo "Rails.application.routes.draw do" > config/routes.rb
  echo '  get "home/index"' >> config/routes.rb
  echo '  get "other/index"' >> config/routes.rb
  echo '  root to: "home#index"' >> config/routes.rb
  echo 'end' >> config/routes.rb

  # Create a default view
  mkdir app/views/home
  echo '<h1>This is home</h1>' > app/views/home/index.html.erb
  echo '<div><%= link_to "go to other page", other_index_path %></div>' >> app/views/home/index.html.erb
    
    # Create another view
  mkdir app/views/other
  echo '<h1>This is another page</h1>' > app/views/other/index.html.erb
  echo '<div><%= link_to "go to home page", root_path %></div>' >> app/views/other/index.html.erb

  
  # Create database and schema.rb
  bin/rails db:create
  bin/rails db:migrate
  

If git is installed locally, you can do some git add . && git commit -m 'added default files'. And add gitk --all & to view what changed since the last commit.

Good ! Run

1
bin/rails s

And open your browser to see your app locally. You should see something like this :

localhost
localhost

Add redis to Rails

Add this to your gemfile :

1
gem 'redis'

And run bundle install.

Good ! Your Rails app is now able to talk to two databases : Postgres and Redis.

A Rails bug to be monitored later

We have here two pages : the home page, and the other page. We don’t want our app to crash immediately, so let’s say the other will.

Add a division by zero (ooh!) in the action of the controller of the other page

1
2
3
4
5
class OtherController < ApplicationController  
  def index 
    42 / 0 # wow!
  end
end

Add logster, and your Rails app can now monitor itself

Add this to your Gemfile

1
gem 'logster'

And run

1
bundle install

Add a route in config/routes.rb in order to view logs :

1
2
# inside config/routes.rb
mount Logster::Web => "/logs"

Great ! It’s time to see where all this leads.

Stop your local web server, launch it again with

1
bin/rails s

Go to the home page, click to the other page. Boom! you have a “division by zero” error.

Now what appears if you go to http://localhost:3000/logs ?

localhost
error

You won!

This post is licensed under CC BY 4.0 by the author.