Building and deploying an application is only the beginning. You have to maintain it. When something goes wrong, how can you figure out what's the problem?
Like backups, logging is one of those topics that seems unnecessary until something goes wrong! It's very frustrating to fix a bug that's only reproducible in production without having any logs to help you debug it. This post covers the basics of logging in Ruby and adds logging to our no-rails app.
It's very easy to find and fix bugs when you're in the development mode. You have the terminal open with the Rails logs scrolling by you. If something goes wrong, just replay it, find the error in the terminal, and fix it.
But in production (or even staging), you can't just open the terminal and search the endless terminal output. Past a limit, it won't even let you scroll up. You need a better solution. You need to redirect the log streams to a different destination than the standard output to view or archive them, e.g. log files or a 3rd party service. You need logs that can be quickly searched and organized.
That's why structured logging is so important in troubleshooting errors. Often, you don't just need the exact error, but the trail of events that led to that error. Detailed logs provide the additional context needed to quickly identify and fix an issue.
You must have seen those postmortems from companies on their downtimes. Often, a detailed log trail provides the much-needed visibility into the sequence of events that happened leading to the issue.
Logging is important because of the visibility it brings into your application. There are many kinds of logs, here're a few I can think of off the top of my head.
Web Server Logs: Information about the incoming HTTP request, where did it come from, response (success or failure), request processing time, etc.
API Logs: Who made the call, what were the input params, how long did it take, etc.
Application Logs: Tracking various events in the application, e.g. user orders, registrations, unsubscribes, etc.
That's why, in this lesson, we'll take a break from adding new features and implement logging so we have a better chance to find and fix errors, when they inevitably pop up in future.