Your Log Level of Choice

One of the more complex topics that often receives less attention in software development is the proper use of logs. I would venture to say that I have seen as many variations as there are companies, and within companies, as many as there are teams, and within teams, as many as there are projects. This is because, when it comes to adding logs, there seem to be as many styles as there are developers. In an area where personal style and objective perception significantly influence how standards are applied, it becomes challenging to define strategies that facilitate subsequent monitoring and debugging. After all, talking about logs is talking about maintainability. And we all know that maintaining our code is as important, if not more so, than writing it in the first place.

As a confessed poor user of logs and their levels, I have taken some time to review certain concepts and try to create a brief guide primarily focused on Laravel, but applicable to other contexts.

“The process of logging is often the first step in understanding what’s happening in your code. It provides a record that helps you diagnose problems and improve your system.”

Logs, a brief intro

When we talk about logs, we refer to the records that our applications generate to document events and activities. They are like a diary or ledger for our application, where both successes and setbacks are noted. These records are essential because they help us understand the behavior of the application, identify problems, and ultimately improve the user experience.

You can implement your own logging system, from something as simple as appending messages to the end of a text file to creating records in a database or sending messages to a tool like Slack. Depending on your needs, the strategy can range from a simple catch-all log to an organized table where you can perform complex searches, or even an alert system that sends you instant notifications about the most important events in the system. All of this becomes much simpler and more escalable if you use well-established protocols and specialized tools.

Syslog is a standard protocol that allows systems to send log messages to a centralized server. Why is this useful? Because it helps us keep everything in one place, making it easier to monitor and analyze logs from multiple applications and servers. It’s like having an organized library where you can quickly and efficiently find the information you need. Using a series of severity levels from 0 to 7, it becomes very straightforward to classify messages.

In this article, we’ll focus on reviewing log levels, understanding the purpose of each one, and exploring a practical example with Laravel. Log messages are a form of communication, and the choice of severity level reflects the intent behind each entry, making both search and code maintenance easier. For example, you’ll want to set up notifications to alert you if the system goes down, but you wouldn’t want to be woken up at 3 a.m. if a user enters an unusual character in a registration form. Similarly, you’ll want to navigate errors easily without normal or minor events cluttering the log.

When reviewing code, or revisiting your own work months later, you’ll want to quickly recognize whether a log is a forgotten debug line or an important warning you need to retain in production. Most tools won’t alert you if you systematically use Log::info for debugging or logging errors, and few teammates will risk being seen as overly picky if they call it out in a pull request. So, it’s a good idea to invest a bit of time in choosing log levels wisely.

Choosing the right log level

0 Emergency: system is unusable

If your application depends on a service and that service fails, such as a database whose cluster is completely down, you are facing an emergency. You should consider as emergencies those failures in critical components that become unusable and require immediate attention. When monitoring your system in production, it is essential to have immediate visibility of this type of message, whether through alerts via an external service or a custom notification configuration, such as Slack, email, among others.

Example

Reserve this level for events that require an immediate response to restore the application’s availability. Avoid using it excessively, as it could lead to “alert fatigue.”

1 Alert: action must be taken immediately

A level below an emergency is a failure that requires immediate action but does not render the system completely unusable. This type of error includes, for example, the loss of critical configurations that affect essential integrations, such as a payment provider, blocking only part of the application.

Log::alert("Missing API key for payment provider. Transactions cannot be processed.");

Example

Use the alert level when a quick human intervention is needed to prevent system disruption.

2 Critical: critical conditions

Critical errors do not require an immediate response, but they can lead to serious problems if left unresolved. For example, an error in the payment gateway during peak hours.

Example

Use the critical level for serious errors that affect the business but do not require an immediate fix, allowing for a scheduled intervention.

3 Error: error conditions

A failure in a part of the application that does not prevent the system from functioning. For example, when a user registration fails due to validation errors or violation of database constraints.

Example

Use the error level for non-fatal conditions that affect functionality, ideally providing detailed context.

4 Warning: warning conditions

Under certain conditions, unusual behaviors may arise that are not errors but could indicate potential problems. For example, a significant delay in the response of a third-party API, which could affect performance without stopping the system

Log::warning("Slow response from shipping API. Response time: {$responseTime}ms.");

Example

Use the warning level for events that, if they recur, may require investigation, as they could indicate latent problems. This level allows for monitoring potential issues without classifying them as errors.

5 Notice: normal but significant condition

Significant changes occur in the system’s conditions without implying errors. For example, when there is a loss in the cache that requires data to be loaded from the database.

Example

Use the notice level for significant events that do not impact functionality but may be useful for monitoring application behavior or identifying trends.

6 Informational: informational messages

Normal events of the application, such as user actions or routine system activities. For example, when a user logs in successfully.

Example

Use the info level to log expected events, but avoid logging every minor action to prevent noise. Limit it to important actions that can assist in auditing the system.

7 Debug: debug-level messages

During development, it is useful to have detailed visibility into technical information or issues that arise when debugging errors. This type of information is generally not useful in production and is, in fact, discouraged. For example, tracing the execution time of database queries in different scenarios.

Example

Use the debug level to obtain details during development and disable it in production.


RFC5424 The Syslog Protocol – March 2009
Laravel logging
Create images from code with ray.so


Posted

in

by

Tags:

Comments

Leave a Reply