•  Back
  • To log or not to log?

    Logging - the when, the where, and the what.

    Yes, you should log, and you know it. :-) You have this piece of information and you are deciding if that is the right moment to log, if that’s the right place to add the log call or if that particular information should be logged at all.

    This is the standard guideline I adopt to decide whether I should log something or not.

    Note
    Remember NEVER to log sensitive information about your users or even information that would allow someone to identify the user. If you are unsure about the information being personal identification or sensitive, ask the organization.

    Note #2: For more tips about information to log related to exceptions, visit this other post about Exception Handling.

    Log Levels Usage

    Fatal

    One or more key business functionalities are not working, and the whole system doesn’t fulfill the business functionalities. In other words, use it for severe errors that cause premature termination. Use it for catastrophic errors (errors that may cause the application to crash).

    Error

    One or more functionalities are not working, preventing some functionalities from working correctly. In comparison to Fatal, use Error for other runtime errors or unexpected conditions. Use it for errors that will prevent a request from being completed. Usually, a result of an exception that could not be completely treated/worked around.

    Warn

    Unexpected behavior happened inside the application, but it is continuing its work, and the key business features are operating as expected. Use it for deprecated APIs, poor use of API, ‘almost’ errors, other runtime situations that are undesirable or unexpected, but not necessarily “wrong”. These can indicate that a problem has happened and the system recovered (like an exception that was worked around) or flag something that could be a problem depending on the circumstances. If the circumstances that determine it to be a problem can be determined from the code, choose to log an error if they are present instead.

    Info

    An event happened, but it is purely informative and can be ignored during normal operations. Use it for interesting runtime events (startup/shutdown of services, etc.).

    Debug

    Debug is a log level used for events considered helpful during the software debugging when more granular information is needed. Use it for detailed information on the flow through the system. This is expected to be very verbose. It should be enabled during testing but not in production except in extreme circumstances. In production, it should be enabled for limited scopes (specific packages/classes) and limited time.

    Trace

    A log level describing events showing step-by-step execution of your code that can be ignored during the standard operation but may be useful during extended debugging sessions. Use it, for example, to annotate each step in the algorithm or each individual query with parameters in your code. It is generally not ok to have it enabled in environments other than dev, but exceptions can be considered.

    Log Placement

    Fatal

    Usually, inside catch blocks. When inside catch blocks, if the exception is not being rethrown (encapsulated or as-is), it is acceptable to log the exception at this time.

    Error

    Usually, inside catch blocks. When inside catch blocks, if the exception is not being rethrown (encapsulated or as-is), it is acceptable to log the exception at this time.

    Warn

    Unexpected behavior happened inside the application, but it is continuing its work, and the key business features are operating as expected. Use it for deprecated APIs, poor use of API, ‘almost’ errors, other runtime situations that are undesirable or unexpected, but not necessarily “wrong” These can indicate that a problem has happened and the system recovered (like an exception that was worked around) or to flag something that could be a problem depending on the circumstances. If the circumstances that determine it to be a problem can be determined from the code, choose to log an error if they are present instead. It can often be placed in catch blocks, but being a warning means it is not a blocking issue, so the exception should be either rethrown (encapsulated or as-is) or worked around. If worked around, the exception can be logged optionally. If rethrown, it shouldn’t, since another catch block will deal with it and it may result in duplicate stack traces for the same event.

    Info

    Usually found before or after (or both) specific method calls or at the beginning and/or end of the execution of a method.

    Debug/Trace

    Anywhere.

    Log information

    Log information usually contains exceptions/stack traces, messages, and parameters/attributes values. Avoid logging any sensitive information from users, like information that would allow correlating data to their identities.

    Fatal

    Log exceptions, the parameters that caused the exception or fatal condition to occur and, if any attempt was made to recover, log the attempt (with parameters) and results.

    Error

    Log exceptions, the parameters that caused the exception or condition to occur and, if any attempt was made to recover, log the attempt (with parameters) and results.

    Warn

    Log exceptions, the parameters that caused the exception or condition to occur and, if any attempt was made to recover, log the attempt (with parameters) and results. If this warning flags a possible problem, log when this should be considered a problem and/or when it shouldn’t.

    Info

    Messages that are usually unrelated to exceptions. Avoid logging stack traces using info, unless highly relevant.

    Debug/Trace

    Anything.

    Audit Logs are not Technical Logs

    I’ve seen some engineers considering using logging frameworks to implement audit log requirements. While I believe it is not fundamentally wrong, some caution is advised.

    Audit logs are a business requirement. They are to be analyzed by auditors with business knowledge, and no technical knowledge should be required. They are not expected to scavenge the information they need between lines of warnings and stack traces. Furthermore, the audit logs are subject to business requirements changes to conform to business needs. So it may be required to change templates of messages or be accessible from user interfaces (not text files).

    Suppose you consider using a logging framework to implement an audit log requirement. In that case, I’d strongly suggest you:

    • Store the logs in a database, making it easier to develop a UI for the auditors to access and query over.
    • Encapsulate the framework to ensure the usage of string templates in your messages. It will make it easier if you need to modify them later without making the change in every place where the event is being logged.
    • Considering a scenario where you may have multiple services, I’d have either a specific service to handle that or at least a shared component that encapsulates the framework and ensures consistency between logged events.
    • You may want to make use of annotations with AOP (aspect-oriented programming) to trigger the logging events in certain methods or classes without compromising too much of the code legibility.

    If you have any more suggestions around auditing logs or logging usage in general, sound off in the comments! :-)

    If you like this post, please share it (you can use the buttons in the end of this post). It will help me a lot and keep me motivated to write more. Also, subscribe to get notified of new posts when they come out.

  •  Back
  • You might also enjoy