Efficient Application Logging Practices

Chien Hoang
5 min readNov 25, 2023

--

Effective logging is essential in software development, especially in complex systems such as distributed architectures and microservices. It’s not just about capturing information, but doing so efficiently and strategically. In moments of production issues, it’s often the logs that come to the rescue, providing crucial insights to resolve the problems swiftly.

The Importance of Logging

Logging offers traceability, support in debugging, monitors performance, and helps in meeting compliance and security standards in distributed systems.

Common Logging Pitfalls

Issues like excessive resource consumption, performance impact, noisy logs, and exposing sensitive data are common pitfalls of inefficient logging practices.

Principles of Efficient Logging

Effective logging should be relevant, assist in diagnostics, avoid redundancy, and ensure information security.

Real-World Examples

Example 1: Handling Order Processing

Context: Consider an e-commerce application where users can place orders. When processing an order, several steps are involved, such as verifying the product’s availability, processing payment, and updating the order status.

Potential Failure Case: A common issue might arise in the payment processing step. For instance, the payment gateway might be temporarily unavailable or the user’s payment could fail due to insufficient funds.

How to Log This Effectively:

Step 1, Log the Start of the Process: When the order processing begins, log an informational message indicating the start of the process.

logInfo(`Order processing started for Order ID: ${orderId}`

Step 2, Log the Payment Attempt: Before attempting to process the payment, log the action.

logInfo(`Attempting payment for Order ID: ${orderId}`);

Step 3, Handle and Log Failures: If the payment processing fails, log an error with relevant details.

try {
// Code to process payment
} catch (e) {
if (e instanceof PaymentException) {
logError(`Payment processing failed for Order ID: ${orderId}: ${e.message}`);
// Additional error handling
}
}

Step 4, Log the Outcome: Regardless of success or failure, log the final outcome of the order processing.

logInfo(`Order processing completed for Order ID: {$orderId}`);

Key Points:

  • Specificity: Each log message is specific and informative, providing a clear context (like the Order ID).
  • Error Details: In case of failures, detailed error messages help in quick diagnosis.
  • Level Appropriateness: Informational messages are logged as ‘info’, while errors are logged as ‘error’, aiding in log filtering and analysis.

This approach ensures that during the order processing lifecycle, any issues can be quickly identified and addressed, minimizing disruption and improving user experience.

Example 2: Logging HTTP Response Codes

Context: In web applications, handling HTTP responses correctly is crucial. Often, developers log all responses, including client errors (4xx status codes), as errors. However, not all HTTP responses signify an application error.

Scenario: Consider a scenario where a user requests a resource that doesn’t exist, resulting in a 404 (Not Found) status code.

Ineffective Logging Practice: Logging all 4xx responses as errors:

logError(`Error: HTTP 404 Not Found for URL: ${url}`);

Effective Logging Practice:

Step 1, Differentiate Between Client and Server Errors: Log 4xx responses as ‘info’ or ‘debug’, since they are often client errors, not application errors.

logInfo(`HTTP 404 Not Found for URL: ${url}`);

Step 2, Reserve ‘Error’ Logs for 5xx Server Errors: These indicate issues on the server-side that need immediate attention.

if (statusCode >= 500) {
logError(`Server error: HTTP ${statusCode} for URL: ${url}`);
}

Step 3, Include Relevant Details: Ensure logs include specifics like the URL, user ID, or other context to help in debugging.

logDebug(`HTTP response for User ID: ${userId}, URL: ${url}, Status Code: ${statusCode}`);

Key Points:

  • Appropriate Log Levels: Use the correct log level based on the nature of the response. Not all HTTP responses are errors.
  • Contextual Information: Providing details like the user ID, URL, and status code aids in understanding the log’s context.
  • Efficient Troubleshooting: This practice helps in quickly identifying actual errors and reduces noise in the log files.

By logging HTTP responses correctly, developers can avoid cluttering their logs with non-critical information, making the logs more effective for monitoring and troubleshooting real issues.

Example 3: Avoiding Sensitive Data in Logs

Context: When logging information related to user actions or system processes, it’s common to inadvertently include sensitive data. This can be a significant security risk, especially with data like passwords, personal identification numbers, or credit card details.

Scenario: Suppose you have a function that handles user authentication, and you need to log the process for debugging purposes.

Ineffective Logging Practice: Logging user credentials directly:

logInfo(`User login attempt: username — ${username}, password — ${password}`);

Effective Logging Practice:

Step 1, Avoid Logging Sensitive Data: Never log sensitive information like passwords or personal user data.

logInfo(`User login attempt for username: ${username}`);

Step 2, Use Placeholders for Sensitive Fields: If you must indicate the presence of sensitive data, use placeholders.

logInfo(`User login attempt: username — ${username}, password — [PROTECTED]`);

Step 3, Implement Log Masking: For fields that may contain sensitive data, implement masking or tokenization.

const maskedPassword = '*'.repeat(password.length);
logDebug(`Processing login for ${username} with password: ${maskedPassword}`);

Key Points:

  • Security First: Always prioritize security when logging, especially in authentication processes.
  • Data Minimization: Only log the necessary amount of data needed for debugging or monitoring.
  • Compliance with Regulations: Be aware of legal requirements regarding data protection and privacy, like GDPR.

In this example, sensitive data is carefully handled to ensure security and compliance. By logging thoughtfully, developers can maintain useful logs without compromising user data privacy.

Log Tracing in Microservices

  • Importance: In a microservices architecture, tracking a request across multiple services is crucial.
  • Trace ID: Implement a unique trace ID (like an order ID) that follows a request through all service logs.
  • Service Owner: Include the service owner will help to identify from where the logs come
  • Example: logDebug(`Processing request Trace ID: ${traceId}, Service: Payment`);

Best Practices for Efficient Logging

Include log level management, structured and contextual logging, log rotation, using logging frameworks, and integrating logging with alerting and monitoring tools.

Conclusion

Efficient logging, involving a strategic approach to content, format, and management, is key to maintaining performance, facilitating maintenance, and enhancing troubleshooting in software systems. Remember, when production issues arise, it’s the well-implemented logs that often come to our rescue, underscoring the indispensable role of logging in modern software development.

At Tamara, our commitment to logging goes beyond conventional practices. We leverage a suite of open-source tools like ELK (Elasticsearch, Logstash, Kibana) for efficient log management, and Grafana and Prometheus for advanced monitoring and visualization. But we don’t stop there; recognizing the unique challenges and needs of our systems, we have also invested in building custom alerting services. These tailor-made solutions enable us to swiftly detect and respond to issues, ensuring our applications and systems run smoothly and reliably.

This blend of industry-standard tools and custom-built solutions is a testament to Tamara’s dedication to quality, reliability, and innovation in all our software endeavors.

Please share your experiences or tips for efficient logging, especially in complex system environments.

--

--

Chien Hoang
Chien Hoang

Written by Chien Hoang

Tech Driven currently @Tamara an Unicorn Fintech startup 🦄

Responses (3)