Paul Oms
Posted on October 19, 2021
It's really helpful to have a way to track what's going on with your application in production, things like: number of user sign ups, status of user accounts, number of X new database entries etc. Out of the box dashboards like Rails Admin are great but only go so far, eventually you will want significant customizations.
You could spend time coding a beautiful, custom dashboard to show you a summary of everything in real time. On top of coding it you'll spend time designing, testing, securing and deploying it. Plus digging into problems that pop up (what is monitoring your monitoring dashboard?). You might instead plug-in a 3rd party dashboard and query using that, which can be expensive and just as time consuming.
There's an easier way, which doesn't take away time from building your app or product: email. Specifically through email daily digests & notifications.
Compared to building a dashboard the advantages are numerous:
- Faster to code
- Doesn't consume any resources
- Minimal DevOps required
- Very easy to extend / customize
- Reuses your existing tech stack
- Almost no maintenance
- Regular notifications (you won't forget to check the dashboard)
- Everything is timestamped and archived by default
The main disadvantage is that it's not real time/interactive. But if you spot anything that requires a detailed drill down, you'll probably want to go in and do a detailed investigation through your app anyway.
Ultimately you should have several different tools monitoring your app to ensure things stay smooth e.g. external uptime monitors, exception trackers, log analysis, CPU/Memory usage tracking etc. This is an additional one you can add on for business logic monitoring
An example in Rails
To show you how easy this is, we'll create an example that sends the latest count of users every day to ourselves at the same time. You could extend this to send updates on anything tracked in your database (e.g. most popular article, unusual user behavior etc.)
Prerequisites:
- A Rails 6+ app
- A transactional email provider (e.g. Amazon SES, Postmark etc.) I recommend OhMySMTP and the associated Rails Gem: https://github.com/ohmysmtp/ohmysmtp-rails.
Email setup
Add this line to your application's Gemfile:
gem 'ohmysmtp-rails'
And then execute:
$ bundle
Configure your API Token
Retrieve your API token for your sending domain from OhMySMTP. You can find it under Organization -> Domain -> API Tokens
Open the credentials editor:
rails secret
rails credentials:edit
Then add your token:
ohmysmtp_api_token: "TOKEN_GOES_HERE"
Finally set OhMySMTP as your mailer in config/application.rb
:
config.action_mailer.delivery_method = :ohmysmtp
config.action_mailer.ohmysmtp_settings = { api_token: Rails.application.credentials.ohmysmtp_api_token }
Setup our email template
We'll prepare an email template to send to ourselves or our team:
rails generate mailer monitoring
Which will create our mailer and folders to place our email templates in.
Modify the app/mailers/monitoring_mailer.rb
file to include our daily notification and override our ApplicationMailer defaults:
class MonitoringMailer < ApplicationMailer
def daily_update
mail(to: "your-email-address@example.com", subject: "User Count Update")
end
end
When this is called ActionMailer will look for a daily_update
template to use. So let's go ahead and create that.
Create a file called daily_update.html.erb
in app/views/monitoring_mailer
with the email contents (note the placeholder for our User Count, count_of_users
):
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<p>Total users: <%= count_of_users %></p>
</body>
</html>
Our email is ready to go, now we need to calculate the count_of_users
variable and trigger the email regularly.
Create a Rake Task
A rake task is basically script that can be called from another location. We'll put our simple monitoring logic and email trigger here.
TIP: For a more complex example in Rails put your monitoring logic in a Job, and call the job from the Rake task. Jobs can be run asynchronously by Sidekiq or another queue manager and are much more easily tested
rails generate task monitor_my_app
This will generate a file lib/tasks/monitor_my_app.rake
- change the contents to the following (and here is where you'll make most customizations to fit your app):
namespace :monitor_my_app do
task email_latest_stats: [:environment] do
# Count number of new users
@count_of_users = User.where("created_at > ?", 24.hours.ago).count
## Send the email with latest count
MonitoringMailer.with(count_of_users: @count_of_users).daily_update.deliver_now
end
end
Test it by running our Rake task
We can call this locally with:
rake monitor_my_app:email_latest_stats
Or if you're using Capistrano for deployments you can run this on production:
bundle exec cap production invoke:rake TASK=monitor_my_app:email_latest_stats
In your development environment an email should pop up in the browser, in production you'll see it arrive in your inbox in a couple of seconds.
Schedule it to run every day
Rake tasks can be called from Cron, so we'll use the Whenever Gem to automatically add our job to our Crontab during deployment, and keep our schedule in change control.
After setting up Whenever, add the following to your schedule.rb
file:
every 1.days do
rake "monitor_my_app:email_latest_stats"
end
That's it, after you deploy you'll get an email every day with the total number of users in your app. You can keep extending this with more concepts and daily digest emails - much much easier than building a custom dashboard!
Posted on October 19, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.