20.2. Log Levels
Table of Contents
Why Log Levels Matter
Log levels help you control how much information your application logs, and how important that information is. Without log levels, your logs quickly become a noisy wall of text that is hard to search and almost impossible to use for debugging or monitoring.
Log levels let you:
- Decide what to log in development vs production.
- Filter logs when searching for a problem.
- Send only important logs to alerting systems.
- Keep log volume (and storage cost) under control.
Most languages, frameworks, and logging libraries use a similar set of levels, from least to most severe:
| Severity (low β high) | Typical name |
|---|---|
| 1 | TRACE |
| 2 | DEBUG |
| 3 | INFO |
| 4 | WARN / WARNING |
| 5 | ERROR |
| 6 | FATAL / CRITICAL |
Rule: Log levels are about importance, not about where the code is. The deeper in your code, the more context you might log, but the level still depends only on how serious the situation is.
Common Log Levels and Their Meanings
TRACE
TRACE is the most detailed level. It is often turned off in most environments.
Use TRACE to log:
- Very fine-grained steps in complex algorithms.
- Every step of a request in a very noisy way.
- Extremely verbose debugging that you only turn on temporarily.
Examples:
2024-08-01T12:00:01Z TRACE Starting cache lookup for key=user:123
2024-08-01T12:00:01Z TRACE Cache miss, querying database for user_id=123
2024-08-01T12:00:01Z TRACE Mapping DB row to UserDTO for user_id=123When to use:
- Deep debugging of a tricky bug.
- Investigating performance issues by following each function call.
When not to use:
- In production by default. TRACE logs can be huge and slow your system.
DEBUG
DEBUG logs are for developers, not for business users or support teams. They help you understand how the application works internally.
Use DEBUG to log:
- Internal decisions.
- Values of important variables.
- Steps of a workflow that you may want to revisit later.
Examples:
2024-08-01T12:10:05Z DEBUG AuthMiddleware: JWT token validated for user_id=42
2024-08-01T12:10:05Z DEBUG get_user_orders: fetching orders for user_id=42, status='open'
2024-08-01T12:10:05Z DEBUG DB query executed in 12ms (SELECT * FROM orders WHERE ...)Typical usage by environment:
| Environment | DEBUG enabled? | Reason |
|---|---|---|
| Local dev | Yes | You want maximum visibility. |
| Staging | Often yes | To debug issues before production. |
| Production | Often no | To reduce noise and log volume. |
INFO
INFO is for normal, high-level events in your application. These are things that are expected and not problems.
Use INFO to log:
- Server start and stop.
- Successful processing of important business events.
- Scheduled jobs starting and finishing.
Examples:
2024-08-01T12:15:00Z INFO HTTP server started on port=8000, env=production
2024-08-01T12:15:02Z INFO User registered successfully user_id=987, email=user@example.com
2024-08-01T12:15:10Z INFO Daily report job completed duration_ms=4500, generated_reports=153INFO logs are usually always on in production, because they show:
- That the system is alive.
- What is happening over time.
- High-level user and business actions.
WARNING / WARN
WARNING means something unexpected happened, or something is not ideal, but the application can still continue.
Use WARNING to log:
- Temporary problems that you retry.
- Usage of deprecated APIs.
- Suspicious activity that might become a problem.
- Partial failures where you fall back to a default.
Examples:
2024-08-01T12:20:00Z WARNING Cache server not reachable, falling back to database
2024-08-01T12:20:01Z WARNING Deprecated endpoint /v1/users used by client_id=mobile-app-v1
2024-08-01T12:20:03Z WARNING Invalid login attempt for email=unknown@example.com, ip=203.0.113.5When to use WARNING instead of ERROR:
- The user still receives a valid response.
- The system recovers automatically.
- No data was lost or corrupted.
ERROR
ERROR means a request or operation failed, and the application could not do what it should have.
Use ERROR to log:
- Exceptions that cause a request to fail with a 4xx or 5xx response.
- Failed background jobs that did not complete.
- Data that could not be saved or processed.
Examples:
2024-08-01T12:25:10Z ERROR Failed to process order order_id=555, reason="payment declined"
2024-08-01T12:25:11Z ERROR Unhandled exception in /api/orders
Traceback (most recent call last):
...
2024-08-01T12:25:12Z ERROR Failed to send email to user_id=987, smtp_error="Timeout"Typical behavior:
- The request or job fails.
- The user often sees an error message.
- You might want alerts depending on how frequent the error is.
FATAL / CRITICAL
FATAL or CRITICAL logs mean something very serious happened. The system cannot continue working normally.
Use FATAL / CRITICAL to log:
- The application cannot start, for example database is not reachable at startup.
- Data corruption is detected.
- A critical dependency is gone and no fallback is possible.
Examples:
2024-08-01T12:30:00Z CRITICAL Database connection failed at startup, exiting. error="connection refused"
2024-08-01T12:30:05Z CRITICAL Configuration error: SECRET_KEY is missing, application cannot start
2024-08-01T12:30:10Z FATAL Unrecoverable error in payment service, shutting down workersUsually:
- FATAL/CRITICAL events should trigger an immediate alert.
- You often exit the process or restart the service.
Choosing the Right Level
Using the right log level is a skill. It directly affects how useful your logs are.
Here is a simple decision table:
| Situation | Suggested level |
|---|---|
| A normal API request completes with 200 OK | INFO or DEBUG |
| A background job starts and finishes normally | INFO |
| You are checking internal variables while developing a feature | DEBUG or TRACE |
| A cache lookup fails, but you fall back to the database successfully | WARNING |
| A user provides invalid input, and you return 400 Bad Request | INFO or WARNING |
| A request causes an unhandled exception and returns 500 Internal Server Error | ERROR |
| The app cannot connect to the database at startup | CRITICAL |
| You detect possible data corruption | CRITICAL |
Rule of thumb:
- INFO for normal events.
- WARNING when something is unusual but handled.
- ERROR when an operation fails.
- CRITICAL when the whole service is in danger.
HTTP Status Codes and Log Levels
You will often log based on HTTP status codes. A simple mapping you can start with:
| HTTP status range | Typical meaning | Usual log level |
|---|---|---|
| 1xx / 2xx | Success | INFO or DEBUG |
| 3xx | Redirect | INFO |
| 4xx (client error) | Client did something wrong | INFO or WARNING |
| 5xx (server error) | Server failed | ERROR or CRITICAL |
Examples:
- A 404 Not Found for a missing resource, when requested URL is random or wrong:
- Often
INFO(it is a normal case). - A 401 Unauthorized due to invalid token:
- Could be
INFOorWARNING(might show suspicious traffic). - A 500 Internal Server Error:
- Always at least
ERROR. - A 503 Service Unavailable during an outage:
ERRORorCRITICALdepending on severity.
Log Level Configuration
Most logging systems let you set a minimum level. Logs below that level are ignored.
For example:
| Environment | Minimum level | Meaning |
|---|---|---|
| Local dev | DEBUG | See everything except TRACE. |
| CI / testing | INFO or DEBUG | Focus on important events and debugging. |
| Staging | INFO | Less noise, but still enough details. |
| Production | INFO or WARNING | Ignore verbose debug logs. |
Pseudo configuration example:
logging:
level:
root: INFO
"my_app.database": DEBUG
"my_app.security": WARNINGIn this example:
- Default logs use INFO.
- Database related logs are more verbose at DEBUG.
- Security logs only log WARNING and above.
Examples of Good vs Bad Log Levels
Example 1: Cache and Database
Bad usage:
DEBUG Cache connection failed, falling back to database
ERROR Cache miss for user_id=123
INFO Database query OK for user_id=123Problems:
- A cache connection failure is more serious than DEBUG.
- A cache miss is not an ERROR, it is normal sometimes.
Better usage:
WARNING Cache connection failed, falling back to database
DEBUG Cache miss for user_id=123
INFO Loaded user profile user_id=123 from databaseExample 2: Validation Errors
Bad usage:
ERROR Validation failed for signup form: invalid emailIf the user simply typed their email wrong, this is not an internal error.
Better usage:
INFO Signup validation error email=not-an-email reason="invalid format"If you see a lot of such logs from the same IP or user, you can investigate.
Example 3: Startup Failure
Bad usage:
ERROR Database not reachable at startupThe application cannot start. This is more than just an ERROR.
Better usage:
CRITICAL Database not reachable at startup, exiting. host=db:5432This tells you that the entire service is down and needs urgent attention.
Log Levels and Alerting
Monitoring and alerting tools often use levels to decide what to alert on.
A common pattern:
- Do not alert on DEBUG or INFO.
- Maybe aggregate and alert on large numbers of WARNING logs.
- Alert on ERROR logs if they exceed a certain rate.
- Always alert on any CRITICAL log.
Example policies:
| Level | Alerting strategy |
|---|---|
| DEBUG | No alerts. |
| INFO | No alerts. Used for dashboards & history. |
| WARNING | Alert if rate is high for a long period. |
| ERROR | Alert if rate spikes or key endpoints affected. |
| CRITICAL | Immediate alert. |
Practical Guidelines for Writing Logs
- Choose level by impact, not by how tricky the code feels.
- Keep secrets out of logs, especially at DEBUG or TRACE:
- Do not log passwords, tokens, full credit card numbers, or full personal data.
- Be consistent:
- Use the same level for the same kind of event everywhere.
- Use higher levels for business failures:
- A failed payment or failed order processing is at least ERROR, even if the code did not crash.
- Use lower levels for expected irregular events:
- Cache misses, occasional invalid inputs, or retries can be INFO or WARNING.
Example of a full log story for a failed request:
2024-08-01T13:00:00Z INFO POST /api/orders user_id=42
2024-08-01T13:00:00Z DEBUG Validating order payload for user_id=42
2024-08-01T13:00:00Z WARNING Payment service timeout, retrying attempt=1
2024-08-01T13:00:01Z WARNING Payment service timeout, retrying attempt=2
2024-08-01T13:00:02Z ERROR Payment failed for order_id=777 user_id=42 reason="service unavailable"From these levels you can quickly see:
- What happened normally (INFO, DEBUG).
- What was unusual but handled (WARNING).
- Where it finally failed (ERROR).
This is the main purpose of log levels: to let you understand the story of your system at a glance.
Views: 7
KAHIBARO