Logging is the process of saving information about what your Ruby application is doing.
It’s very helpful, both in development & production environments.
Why?
Because the whole point of logging is to collect information about what happened, what went wrong & what went right.
All kinds of information can be logged:
- Slow SQL queries (so you can find & fix them)
- Error messages
- Detailed request information (URL, Controller, Params, Views…)
With this information, you can diagnose & find the source of problems in your application faster.
In a Rails app, logs are stored under the /log
folder.
In development mode, the development.log
file is used & you see log output on the terminal you’re running rails server
on.
Now:
Let’s learn how you can do logging in Ruby using the Logger
class!
The Logger Class
The Ruby Logger class gives you a way to generate logs with a default output format & different levels of severity.
Here’s how to create a log:
logger = Logger.new("my_log.txt")
This will write logging messages to my_log.txt
.
If you want to display messages on the terminal, where the program is running, you can log to STDOUT
.
Like this:
logger = Logger.new(STDOUT)
Logging messages can have different levels, depending on how critical they’re.
The levels are:
- DEBUG
- INFO
- WARN
- ERROR
- FATAL
- UNKNOWN
Every level has a corresponding instance method.
So if you want to log “info”.
Do this:
logger.info("I'm reading a RubyGuide about logging!")
This is what the actual log entry looks like:
# I, [2019-08-08T19:22:00.152079 #642] INFO -- : I'm reading a RubyGuide about logging!
Having these different levels helps you filter your log file, so you can find what you’re looking for faster!
It also helps you see how many errors & warn messages you generate over time.
Great stuff!
How to Format Your Logs
Using the default output format for your Ruby logs is great because tools can be built around it & more people can understand how it works.
Here’s a log line again:
# I, [2019-08-08T19:22:00.152079 #642] INFO -- : test
This has a few components:
- The “I” represents the first letter of the severity level
- Inside brackets, you find the timestamp & the process id (PID) of the process that generated this log message
- INFO is the full name of the severity level
- After the colon, we have the actual message that was logged
But this format may not be ideal for everybody.
So Ruby allows you to change it!
Here’s how:
logger.formatter = proc { |severity, datetime, progname, msg| "#{severity}, #{datetime}, #{msg}\n" }
As a result, you get this output:
DEBUG, 2019-08-08 19:39:01 +0200, testing
You can use this to add extra information that may be helpful for you & your team.
How to Limit Your Log Size
Logs can become really big files unless you keep track of their size.
If you run out of disk space because of logs, then all kinds of strange things start happening in your system.
There is a solution!
You can limit the size of your logs.
Here’s how:
MEGABYTE = 1024 ** 2 ONE_HUNDRED_MEGABYTES = MEGABYTE * 100 logger = Logger.new("my_log.txt", 1, ONE_HUNDRED_MEGABYTES)
The 1st parameter is where to save log messages.
The 2nd parameter is how many log files you want to keep (log rotation), and the last parameter is the maximum file size.
Log Reading & Filtering
Ok, you got your logs.
How do you read them & find what you need?
Logs are plain-text files, so you can use any text-processing tools you like.
For example:
Grep.
It’s a command-line tool you can use to filter text files.
Here’s how:
grep INFO my_log.txt
This gives you every line that has been logged as “INFO”.
You can search for any other text inside your logs using grep
, just replace “INFO” with what you’re looking for.
Another Unix tool you can use is called less
(with -R option).
It allows you to scroll through the logs using only your keyboard & it has a search function.
You can also use…
Tools specific for log management & searching.
Like Discourse’s logster gem.
Summary
You’ve learned about logging in Ruby, what it is, how it works, and how to use it.
Now it’s your turn to try this.
Thanks for reading!
Every time a helpful article!
Thanks!
Thanks for your support! 🙂
It’s good to know you find it helpful.
Cool – lots of helpful tidbits
Thanks for reading! 🙂
Thank you so much Jesus! You are a treasure to the Ruby community 😀
Thanks for your support Omar!
Very very good and helpful article. I actually decided to use this info in my current project . Thanks a lot, and please keep up the good work.
Nice! I’ll keep writing great articles for you 🙂
Always informative
ONE_HUNDRED_MEGABYTES = 1024 ** 4
There should be 100 * 1024 ** 2
PS: you can improve UX of your site if it will remember my name, email in the comment form 😉
Thanks for the correction 🙂