Методы Init(), Log() и макрос LOG
Метод logrr::Init() инициализирует клиентскую часть компонента LogRR. Метод принимает идентификатор провайдера журналов. Если явно не вызвать метод logrr::Init(), то инициализация будет выполнена при первом вызове макроса LOG, а в качестве идентификатора провайдера будет установлено имя программы, вызвавшей макрос.
Метод logrr::Log() выполняет запись в журнал.
Параметры метода:
logLevelУровень журналирования
LogLevel.sourceLocationОбъект, определяющий местоположение в исходном коде (имя файла, имя функции, номер строки и номер столбца). В C++20 используется класс
std::source_location, в более ранних версиях используется классstd::experimental::source_location.formatСтрока форматирования текста сообщения.
argsПараметры для подстановки в строку форматирования
format.
Метод logrr::Log() предназначен для использования в программах на языке C++. В программах на языке C используйте статическую функцию ClogLog() или макрос CLOG.
Описание методов logrr::Init() и logrr::Log() и макроса быстрого доступа к методу для журналирования представлены в файле /opt/KasperskyOS-Community-Edition-<platform>-<version>/sysroot-*-kos/include/component/logrr/cpp/logger.h.
component/logrr/cpp/logger.h (фрагмент)
namespace logrr {
__rtl_public
void Init(const char* providerName = nullptr) noexcept;
__rtl_public
bool ShouldLog(logrr::LogLevel logLevel, logrr::SubProviderId id, std::string_view filename = std::string_view{}) noexcept;
__rtl_public
void RegisterSubProvider(std::string_view name, logrr::SubProviderId* id) noexcept;
__rtl_public
void LogWithClog(
logrr::SubProviderId subProviderId,
LogLevel logLevel,
std::string_view file,
const uint32_t line,
std::string_view function,
std::string_view msg) noexcept;
namespace details {
__rtl_public
void PrintErrorMessage(std::string_view fileName, std::uint32_t line, std::string_view exMsg) noexcept;
__rtl_public
void PrintWarnMessage(std::string_view fileName, std::uint32_t line, std::string_view exMsg) noexcept;
template <bool IsSecure, typename... Args>
__rtl_public
void LogImpl(
logrr::SubProviderId subProviderId,
logrr::LogLevel logLevel,
std::string_view file,
const uint32_t line,
std::string_view function,
fmt::format_string<Args...> format,
Args&&... args)
{
constexpr std::size_t MaxLength{LOGRR_LOG_MESSAGE_MAX_SIZE - 1};
if constexpr (sizeof...(Args) == 0)
{
std::string_view msg(format.get().data(), format.get().size());
LogWithClog(subProviderId, logLevel, file, line, function, msg);
}
else
{
constexpr std::size_t BufInitialSize{2 * LOGRR_LOG_FRAGMENT_MAX_SIZE};
std::string buf;
buf.reserve(BufInitialSize);
auto result = fmt::vformat_to_n(
std::back_inserter(buf),
MaxLength,
format,
fmt::make_format_args(args...));
if (result.size > MaxLength)
{
details::PrintWarnMessage(file, line,
fmt::format("Log message was truncated to {} bytes", MaxLength));
}
buf.push_back('\0');
if constexpr (IsSecure)
{
SecretMaskingContext::GetMasker()->ApplyMasking(buf);
}
std::string_view formattedStr{buf.data(), buf.size()};
LogWithClog(subProviderId, logLevel, file, line, function, formattedStr);
}
}
} // namespace details
template <typename SourceLocationType, typename... Args>
__rtl_public
void Log(
logrr::SubProviderId subProviderId,
logrr::LogLevel logLevel,
SourceLocationType sourceLocation,
fmt::format_string<Args...> format,
Args&&... args) noexcept
{
Log(subProviderId, logLevel, sourceLocation.file_name(), sourceLocation.line(),
sourceLocation.function_name(), format, std::forward<Args>(args)...);
}
template <typename... Args>
__rtl_public
void Log(
logrr::SubProviderId subProviderId,
logrr::LogLevel logLevel,
std::string_view file,
const uint32_t line,
std::string_view function,
fmt::format_string<Args...> format,
Args&&... args) noexcept
try
{
details::LogImpl<false>(
subProviderId, logLevel, file, line, function,
format, std::forward<Args>(args)...);
}
catch (const std::exception& e)
{
details::PrintErrorMessage(file, line, e.what());
}
} // namespace logrr
#define __CPPLOG_LEVEL_TRACE__ logrr::LogLevel::Trace
#define __CPPLOG_LEVEL_DEBUG__ logrr::LogLevel::Debug
#define __CPPLOG_LEVEL_INFO__ logrr::LogLevel::Info
#define __CPPLOG_LEVEL_WARNING__ logrr::LogLevel::Warning
#define __CPPLOG_LEVEL_ERROR__ logrr::LogLevel::Error
#define __CPPLOG_LEVEL_CRITICAL__ logrr::LogLevel::Critical
#define CALL_LOG_SL(level, file, line, func, ...) \
do { \
if (::logrr::ShouldLog(level, *LogrrSubProviderId, file)) \
::logrr::Log(*LogrrSubProviderId, level, file, line, func, __VA_ARGS__); \
} while (0)
#define CALL_LOG(level, ...) \
do { \
const auto sl = logrr::SourceLocation::current(); \
CALL_LOG_SL(level, sl.file_name(), sl.line(), sl.function_name(), __VA_ARGS__); \
} while (0)
#define LOG(level, ...) CALL_LOG(__CPPLOG_LEVEL_ ## level ## __, __VA_ARGS__)
#define LOG_SL(level, file, line, func, ...) CALL_LOG_SL(__CPPLOG_LEVEL_ ## level ## __, file, line, func, __VA_ARGS__)
Макрос быстрого доступа к методу Log()
Вместо вызова статического метода Logger::Log() вы можете использовать макрос, описание которого представлено в файле component/logrr/cpp/logger.h. Этот макрос является вариационным (принимает переменное число параметров), что позволяет не указывать все параметры метода Logger::Log(). При вызове макроса достаточно указать только уровень журналирования и строку форматирования сообщения со значениями параметров. Используемый уровень журналирования logLevel определяется первым параметром макроса: Пример использования этого макросов представлен в разделе "Отправка сообщений в журнал с помощью макросов".