Contents
LogRR component
The LogRR
component provides a system for logging information about program operation. The component includes a server program to which other programs forward messages about their state, and auxiliary output channels used for logging. Messages are sent to the server by using the logrr_clog
library (the logrr_cpp
library is available for C++), which filters messages according to the log level and sends them to the server. The server relays messages to output channels. An output channel saves log messages to files.
In the SDK, the LogRR program APIs are represented by static and dynamic libraries linked to the programs whose operating information is logged:
- The
logrr_clog
library and the header filesysroot-*-kos/include/component/logrr/clog/clog.h
are used in C-language programs. - The
logrr_cpp
library and the header filesysroot-*-kos/include/component/logrr/cpp/logger.h
are used in C++ programs.
Adding a log server and output channels to a solution
The LogrrServer
program sends messages to one or more output channels. You can write log messages to files by using the output channel named FsOutputChannel
.
Adding and configuring logging server
The command for creating and configuring the log server create_logrr_server()
may contain the following parameters:
LOG_LEVEL
- Sets the specified log level. The available values for
LOG_LEVEL
areCRITICAL
,ERROR
,WARNING
,INFO
,DEBUG
andTRACE
. By default, the log server handles messages with the Info level. CONFIG_PATH
- Specifies the path to the configuration file of the log server.
RECV_CORE_LOGS
- Enables collection of kernel logs.
WRITE_TO_CORE
- Enables forwarding of logs to the kernel. Does not exclude forwarding of logs to the log server or further to the output channel. Required for printing logs to UART.
OUTPUT_CHANNELS
- Connects one or more specified output channels to the server.
DENY_DYNAMIC_CONN_TYPES
- Enables rejection of dynamic connections to the log server.
DENY_STATIC_CONN_TYPES
- Enables rejection of static connections to the log server.
To add the LogrrServer
program to a solution:
Edit the root file containing the CMake commands for building the solution or the file containing the CMake commands for building the Einit
initializing program:
CMakeLists.txt
The PACK_DEPS
option must be included when calling the build_kos_qemu_image()
or build_kos_hw_image()
command to include an automatic build of the libraries in the disk image.
Adding and configuring output channels
The command for creating and configuring the channel for printing logs to files create_logrr_fs_output_channel()
may contain the following parameters:
CONFIG_PATH
- Specifies the path to the configuration file of the output channel.
SERVER_TARGET
- Specifies the log server to which the created output channel must connect.
APP_LOG_DIR
- Specifies the directory for storing log files for programs. Required parameter.
SYS_LOG_DIR
- Specifies the directory for storing system log files. If this parameter is not defined, system log files are not saved.
To add the FsOutputChannel
to a solution:
Edit the root file containing the CMake commands for building the solution or the file containing the CMake commands for building the Einit
initializing program:
CMakeLists.txt
Creating IPC channels and allowing interaction between programs
The build system automatically creates IPC channels required for the log system to work, and generates a security policy description that allows interaction between processes.
To create a static connection to the log server, you can use the CMake command connect_to_logrr_server (ENTITIES <names_of_programs_to_connect>)
.
Getting log entries when running in QEMU
The client libraries logrr_clog
and logrr_cpp
send messages to the kernel, which forwards them to the UART port. You can forward data from an emulated UART port to a standard I/O stream by specifying the -serial stdio
flag when starting QEMU. In this case, log messages will be displayed in the terminal in which QEMU is running.
Specify the QEMU startup flags in the value of the QEMU_FLAGS parameter that is passed to the build_kos_qemu_image() command:
CMakeLists.txt
Using macros to send messages to a log
The LogRR
program provides macros for quickly accessing logging functions with a specific log level.
Example use of macros in a C-language program:
C
To use these macros, you need to link the program to the logrr_clog library.
Example use of macros in a C++ program:
C++
To use these macros, you need to link the program to the logrr_cpp library.
Advanced capabilities when sending messages to a log
In most cases, you can send messages to the log by simply using macros for quick access to logging functions.
This section describes the additional capabilities of the logrr_cpp
library API: merging messages, condition-based message forwarding, and deferred forwarding of messages.
Merging messages
To incrementally build the text of a log entry from parts and then send the entry to the log with one call:
- Link the program to the logrr_cpp library.
- Include the header file
component/logrr/cpp/tools.h
.C++
- Create an instance of the
LogIface
class.C++
auto logger = LogIface(logrr::LogLevel::Warning); - Fill the message buffer with one or more calls of the
LogIface::Push()
method.C++
logger.Push("a={}", a); // ... logger.Push(", b={}", b); // ... logger.Push(", c={}", c); - Send the previously received messages to the log by using the
LogIface::Flush()
method.C++
logger.Flush();
Sending a message to the log based on a condition
To send a message to the log only when a specified condition is fulfilled:
- Link the program to the logrr_cpp library.
- Include the header file
component/logrr/cpp/tools.h
.C++
- Pass the logical value, one of the
LogLevel
enumerators, and the message text to theLOG_IF()
macro.C++
LOG_IF(IsWorldBroken(), logrr::LogLevel::Critical, "World is broken!");
Deferred forwarding of messages to the log
The LOG_DEFER()
macro declared in the header file component/logrr/cpp/tools.h
lets you avoid duplicating code for logging in the if
...else
blocks.
To send a pre-formatted message to the log when exiting a function:
- Link the program to the logrr_cpp library.
- Include the header file
component/logrr/cpp/tools.h
.C++
- Add a
LOG_DEFER()
macro call to the beginning of the code for the function that changes the values that need to be sent to the log. Pass theLogLevel
value, message formatting string and arguments to be inserted in the formatting string to the macro.C++
int DeferredLoggingExample() { auto logger = LOG_DEFER(logrr::LogLevel::Info, "a={}, b={}", a, b); if (someCondition) { a = 1; b = 2; return -1; } else { a = 3; b = 4; return 0; } }
In this example, a message is sent to the log when the logger
object's destructor is called on exit from the DeferredLoggingExample()
function. The values a
and b
at the time of exit from the function are inserted into the message formatting string.
Log levels
A log level is an attribute of each message in the logging system. The log level is configured through the server and is used when filtering messages in a client.
- Critical
- Critical malfunction in program operation that makes it impossible for the program to continue working.
- Error
- Program operating error that does not completely prevent the program from continuing to work. This level is applied for logging an unexpected termination of the current operation. It is not recommended to apply this level for logging erroneous user actions.
- Warning
- Problem situation that is anticipated and normally handled by the program.
- Info (default)
- Information about the current functional performance of the program without additional details. For example, this info can include switching to a new window in the user interface or successfully writing an entry in the database.
- Debug
- More detailed log level than Info. It provides more details on program events and may be useful for debugging.
- Trace
- The most detailed log level that is used for the most detailed tracking of program events. When this level is enabled, it can have a substantial impact on performance.
Each successive level includes all previous levels. For example, if a server is configured for the Warning level, it forwards messages with the Critical, Error and Warning levels to the log while ignoring messages with the Info, Debug and Trace levels.
The log level when the program sends a message can be defined by doing the following:
- Using the macro with the parameter corresponding to the selected level.
- Passing the value of the
LogrrLogLevel
orLogLevel
enumerator when logging functions are called.
LogRR program API
The libraries of the LogRR
program provide APIs for sending messages to the log through the log server and APIs for managing the log server.
logrr_clog library
The logrr_clog
library provides the API for sending messages to the log.
The logrr_clog
library is intended for use in C-language programs. Use the logrr_cpp
library in C++ programs.
To get access to the API of this library:
Link your program to the library by using the target_link_libraries()
CMake command.
CMakeLists.txt
ClogLog() function and CLOG macro
The ClogLog()
function writes to the log.
The ClogLog()
function is intended for use in C-language programs. In C++ programs, use the Logger::Log() function or LOG_* macros.
A description of the ClogLog()
function and macros for quick access to it are provided in the file /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/clog/clog.h
.
component/logrr/clog/clog.h (fragment)
Parameters of the ClogLog()
function:
level
- Log level
LogrrLogLevel
. file
- File name.
line
- Number of the line in the file.
func
- Function name.
message
- Message text or message text formatting string.
...
- Parameters to be inserted into the
message
formatting string.
Macro for quick access to the ClogLog() function
Instead of calling the ClogLog()
function, you can use the macro whose description is provided in the file component/logrr/clog/clog.h
. This macros is variadic (takes a variable number of parameters), which lets you avoid specifying all parameters of the ClogLog()
function. When calling this macro, you only need to specify the log level and message text or the message formatting string with the values of parameters. The applied log level
is determined by the first parameter of the macro. An example of using this macro is provided in the section titled Using macros to send messages to a log.
LogrrLogLevel enumerated type
The enumerated type LogrrLogLevel
contains fields whose names correspond to the log levels available in the LogRR
program.
The enumerated type LogrrLogLevel
is intended for use in C-language programs. In C++ programs, use the LogLevel
class.
LogrrLogLevel
enumerators can be passed to the ClogLog()
function to send a message with the specified log level.
A description of LogrrLogLevel
enumeration is provided in the file /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/core/log_level_c.h
.
component/logrr/core/log_level_c.h (fragment)
The logrr_cpp library
The logrr_cpp
library provides the API for sending messages to the log.
The logrr_cpp
library is intended for use in C++ programs. In C-language programs, use the logrr_clog
library.
To get access to the API of this library:
Link your program to the library by using the target_link_libraries()
CMake command.
CMakeLists.txt
Log() method and LOG macro
The logrr::Log()
method writes to the log.
Method parameters:
logLevel
- Log level
LogLevel
. sourceLocation
- Object that determines the location in the source code (file name, function name, line number and column number). The
std::source_location
class is used in C++20, while thestd::experimental::source_location
class is used in earlier versions. format
- Message text formatting string.
args
- Parameters to be inserted into the
format
formatting string.
The logrr::Log()
method is intended for use in C++ programs. In C-language programs, use the static function ClogLog() or CLOG macro.
A description of the logrr::Log()
method and macros for quick access to it are provided in the file /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/cpp/logger.h
.
component/logrr/cpp/logger.h (fragment)
A macro for quick access to the Log() method
Instead of calling the static method Logger::Log()
, you can use the macro whose description is provided in the file component/logrr/cpp/logger.h
. This macro is variadic (takes a variable number of parameters), which lets you avoid specifying all parameters of the Logger::Log()
method. When calling this macro, you only need to specify the log level and message formatting string with the values of parameters. The applied log level logLevel
is determined by the first parameter of the macro: An example of using these macros is provided in the section titled Using macros to send messages to a log.
LogLevel class
The LogLevel
class is an enumeration (enum class
) and contains fields whose names correspond to the log levels available in the LogRR
program.
The LogLevel
class is intended for use in C++ programs. In C-language programs, use the enumerated type LogrrLogLevel
.
Values of LogLevel
enumeration can be passed to the following:
- Static method
Log()
of theLogger
class - Static methods
ChangeLogLevel()
andChangeGlobalLogLevel()
of theController
structure LogIface
class constructor
A description of the LogLevel
class is provided in the file /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/core/log_level.h
.
component/logrr/core/log_level.h (fragment)
LogIface class
The LogIface
class contains methods that let you incrementally build the text of a log entry from parts and then send the entry to the log with one call:
- The
SetLogLevel()
method is used to set the log level of sent messages. - The
Push()
method is used to add text to a message. - The
Flush()
method is used to send a message composed of one or morePush()
method calls to the log.When the
~LogIface()
destructor is called, the message composed ofPush()
calls is also sent to the log if the message was not previously sent usingFlush()
. - The
Log()
method is used to immediately send a separate message (without using the text composed ofPush()
calls).
To create a LogIface
class instance, pass one of the LogLevel
enumerators to the class constructor. An example of using functions of the LogIface
class is provided in the "Merging messages" subsection under Advanced capabilities when sending messages to a log.
A description of the LogIface
class is provided in the file /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/component/logrr/cpp/tools.h
.
component/logrr/cpp/tools.h (fragment)