Skip to content

Appendix B - Application Logging

Application Log Format

A log collector called Fluent Bit is used to process text logs within the HCC2. It expects logs in a particular format to be processed fully.

An application running on the HCC2 must log the log message in the following format:

[version][YYYY-MM-DDThh:mm:ss.sssZ][loggerName][logLevel]log message

Example:

[0][2024-02-14T19:43:00.999Z][SR_CSAPP][error]Failed to connect to Modbus Server 127.0.0.1:502

Where:

  • [version]: Version number for the log format. This format is version 0.

  • [YYYY-MM-DDThh:mm:ss.sssZ]: The timestamp that specifies when the log message is generated. It is in UTC time, not local time.

    Info

    To see the message in local time for easy debugging, add a compile-time switch to use a separate implementation of the logger functionality.

  • [loggerName]: Free text to identify your application or application sub function. It can be the module / application name, e.g., configurationManager or RPC, or a functionality name within a single application. E.g., to log a message for a file access failure, you can use this section to differentiate it from an error generated within the same application. E.g., initConfig, initConnection, runtimeCommsCallbackup, diagsPollTime...

    Warning

    Sensia strongly recommends keeping the logger names short (12 characters maximum) to minimize risk for formatting issues, and using camel case.

  • [logLevel]: Valid levels (in words) are

    • critical: The application cannot perform and requires user intervention. For example, memory allocation or port binding failed.
    • error: The application may not work correctly or might produce the wrong result. For example, continuous Modbus timeouts resulting in the connection being closed.
    • warning: The application can perform properly but it may require user attention to avoid future errors or damage. E.g., disk 80% full.
    • info: Informative message. Normally, the info level is disabled in the system. When enabled, it provides information about the application's working state and status. For example, the web server is working on port 3000, or the application is in auto mode.
    • debug: Debugging information that can be used in the field. Using debug mode, the field engineer can gain insight into the system and correct errors.
    • trace: The lowest log level. Trace should be used only by developers when working on the application. It can be used in place of printf or the console log and should not be left in production code.
  • log message: Concise, appropriate text to include any pertinent values that warranted a message

Rules for Logging

DO

  • Make sure each log is self-contained and informative.
  • Use the lowest appropriate log level.
  • Consider using a less severe log level if something can happen often such as timeouts.
  • In the event of a repeated timeout leading to a “failed” state and a single warning or error, consider a programmatic mechanism to transition the application back into a retry state.
  • Log its version upon startup, and if it started up successfully as a warning.
  • Set the application's log level via an environment variable called LOGLEVEL at startup using the levels defined above (in lowercase), i.e., LOGLEVEL=info. Use the value in the application.
  • Strive to have the application output a total of 3 logs during their lifecycle higher than info when working normally:
    • Startup & version, Configuration success, Shutdown.
  • Adhere to the above defined format. Every new line shall contain one complete, self contained log in the above format.

DO NOT

  • Output separators, headers, or other attempts to grab attention or delineate logs:
    • Logs are parsed/interpreted line by line. These multi-line outputs appear as garbage/clutter for the user.
    • If output separators or headers are of great value to you, they can be enabled through a compile option or environment variable, but must be off by default.
  • Output the entirety of your configuration as info logs.
    • If you must output your configuration as a log, use a debug or trace log level.
    • It is acceptable to output unexpected failures to parse as info or as a warning.
  • Output unexpected but ‘normal’ behavior as a warning. This should be output as info or debug log levels. For example, a Modbus client experiencing a timeout. There are other mechanisms for conveying this info to the user, such as diagnostic data points.
  • Output logs that depend on the previous log for context.
    • Refer to “self contained and informative” rule. For example, “attempting to connect to server” followed by “ok”.
  • Override log level rules set via the environment variable. If a log is deemed “info,” do not output it when the log level is set higher than "info".
    • It may seem logical to set a log level based on the type of content it provides; however, it is important to consider other factors. Log levels exist to ensure users receive the information they need and at the time they need it. If a user absolutely needs to see a log under normal conditions, even if it is ‘informative’, set it as a warning, not a ‘special info'. For example, set the startup message/version as a warning.
  • Generate logs continuously at the info level or higher when operating normally:
    • Info will be seen by end users and is intended to convey useful information.
    • Use debug for things that happen occasionally but do repeat.
    • Use trace for things that happen continuously.