TICS Coding Standard Viewer 
TIOBE Software Quality Framework
Print-friendly version
©TIOBE Software www.tiobe.com
 
C++ Coding Standard
Search

Rule:  TT#003

This rule is Obsolete
Synopsis:Logging shall be be performed according to a common standard.
Language:C++
Severity Level:10
Category:TomTom Guidelines


Description:

TTLog

TTLog is NavKit's configurable logging mechanism. It is enabled by default in debug builds and release builds.

Because TTLog is enabled in release builds, all messages will be part of NavKit library. This means that even debug messages should contain professional, proper English as it is to be expected that they will be read by external parties.

There are two aspects to TTLog: instrumentation of the source code to include logging messages, and configuring what is to be logged during any specific run.

Details of how to instrument your code to include logging are given here.

Details of the configuration file are given in Configuration file.

Instrumenting code for logging

First you have to define a logger, which is done in the cpp file that contains the module that is to be instrumented. This is done with help of the following macro, which is available in ./Framework/Common/Logging/Interface/TTLog.h:

DEFINE_LOGGER(variableName, logId)
  • variableName is the global variable that contains the logging class for this module,
  • logId (const char*) is a unique string that is used to identify this module (see Module names). logId is used to identify the module both in the output file and in the configuration file.

The next step is to instrument your code with logging statements. This can be done by using the following macro:

LOG_LV(variableName, level, format, ...)
  • variableName is the same variable as used in the DEFINE_LOGGER macro,
  • level is the level of this log message (see [Logging levels#logginglevels]),
  • format is the printf-like format string for the message,
  • ... represents the message's arguments (which should match format).

A set of macros makes it simple to log directly at the correct level. These are:

LOG(variableName, format, ...)
LOG_INFO(variableName, format, ...)
LOG_NOTICE(variableName, format, ...)
LOG_WARNING(variableName, format, ...)
LOG_ERROR(variableName, format, ...)
LOG_CRITICAL(variableName, format, ...)

LOG() logs at the lowest level and the other macros correspond to other predefined severity levels

If your module is spread over multiple cpp files, you can use the following macro to declare a logger that is defined in another cpp file:

DECLARE_LOGGER(variableName)

+ variableName is the same as is used in the DEFINE_LOGGER macro.

DECLARE_LOGGER can also be used when you want to log in a module's header file. This should only be done in exceptional cases.

Initializing logging

The overall logging system has to be initialized before it can be used (see also Logging before initialization). For NavKit this is done in NavKitMain. If you have other executables with which you want to use TTLog you have to initialize the logging system with the following statements:

TPathList paths;
paths.push_back("<directory>"); // <directory> points to directory where TTLog configuration file is stored
Logger::GetInstance().Initialize(paths);

NOTE: The LOGT and LOGT_LV macros are deprecated and should no longer be used.

Logging before initialization

If the logger is not yet initialized, that is, the call to Initialize has not been done, logging will be performed as if there were no configuration file.

This means that even if logging is disabled completely, there can still be some logging to the console in the event that the logger is used before initialization. This logging will stop as soon as Initialize is executed, assuming the configuration file disables logging.

Logging levels

Each message is assigned a level: the smaller the number the more severe the event being reported. These values can be used with the loglevel attribute to set the level of logging.

Where a message indicates an error, it should almost always end up in a log file unless logging is disabled for the module. If a message is a debug message for a certain module, probably only the team that maintains that module is interested in that message and therefore it severity should be much lower.

The following severity levels are defined:

Severity level Constant Value Description Example
NOT SET DEBUG_LVL0 0 Do not log. This value will be used very rarely, but it can be used in code when a message has to be disabled completely.
CRITICAL DEBUG_LVL1 1 Use for errors that are not recoverable (NavKit will enter an unusable state and manual intervention will be required). Operating system signals that the file system with the map is unavailable.
ERROR DEBUG_LVL2 10 Something went wrong but is not critical (NavKit can still be used even if the current use case will probably fail). The client requests instructions for route 13 but this route is not available in the system.
WARNING DEBUG_LVL3 20 Something 'suspicious' has been observed which may be ok but it may also be a sign that the system is in an unhealthy state. The client requests planning a route from the current position but we don't have a current GPS position.
NOTICE DEBUG_LVL4 30 Something 'remarkable' has been observed which is important for understanding the current state of the system. A new map is loaded.
INFO DEBUG_LVL5 40 Provide information about what NavKit is currently doing. This log level should be used to show when some major computation is started or a client request is received and processing starts. The purpose is to provide some context for error logs and to make analysis of problems easier. The volume of messages with this level should still be small enough to permit enabling it in production. A new route planning request has been received.
DEBUG DEBUG_LVL6 100 Debugging information that is only switched on during development and only for selected components where an error is under investigation. The newly re-timed ETA value is now 10:31:40.


Literature References:
TomTom Guidelines