In today's era, logs are the First and foremost source of truth when we want to analyze what is happening with the application, or if something goes south, logs will help to analyze/trace what makes the application behave in that manner.
Logs can act like a complete script of a TV series 😀 which indicate that what is happening in the system at a very detailed level, on change of log level, they can act as just a season of the same TV series, and on the further change of the log level, they can act as launch treasure for the same series that will give us minimum information of what is happening in the application.
So just like as per the need or interest, we either watch treasure, season and if the seasons are interested then we might watch the entire TV series right?
Similarly Imagine if based on the need, on change of the log level if application logging works similarly then that will be very useful and less hectic to digest and understand application behavior in the production environment, isn’t it?
But to ensure our application logs are indeed useful, there are some basic requirements. First and foremost, they need to be digestible. Meaning, they need to be structured in a way that both humans and machines can read, search, and analyze. that can be done by using a good logging library which will take care of generating the logs in a structured manner i.e JSON, XML
Below is a list of some tips and best practices that I preferably encourage to use while writing logs in any application.
Choose correct level
ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF, TRACE
Choosing a correct level will be a very important aspect of efficient logging before logging remembers the PTI rule.
PTI = Purpose, Type, Impact.. here is what it means
Purpose: For what purpose (debugging and development or trace routing a request like what data was sent to yield a particular result)
Type: Is it a major breakdown or something recoverable or is it just an FYI..
Impact: Single user or entire system, Absolutely helpful in debugging or no.
There are many more such, rules/criteria on behalf of those we can decide the log level, Will come up with another article on when to use which log level, till then would love to hear your thoughts in the comment section.
Keep the Audience in Mind
Why add logging to an application?
The only answer is that someone will have to read it one day or later, right? More importantly, it’s interesting to think about who will read those lines. Depending on the person you think will read the log messages you’re about to write, the log message content, context, and level can be quite different.
Those persons can be:
End-user - an end-user/customer trying to troubleshoot herself a problem (imagine a client or desktop application)
Solution engineer - someone from the Customer Solution Engineering team, trying to figure trace something based on customer reported issue.
QA engineer - a QA engineer, when doing quality assurance after the development cycle completed and during that face, they might have faced some issues.
A developer from the team either for debugging during development or solving a production issue.
A developer from another team trying to trace something at the time of integrations.
Of course, the developer knows the internals of the program, thus here log messages can be much more complex than if the log message is to be addressed to an end-user. So adapt your language to the intended target audience.
Avoid Logging Sensitive Information
We should avoid logging sensitive information of the application users, as well as the sensitive information of the application like
Passwords
Credit card numbers
Social security numbers
API Keys
Session identifiers Information the user has opted out of
Authorization tokens
PII (Personal Identifiable Information, such as personal names)
Database credentials
To achieve that, various logging libraries themselves provide mechanisms to filter the log message based on some patterns before writing to log file or console.
Provide Context
Being concise and logging short messages is recommended always. But there is a huge difference between writing concise logs and writing incomprehensible logs.
Consider this log message:
{"@timestamp":"2020-10-17T08:03:55.350+00:00","message":"user login/authentication failed"}
Not very insightful, right? But how about:
{"@timestamp":"2020-10-17T09:03:55.350+00:00", "message":"user login failed for customerI: 10, userId: 12","logger_name":"com.test.loging.User","thread_name":"main","level":"INFO","HOSTNAME":"Subhams-MacBook-Pro-2.local","caller_class_name":"com.test.loging.User","caller_method_name":"login","caller_file_name":"User.java","caller_line_number":123}
In logging, context is very important. adding contextual information to log messages creates a story and allows us, or any other team member to more easily understand and analyze the data.
Part of the context that can be added to logs are fields containing metadata. Common examples are application name, function name, class name, date time, caller-line-number, and so on.
Summing it up
Efficient logging requires planning and standardized things across the team, a step that most of the organization skip at the beginning of the development cycle, either intentionally or in the initial phase logging is simply not a top priority, but somewhere down the line planning should come into the picture as we all know logs play a crucial role to understand the behavior of application running in the production environment. So It’s time to get serious about Logging, by choosing log level wisely while writing the logs, along with proper context that will help to digest the log to the reader.
Also, read our next blog on Working With ThreadPoolTaskExecutor of Spring
Comments