Writing Best Practices For Application Logs
Last updated September 09, 2024
Table of Contents
Logging is an important data source for troubleshooting issues, business intelligence, and meeting compliance. Logs give records of precisely what your application is doing when.
You can log from anywhere in your app’s code with an output statement. Heroku also aggregates logs from other components of the platform. For more info about logs aggregated from other sources and how logging works, see Logging. This article focuses on best practices for writing logs that your application code generates.
Heroku Enterprise customers with Premier or Signature Success Plans can request in-depth guidance on this topic from the Customer Solutions Architecture (CSA) team. Learn more about Expert Coaching Sessions here or contact your Salesforce account executive.
Define which events to log
Log events that tell the story of how your app is behaving. Always log:
- Application errors
- Input and output validation failures
- Authentication successes and failures
- Authorization failures
- Session management failures
- Privilege elevation successes and failures
- Other higher-risk events, like data import and export
- Logging initialization
- Opt-ins, like terms of service
Consider logging other events that address these use cases:
- Troubleshooting
- Monitoring and performance improvement
- Testing
- Understanding user behavior
- Security and auditing
For example, for auditing purposes, log an event whenever a user updates their profile in your app.
Include pertinent details
Heroku’s logging infrastructure records when and where something occurred. It automatically adds to your log output a timestamp and the dyno that a log message came from:
timestamp source[dyno]: message
Add context to the message content, such as:
- What action was performed
- Who performed the action
- Why a failure occurred
- Remediation information when possible for WARN and ERROR messages
- HTTP request ID - see HTTP Request IDs for more info.
The Open Web Application Security Project (OWASP) has a larger list of suggested event attributes. Choose attributes that provide just enough meaningful context.
Here is an example of not enough context:
2019-06-20T17:21:00.002899+00:00 app[web.1]: INFO: Address removed.
This message shows the event time and location (web.1
dyno), but only a general description of what happened.
Just enough context:
2019-06-20T17:21:00.002899+00:00 app[web.1]: INFO: Address removed by customer. {"addressid":18344857, "customerid":50333}
This message includes which customer removed which record.
Some logging add-on providers limit individual message size. Check your logging add-on provider’s documentation for size limitations.
Exclude sensitive information
In the Common Runtime, we expand the values of the config vars referenced in your code commands before sending the output to your logs for audit purposes. Avoid using direct references to sensitive environment variables where your app code writes to standard out (stdout) or standard error (stderr).
Keep security and compliance requirements in mind:
- Don’t emit sensitive Personal Identifiable Information (PII).
- Don’t emit encryption keys or secrets to your logs.
- Ensure that your company’s privacy policy covers your log data.
- Ensure that your logging add-on provider meets your compliance needs.
- Ensure that you meet data residency requirements.
Unless you are using Private Space Logging with a Shield Private Space, all log data passes through Heroku’s logging infrastructure located in the U.S. region. For more info, see Private Space Logging and Logplex.
Use structured logging
Human readable logs are helpful, but structured logs add value, especially as an application’s logs become more complex or as request throughput increases. Structured logging provides a well-defined format for your log entries so you can more easily parse, query, and process them for analytics.
The structure of log entries from the Heroku platform is called logfmt
, where each line consists of a single level of densely packed key/value pairs. This format is human readable and fairly easy to parse, if needed.
JSON is the de facto standard for structured logging, but consider using key=value pairs, XML, or another format for your application logs. Review the supported formats that your add-on provider can automatically parse.
Consider these unstructured log entries:
2019-06-20T17:21:00.002899+00:00 app[email-wrkr.1]: DEBUG: Fetching mailing list 14777
2019-06-20T17:22:00.000098+00:00 app[email-wrkr.1]: DEBUG: User 3654 opted out
Changing these entries to use structured JSON results in:
2019-06-20T17:21:00.002899+00:00 app[email-wrkr.1]: DEBUG: Fetching mailing list {"listid":14777}
2019-06-20T17:22:00.000098+00:00 app[email-wrkr.1]: DEBUG: User opted out {"userid":3654}
The consistent format of these log messages makes it straightforward for your chosen log drain to parse them, extract the JSON metadata, and make it available for searching and filtering.
Log at the correct level
Record events at the correct level.
Log levels:
INFO
- Informational messages that do not indicate any fault or error.WARN
- Indicates that there is a potential problem, but with no user experience impact.ERROR
- Indicates a serious problem, with some user experience impact.FATAL
- Indicates fatal errors, user experience is majorly impacted.DEBUG
- Used for debugging. The messaging targets specifically the app’s developers.
For example, logging an ERROR
as INFO
will interfere with troubleshooting. Also, if an exception is expected behavior and does not indicate degraded behavior, consider logging that exception as INFO
instead of ERROR
. For more details about log levels, see the Art of Logging.
To ensure you are logging at the correct level:
- Review your logging framework settings, especially if you didn’t set the log level.
- Document and review exceptions to determine whether to log as INFO
or ERROR
.
- Check other log messages to ensure they are recording at the level that you expect.
- Consider setting separate log levels on your development and production environments.
Additional Information
The Open Web Application Security Project (OWASP) provides an excellent logging cheat sheet containing guidance on all aspects of logging.
Heroku’s logging infrastructure has limited retention of your logs. See the Logging article for more info and provision a logging add-on or a custom log drain to persist your logs.