Creating good logging in the application is hard. The application should not log too much or too little, so it's always a game of balance. Use log level wisely and always log errors.
Ideally, all application component should use the same logs format and include the following information:
- Time (ISO8601, UTC)
- Avoid using local time. UTC should be a golden standard for all timestamps as it will help to unify all systems in one time zone and to avoid misunderstandings while analysing logs from different systems.
- Logging level (FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE)
- Meaningful message
To make the message meaningful you should include some important pieces of information in it, like:
- include stack trace if any
- include thread name if it's a multi-threaded application
- include context like:
- Global request-id (to trace the whole operation across the services)
- Module/class (for errors and logic flow). This is not always possible
- Additional information about the event (like not just "user registered" but "user with ID 1234 registered")
It's better to use tabs to separate fields. Anyway, sticking to the libraries your language/framework provides is usually the best strategy. Try to avoid multi-line logs and context variables is preferable to separate extra fields.
Don’t log for troubleshooting purposes only! Logs could provide much more useful information for audit (who did what), profiling (part of the application surrounded by logs will give enough information about operation duration in milliseconds).
Top comments (1)
Great blog post! What do you think on masking sensetive data on logging, I guess it's also good practice to include. Just in case