使用 Kanzi 日志系统打印消息到您目标设备中的 日志 (Log) 窗口、Kanzi 调试控制台、标准输出和系统日志。例如,使用日志查找 Kanzi 应用程序中的问题,并通知用户您应用程序的状态。
您可以:
使用 Kanzi 日志宏打印消息到日志。绝大多数日志宏使用固定日志级别显示消息中信息的严重性。请参阅 设置日志级别。
请勿在日志宏调用中使用应用程序关键代码。如果在日志宏调用中,将应用程序关键代码用作参数,且在编译过程中禁用分配给调用中的消息的日志级别或日志类别,预处理器会移除带有应用程序关键代码的日志宏调用。
Kanzi 提供以下日志宏:
日志宏 | 描述 |
---|---|
kzLogError
|
日志错误消息,使用默认记录器 (DefaultLogger )、error (KZ_LOG_LEVEL_ERROR ) 日志级别和您作为输入参数提供的日志类别。 |
kzLogWarning
|
日志警告消息,使用默认记录器 (DefaultLogger )、warning (KZ_LOG_LEVEL_WARNING ) 日志级别和您作为输入参数提供的日志类别。 |
kzLogInfo
|
日志信息消息,使用默认记录器(DefaultLogger )、info (KZ_LOG_LEVEL_INFO ) 日志级别和您作为输入参数提供的日志类别。 |
kzLogTrace
|
日志跟踪消息,使用默认记录器 (DefaultLogger )、trace (KZ_LOG_LEVEL_TRACE ) 日志级别和您作为输入参数提供的日志类别。 |
kzLogDebug
|
日志调试消息,使用默认记录器 (DefaultLogger )、info (KZ_LOG_LEVEL_INFO ) 日志级别和日志类别 KZ_LOG_CATEGORY_DEBUG 。 |
kzLog
|
日志消息,使用自定义记录器和您作为输入参数提供的日志级别和日志类别。请参阅创建自定义记录器。 |
要打印日志消息:
//打印“这是一条调试消息。”。 kzLogDebug(("这是一条调试消息。"));打印到日志:
info:debug> This is a debug message.
//使用日志类型 MY_LOG_CATEGORY 打印“这是一条错误消息。” //使用日志类别基于日志消息相关功能对其进行分组。请参阅 使用日志类别。 kzLogError(MY_LOG_CATEGORY, ("这是一条错误消息。"));将文件路径、错误出现行数以及错误消息打印到日志:
error:My category:c:\kanziworkspace\projects\myproject\application\src\myproject.cpp:196> This is an error message.
//使用日志类别 MY_LOG_CATEGORY 打印“1 加 2 等于 3。”。请参阅 使用日志类别。 kzLogInfo(MY_LOG_CATEGORY, ("{} plus {} equals {}.", 1, 2, 1+2)); int length = 100; //打印“长度为 100。”。 kzLogInfo(MY_LOG_CATEGORY, ("The length is {}.", length));打印到日志:
info:My category> 1 plus 2 equals 3. info:My category> The length is 100.
使用日志等级来基于严重性显示日志消息。 例如,要记录应用程序执行过程中的关键问题,请使用 error
日志级别 (KZ_LOG_LEVEL_ERROR
)。
Kanzi日志系统提供以下日志级别:
日志级别 | 名称 | 严重性 | 描述 |
---|---|---|---|
KZ_LOG_LEVEL_ERROR
|
error
|
1 | 记录关键故障消息。创建详细的错误消息,让用户能够接收到足够多的问题相关信息。 |
KZ_LOG_LEVEL_WARNING
|
warning
|
2 | 记录需要引起注意但不必归为故障的事实。例如,通过警告消息,告知用户应用程序可以从中恢复的结果,例如缺失一个具有默认值的参数,或是一个可导致性能下降的事件(但不是故障)。 |
KZ_LOG_LEVEL_INFO
|
info
|
3 | 记录概览系统当前情况,通过的日志状态数量,配置相关的静态信息,以及其他内容的相关信息。 |
KZ_LOG_LEVEL_TRACE
|
trace
|
4 | 记录系统相关信息的最大数量。这是最为详细的日志级别。使用该级别可排除多种问题。 |
以下日志级别默认启用:
要设置日志级别,请使用 KZ_LOG_LEVEL_ENABLED_THRESHOLD
宏。
例如,要设置启用所有日志级别的日志级别:
#定义 KZ_LOG_LEVEL_ENABLED_THRESHOLD KZ_LOG_LEVEL_TRACE
您可以创建自己的日志级别。请参阅 KZ_LOG_CREATE_LEVEL
。
使用日志类别对包含特定功能相关信息的消息进行分组。
Kanzi 日志系统提供以下默认日志类别:
日志类别 | 描述 |
---|---|
KZ_LOG_CATEGORY_DEBUG
|
收集调试消息。 |
KZ_LOG_CATEGORY_GRAPHICS_MESH_EXTRA
|
收集图形网格日志消息。 |
KZ_LOG_CATEGORY_EGL_EXTRA
|
收集 EGL 日志消息。 |
KZ_LOG_CATEGORY_GENERIC
|
收集尚未分配任何其他日志类别的日志消息。推荐始终为每条日志消息明确分配以下其中一种日志类别,或创建新的日志类别。 |
要创建和使用日志类别,请执行以下代码:
KZ_LOG_CREATE_CATEGORY
宏创建日志类别://创建一个名为“My category”的日志类别,并将类别状态设置为启用。
//Kanzi 日志系统使用类别状态过滤日志消息。
//要禁用日志类别,请使用 KZ_LOG_DISABLED_CATEGORY
。
#定义 MY_LOG_CATEGORY KZ_LOG_CREATE_CATEGORY(KZ_LOG_ENABLED_CATEGORY, "My category")
//使用 MY_LOG_CATEGORY 日志类别打印到日志 "这是一条信息消息。” kzLogInfo(MY_LOG_CATEGORY, ("这是一条信息消息。"));
info:My category> This is an info message.
要重定向日志消息,您可以实现自定义记录器类(继承自 AbstractLogger
),并向 Kanzi 日志系统推送自定义日志。让记录器类重写 AbstractLogger::writeOverride
函数。
要使用自定义记录器重写日志消息,请使用 kzLog
宏。
如果要使用自定义记录器写入所有应用程序日志消息,请在默认记录器 (DefaultLogger
) 中注册记录器。默认记录器继承自 AbstractLogger
,包含每条日志消息通过的一长串记录器。默认情况下,这些记录器已在默认记录器中注册。
默认记录器 | 日志消息目的地 |
---|---|
CoutLogger
|
标准输出 |
AndroidLogger
|
Android 系统日志 |
Win32DebugLogger
|
Windows 系统中的 Kanzi 调试控制台 |
要实施记录器:
//使用此记录器将日志消息存储在容器中,用于日后检索。 // //该类继承自 kanzi::AbstractLogger and implements the writeOverride() 函数。在容器中存储日志。 //要检索日志,使用 get() function. class SimpleLogger : public AbstractLogger { public: //Kanzi 调用此函数将消息写入日志。 // //此函数将日志消息存储在容器中。要检索所有日志消息,使用 get() 函数。 //每条日志消息中包含: // - 消息文本 - // - 日志级别 - // - 日志类别 // - 如果某条消息为错误消息,则包括文件名和发生错误的所在行数 // // \参数等级 消息的日志等级。 // \param levelName 该字符串代表日志等级。 // \param categoryName 该字符串代表日志类别。 // \param fileName 文件名(消息内容起始点)。 // \param lineNumber 消息内容起始行。 // \param message 消息内容。 virtual void writeOverride(LogLevel level, string_view levelName, string_view categoryName, string_view fileName, size_t lineNumber, string_view message) { //日志以级别名称开始。 string logMessage(levelName); //用冒号分隔日志级别和日志类别。 logMessage += ':'; // 添加类别名称。 logMessage.append(categoryName.data(), categoryName.length()); if (level == LogLevelError) { // 已报告错误。 // 要显示错误在代码中的报告位置,添加文件名和行数到消息中。 logMessage.append(fileName.data(), fileName.length()); // 用冒号分隔文件名和行数。 logMessage += ':'; logMessage += to_string(lineNumber); } // 添加尖括号和消息文本。 logMessage += "> "; logMessage.append(message.data(), message.length()); // 将日志消息附加到日志矢量。 m_log.push_back(logMessage); } // 获得日志矢量参考。 vector<string>& getLog() { return m_log; } private: // 日志矢量。 vector<string> m_log; };
要以静态方式使用记录器,请实现以下操作:
// SimpleLogger 从 from kanzi 继承::AbstractLogger and implements writeOverride. SimpleLogger simpleLogger; //使用 SimpleLogger 编写日志消息。 kzLog(simpleLogger, KZ_LOG_LEVEL_INFO, KZ_LOG_CATEGORY_GENERIC, ("Lets log 1 + 2 = {}.", 1 + 2));
要使用记录器链中的记录器,请实现以下操作:
// SimpleLogger 从 from kanzi 继承::AbstractLogger and implements writeOverride. AbstractLoggerUniquePtr simpleLogger(new SimpleLogger()); // 将 SimpleLogger 添加到记录器链前,将指针指向它。 //将 SimpleLogger 添加到记录器链后,记录器链控制 SimpleLogger 的寿命。 SimpleLogger* simpleLoggerPtr = static_cast<SimpleLogger*>(simpleLogger.get()); // 将 SimpleLogger 推向记录器链。现在,SimpleLogger 和其他记录器都有处理每一条日志消息。 DefaultLogger::pushLogger(kanzi::move(simpleLogger)); // 编写日志消息。SimpleLogger 处理该消息。 kzLogInfo(KZ_LOG_CATEGORY_GENERIC, ("Lets log 1 + 2 = {}.", 1 + 2));
要将记录器设置为处理所有日志消息,请实现以下操作:
// SimpleLogger 从 from kanzi 继承::AbstractLogger and implements writeOverride. AbstractLoggerUniquePtr simpleLogger(new SimpleLogger()); // 将 SimpleLogger 添加到记录器链前,将指针指向它。 //将 SimpleLogger 添加到记录器链后,记录器链控制 SimpleLogger 的寿命。 SimpleLogger* simpleLoggerPtr = static_cast<SimpleLogger*>(simpleLogger.get()); // 移除记录器中所有默认记录器。 //这样,只有 SimpleLogger(稍后推送给链)处理日志消息。 DefaultLogger::popAllLoggers(); // 向记录器链推送 SimpleLogger。现在,只有 SimpleLogger 处理每一条日志消息。 DefaultLogger::pushLogger(kanzi::move(simpleLogger)); // 编写日志消息。SimpleLogger 处理该消息。 kzLogInfo(KZ_LOG_CATEGORY_GENERIC, ("Lets log 1 + 2 = {}.", 1 + 2));