forked from espressif/esp-idf
docs: Update translation
This commit is contained in:
@@ -68,7 +68,7 @@ Log level settings control which logs are included in the binary and their visib
|
||||
|
||||
Example for the application: if the **log level** is set to **Warning** and the **maximum log level** is set to **Debug**, the binary will include log messages of levels **Error**, **Warning**, **Info**, and **Debug**. However, at runtime, only log messages of levels **Error** and **Warning** will be outputted unless the log level is explicitly changed using :cpp:func:`esp_log_level_set`. The log level can be adjusted, increased or decreased, depending on the user's needs.
|
||||
|
||||
**Maximum Log Level** Setting
|
||||
``Maximum Log Level`` Setting
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``LOG_LOCAL_LEVEL`` definition allows you to override the **maximum log level** for a specific source file or component without modifying the Kconfig options. It effectively sets the **maximum log level** locally, enabling or excluding specific logs in the binary.
|
||||
@@ -105,13 +105,13 @@ Example: Set the log level to ``ERROR`` for all components (global setting):
|
||||
|
||||
Adjusting log output per module (tag) depends on :ref:`CONFIG_LOG_TAG_LEVEL_IMPL`, which is enabled by default. If this feature is not required, you can disable it to reduce code size and improve performance:
|
||||
|
||||
Example: Set the log level to ``WARNING`` only for the Wi-Fi component (module-specific setting).
|
||||
Example: Set the log level to ``WARNING`` only for the Wi-Fi component (module-specific setting):
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
esp_log_level_set("wifi", ESP_LOG_WARN);
|
||||
|
||||
Using Logging Library
|
||||
Use Logging Library
|
||||
---------------------
|
||||
|
||||
In each C file that uses the logging functionality, define the ``TAG`` variable.
|
||||
@@ -203,7 +203,7 @@ The logging system supports the following formatting options, applicable for bot
|
||||
- **System time (HH:MM:SS.sss)** `(14:31:18.532)`: Displays time in hours, minutes, seconds, and milliseconds.
|
||||
- **System time (YY-MM-DD HH:MM:SS.sss)** `(2023-08-15 14:31:18.532)`: Similar to the above, but also includes the date.
|
||||
- **Unix time in milliseconds** `(1692099078532)`: Displays Unix time in milliseconds.
|
||||
- For **Log V2**, the :ref:`CONFIG_LOG_TIMESTAMP_SUPPORT` option enables runtime support for adding timestamp output to specific logs, files, or components, even if global timestamp is disabled. To enable the **Milliseconds since boot** timestamp for a specific context use ``ESP_LOG_TIMESTAMP_DISABLED``.
|
||||
- For **Log V2**, the :ref:`CONFIG_LOG_TIMESTAMP_SUPPORT` option enables runtime support for adding timestamp output to specific logs, files, or components, even if global timestamp is disabled. To enable the **Milliseconds since boot** timestamp for a specific context, use ``ESP_LOG_TIMESTAMP_DISABLED``.
|
||||
|
||||
- **Tag**: Displays a user-defined identifier for the source module.
|
||||
|
||||
@@ -292,9 +292,9 @@ There are three settings that control the ability to change the log level at run
|
||||
|
||||
- Reducing memory consumption:
|
||||
|
||||
- **IRAM**: ~260 bytes
|
||||
- **DRAM**: ~264 bytes
|
||||
- **Flash**: ~1 KB
|
||||
- **IRAM**: about 260 bytes
|
||||
- **DRAM**: about 264 bytes
|
||||
- **Flash**: about 1 KB
|
||||
|
||||
- Boosting log operation performance by up to 10 times.
|
||||
|
||||
@@ -302,7 +302,7 @@ There are three settings that control the ability to change the log level at run
|
||||
|
||||
- **None**: Disables per-tag log level checks entirely, reducing overhead but removing runtime flexibility.
|
||||
|
||||
- **Linked List**: Enables per-tag log level settings using a linked list-only implementation (no cache). This method searches through all tags in the linked list to determine the log level, which may result in slower lookups for a large number of tags but consumes less memory compared to the **cache** approach. The linked list approach performs full string comparisons of log tags to identify the appropriate log level. Unlike **Cache**, it does not rely on tag pointer comparisons, making it suitable for dynamic tag definitions. Select this option if you prioritize memory savings, need to enable or disable logs for specific modules, or want to use tags defined as variables. Selecting this option automatically enables **Dynamic Log Level Control**. The linked list entries are allocated on the heap during the execution of ``ESP_LOGx`` macros when a new tag is encountered.
|
||||
- **Linked List**: Enables per-tag log level settings using a linked list-only implementation (no cache). This method searches through all tags in the linked list to determine the log level, which may result in slower lookups for a large number of tags but consumes less memory compared to the **Cache** approach. The linked list approach performs full string comparisons of log tags to identify the appropriate log level. Unlike **Cache**, it does not rely on tag pointer comparisons, making it suitable for dynamic tag definitions. Select this option if you prioritize memory savings, need to enable or disable logs for specific modules, or want to use tags defined as variables. Selecting this option automatically enables **Dynamic Log Level Control**. The linked list entries are allocated on the heap during the execution of ``ESP_LOGx`` macros when a new tag is encountered.
|
||||
|
||||
- **Cache + Linked List** (Default): It is a hybrid mode that combines caching with a **linked list** for log tag level checks. This hybrid approach offers a balance between speed and memory usage. The cache stores recently accessed log tags and their corresponding log levels, providing faster lookups for frequently used tags. The cache approach compares the tag pointers, which is faster than performing full string comparisons. For less frequently used tags, the **linked list** is utilized to search for the log level. This option may not work properly when dynamic tag definitions are used, as it relies on tag pointer comparisons in the cache, which are not suitable for dynamically defined tags. This hybrid approach improves the efficiency of log level retrieval by leveraging the speed of caching for common tags and the memory efficiency of a linked list for less frequently used tags. Selecting this option automatically enables **Dynamic Log Level Control**.
|
||||
|
||||
@@ -402,6 +402,7 @@ The logging system provides macros for logging buffer data. These macros can be
|
||||
|
||||
The number of lines in the output depends on the size of the buffer.
|
||||
|
||||
|
||||
Performance and Measurements
|
||||
----------------------------
|
||||
|
||||
@@ -409,60 +410,96 @@ When logging is used in a task, the task stack must be configured with at least
|
||||
|
||||
The following measurements were performed using tests inside the log component with default settings (the maximum and default log levels were set to INFO, color support was disabled, without master log and timestamps were enabled) across different chips:
|
||||
|
||||
- ``Performance measurements for log APIs``.
|
||||
- ``Stack usage for log APIs``.
|
||||
- Performance measurements for log APIs
|
||||
- Stack usage for log APIs
|
||||
|
||||
``esp_rom_printf`` and ``esp_rom_vprintf`` produce similar results. Similarly, ``vprintf`` and ``printf`` yield comparable outcomes. Hence, only one of each pair is included in the tables below.
|
||||
|
||||
**Stack Usage (bytes):**
|
||||
.. list-table:: Stack Usage (bytes)
|
||||
:header-rows: 1
|
||||
|
||||
+-------------------+-------+---------+---------+
|
||||
| Function | ESP32 | ESP32C2 | ESP32C3 |
|
||||
+===================+=======+=========+=========+
|
||||
| esp_rom_printf | 128 | 192 | 192 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V1 | 128 | 192 | 192 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V2 | 336 | 324 | 324 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V1 | 128 | 192 | 192 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V2 | 336 | 324 | 324 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| vprintf | 1168 | 384 | 1344 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V1 | 1184 | 384 | 1344 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V2 | 1152 | 592 | 1504 |
|
||||
+-------------------+-------+---------+---------+
|
||||
* - Function
|
||||
- ESP32
|
||||
- ESP32C2
|
||||
- ESP32C3
|
||||
* - esp_rom_printf
|
||||
- 128
|
||||
- 192
|
||||
- 192
|
||||
* - ESP_EARLY_LOGI V1
|
||||
- 128
|
||||
- 192
|
||||
- 192
|
||||
* - ESP_EARLY_LOGI V2
|
||||
- 336
|
||||
- 324
|
||||
- 324
|
||||
* - ESP_DRAM_LOGI V1
|
||||
- 128
|
||||
- 192
|
||||
- 192
|
||||
* - ESP_DRAM_LOGI V2
|
||||
- 336
|
||||
- 324
|
||||
- 324
|
||||
* - vprintf
|
||||
- 1168
|
||||
- 384
|
||||
- 1344
|
||||
* - ESP_LOGI V1
|
||||
- 1184
|
||||
- 384
|
||||
- 1344
|
||||
* - ESP_LOGI V2
|
||||
- 1152
|
||||
- 592
|
||||
- 1504
|
||||
|
||||
The stack usage differences between **Log V1** and **Log V2** are negligible.
|
||||
|
||||
**Performance (without output in microseconds):**
|
||||
.. list-table:: Performance (without output in microseconds)
|
||||
:header-rows: 1
|
||||
|
||||
+-------------------+-------+---------+---------+
|
||||
| Function | ESP32 | ESP32C2 | ESP32C3 |
|
||||
+===================+=======+=========+=========+
|
||||
| esp_rom_printf | 1 | 2 | 1 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V1 | 15 | 24 | 14 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V2 | 28 | 36 | 25 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V1 | 6 | 9 | 5 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V2 | 19 | 22 | 14 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| vprintf | 15 | 9 | 7 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V1 | 27 | 16 | 12 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V2 | 77 | 54 | 40 |
|
||||
+-------------------+-------+---------+---------+
|
||||
* - Function
|
||||
- ESP32
|
||||
- ESP32C2
|
||||
- ESP32C3
|
||||
* - esp_rom_printf
|
||||
- 1
|
||||
- 2
|
||||
- 1
|
||||
* - ESP_EARLY_LOGI V1
|
||||
- 15
|
||||
- 24
|
||||
- 14
|
||||
* - ESP_EARLY_LOGI V2
|
||||
- 28
|
||||
- 36
|
||||
- 25
|
||||
* - ESP_DRAM_LOGI V1
|
||||
- 6
|
||||
- 9
|
||||
- 5
|
||||
* - ESP_DRAM_LOGI V2
|
||||
- 19
|
||||
- 22
|
||||
- 14
|
||||
* - vprintf
|
||||
- 15
|
||||
- 9
|
||||
- 7
|
||||
* - ESP_LOGI V1
|
||||
- 27
|
||||
- 16
|
||||
- 12
|
||||
* - ESP_LOGI V2
|
||||
- 77
|
||||
- 54
|
||||
- 40
|
||||
|
||||
If logging to UART is measured, the performance numbers for **Log V1** and **Log V2** are nearly identical. The slight differences in processing overhead introduced by **Log V2** become negligible compared to the time it takes to send logs over UART. Thus, in most practical use cases, the performance impact of switching to **Log V2** will be unnoticeable.
|
||||
|
||||
**Memory Usage (bytes):**
|
||||
**Memory Usage (bytes)**
|
||||
|
||||
The following measurements were performed using the ``esp_timer`` example with default settings for ESP32: the maximum and default log levels were set to INFO, color support was disabled, and timestamps were enabled. After enabling the **Log V2** option, the example was rebuilt, and the memory usage differences were compared using the command:
|
||||
|
||||
@@ -470,17 +507,31 @@ The following measurements were performed using the ``esp_timer`` example with d
|
||||
|
||||
idf.py size --diff ~/esp/logv2/build_v1
|
||||
|
||||
+------------------------+---------------+--------------+---------------+------------+-----------------+
|
||||
| Version | IRAM | DRAM | Flash Code | Flash Data | App binary size |
|
||||
+========================+===============+==============+===============+============+=================+
|
||||
| Log V2 | +1772 | -36 | -956 | -1172 | 181104 (-384) |
|
||||
+------------------------+---------------+--------------+---------------+------------+-----------------+
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
+------------------------+-------------------------+
|
||||
| Version | Bootloader binary size |
|
||||
+========================+=========================+
|
||||
| Log V2 | 26272 (+160) |
|
||||
+------------------------+-------------------------+
|
||||
* - Version
|
||||
- IRAM
|
||||
- DRAM
|
||||
- Flash Code
|
||||
- Flash Data
|
||||
- App binary size
|
||||
* - Log V2
|
||||
- +1772
|
||||
- –36
|
||||
- –956
|
||||
- –1172
|
||||
- 181104 (–384)
|
||||
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:align: center
|
||||
|
||||
* - Version
|
||||
- Bootloader binary size
|
||||
* - Log V2
|
||||
- 26272 (+160)
|
||||
|
||||
Enabling **Log V2** increases IRAM usage while reducing the overall application binary size, Flash code, and data usage.
|
||||
|
||||
|
@@ -6,33 +6,33 @@
|
||||
概述
|
||||
--------
|
||||
|
||||
ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**Log V1** 和 **Log V2**,可通过 :ref:`CONFIG_LOG_VERSION` 参数进行选择。本文档概述了这两个日志系统版本的特性、配置及使用方法,并比较了二者的性能表现。
|
||||
ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本 **Log V1** 和 **Log V2**,可通过 :ref:`CONFIG_LOG_VERSION` 参数进行选择。本文档概述了这两个日志系统版本的特性、配置及使用方法,并比较了二者的性能表现。
|
||||
|
||||
- **Log V1**(默认):原始实现方式,具备简洁性,针对早期日志和 DRAM 日志进行了优化,但 flash 占用较高,缺乏灵活性。
|
||||
- **日志 V2**:增强实现方式,更加灵活,降低了 flash 占用,并集中处理日志格式,但需要更多的堆栈。
|
||||
- **Log V1**:默认的原始实现方式,具备简洁性,针对早期日志和 DRAM 日志进行了优化,但 flash 占用较高,缺乏灵活性。
|
||||
- **Log V2**:增强的实现方式,更加灵活,降低了 flash 占用,并集中处理日志格式,但需要更多的堆栈。
|
||||
|
||||
**Log V2** 向后兼容 **Log V1**,这意味着使用 **Log V1** 编写的项目可以直接切换到 **Log V2**,无需额外修改。但是,使用 **Log V2** 特定功能的项目无法恢复到 **Log V1**。
|
||||
**Log V2** 向后兼容 **Log V1**,这意味着使用 **Log V1** 编写的项目可以直接切换到 **Log V2**,无需额外修改。但是,由于兼容性限制,使用 **Log V2** 特定功能的项目不能恢复到 **Log V1**。
|
||||
|
||||
**Log V1** 的特性
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- 日志格式信息由 ``format`` 参数定义,在编译时嵌入了 flash。
|
||||
- 日志格式由 ``format`` 参数定义,在编译时嵌入了 flash 中。
|
||||
- 相比 ESP_LOG,能更快记录早期日志和 DRAM 日志。
|
||||
- 实现简单,但具有局限性:
|
||||
|
||||
- 由于包含冗余的格式化信息,二进制文件体积较大。
|
||||
- 不支持自定义日志格式,缺乏灵活性。
|
||||
- 编译错误所指向的宏中的参数位置不准确。
|
||||
- 编译错误所指向的宏中的参数位置编号不准确。
|
||||
|
||||
**Log V2** 的特性
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- 通过单个函数 :cpp:func:`esp_log` 集中处理格式。
|
||||
- 仅存储用户定义的格式字符串,从而减小二进制文件大小。
|
||||
- 仅在输出需要且日志级别允许记录时,才获取时间戳。
|
||||
- 仅在输出需要且日志级别允许记录时,才会获取时间戳。
|
||||
- 允许自定义日志输出:
|
||||
|
||||
- 为某个层级(全局、文件或消息)禁用或启用颜色、时间戳或标签。
|
||||
- 为某个层级(全局、文件或日志消息)启用或禁用颜色、时间戳或标签。
|
||||
- 输出不经过格式化处理的原始日志(适用于二进制日志)。
|
||||
- 为引导加载程序和应用程序采用不同的日志设置。
|
||||
|
||||
@@ -41,43 +41,41 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
- 缺点:
|
||||
|
||||
- 消耗更多的栈和内存。
|
||||
- 日志处理速度比 **Log V1** 稍慢,但在 UART 传输过程中,其差异可忽略不计。
|
||||
- 日志处理速度比 **Log V1** 略慢,但与传输数据的时间相比(例如通过 UART),差异可以忽略不计。
|
||||
|
||||
日志级别
|
||||
----------
|
||||
|
||||
对于应用程序和引导加载程序,日志级别需要分别配置。这一分离配置的特点使开发者能够通过 Kconfig 选项为每个模块应用不同的日志设置。例如,可以为引导加载程序启用简洁的日志,而为应用程序启用详细的调试日志(Debug 模式)。使用引导加载程序专用的 Kconfig 选项,可以为引导加载程序独立配置日志级别,不会影响主应用程序。
|
||||
对于应用程序和引导加载程序,日志级别需要分别配置。开发者可以通过 Kconfig 选项为每个模块设置不同的日志级别,从而实现配置的独立性。例如,可以为引导加载程序启用简洁的日志,而为应用程序启用详细的调试日志。使用引导加载程序专用的 Kconfig 选项,可以为引导加载程序独立配置日志级别,不会影响主应用程序。
|
||||
|
||||
日志库有六个详细程度级别:
|
||||
日志库共有六个详细程度级别:
|
||||
|
||||
- (最高)
|
||||
- **Verbose** - 输出高度详细且频繁的调试信息,通常包括内部状态,可能会使输出过于繁杂。
|
||||
- **Verbose** - 输出高度详细且频繁的调试信息,通常包括内部状态,可能会使输出过于繁杂。(最高级别)
|
||||
- **Debug** - 输出详细的诊断信息(例如变量值、指针地址等),适用于调试。
|
||||
- **Info** - 输出描述系统正常运行的一般信息。
|
||||
- **Warning** - 输出可能引发问题,但已被处理或减轻影响的事件。
|
||||
- **Error** - 仅输出严重错误,这些错误如果不进行干预处理,软件无法自行恢复。
|
||||
- **None** - 无日志输出,即完全禁用日志。
|
||||
- (最低)
|
||||
- **None** - 无日志输出,即完全禁用日志。(最低级别)
|
||||
|
||||
日志级别设置
|
||||
------------------
|
||||
|
||||
日志级别设置控制将哪些日志包含在二进制文件中,以及这些日志在运行时的可见性。日志级别设置有两种:
|
||||
通过日志级别设置,可以选择将哪些日志包含在二进制文件中,并决定这些日志在运行时的可见性。日志级别设置包括以下两种:
|
||||
|
||||
- **日志级别(Log level)**:指定运行时显示哪些级别的日志。引导加载程序的 **日志级别** 通过 :ref:`CONFIG_BOOTLOADER_LOG_LEVEL` 配置,而应用程序的 **日志级别** 通过 :ref:`CONFIG_LOG_DEFAULT_LEVEL` 设置。通过函数 ``esp_log_get_default_level`` 能够获取当前日志级别。
|
||||
- **日志级别**:指定在运行时显示哪些级别的日志。引导加载程序的 **日志级别** 通过 :ref:`CONFIG_BOOTLOADER_LOG_LEVEL` 配置,而应用程序的 **日志级别** 通过 :ref:`CONFIG_LOG_DEFAULT_LEVEL` 设置。通过函数 ``esp_log_get_default_level`` 能够获取当前日志级别。
|
||||
|
||||
- **最大日志级别(Maximum log level)**:决定将哪些日志级别包含在二进制文件中。高于此级别的日志会在编译时丢弃,不包含在最终镜像中。**最大日志级别** 可以将其设置得高于 **日志级别**,从而在二进制文件中包含额外的日志,在必要时便可通过 :cpp:func:`esp_log_level_set` 启用这些日志以帮助调试。使用 :ref:`CONFIG_LOG_MAXIMUM_LEVEL` 选项可以为应用程序启用此功能,但引导加载程序不支持此功能。对于引导加载程序,**最大日志级别** 始终与 **日志级别** 相同。
|
||||
- **最高日志级别**:指定将哪些日志级别包含在二进制文件中。高于此级别的日志会在编译时丢弃,不包含在最终镜像中。对于应用程序,**最高日志级别** 可以设置得高于 **日志级别**,从而在二进制文件中包含额外的日志,必要时,便可通过 :cpp:func:`esp_log_level_set` 启用这些日志以帮助调试。使用 :ref:`CONFIG_LOG_MAXIMUM_LEVEL` 选项可以为应用程序启用此功能。引导加载程序不支持此功能,其 **最高日志级别** 始终与 **日志级别** 相同。
|
||||
|
||||
为应用程序设置日志级别示例:如果将 **日志级别** 设置为 **Warning**,**最大日志级别** 设置为 **Debug**,则二进制文件会包含 **Error**、**Warning**、**Info** 和 **Debug** 级别的日志消息。然而,在运行时仅输出 **Error** 和 **Warning** 级别的日志,除非通过 :cpp:func:`esp_log_level_set` 显式更改日志级别。根据具体需求,日志级别可以提高或降低。
|
||||
例如,如果将 **日志级别** 设置为 **Warning**,**最高日志级别** 设置为 **Debug**,则二进制文件会包含 **Error**、**Warning**、**Info** 和 **Debug** 级别的日志。然而,在运行时仅输出 **Error** 和 **Warning** 级别的日志,除非通过 :cpp:func:`esp_log_level_set` 显式更改日志级别。根据具体需求,日志级别可以提高或降低。
|
||||
|
||||
**最大日志级别** 设置
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
设置 ``最高日志级别``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
根据 ``LOG_LOCAL_LEVEL`` 的定义可知,可以使用此参数覆盖特定源文件或组件的 **最大日志级别**,而无需修改 Kconfig 选项。此参数能在本地设置 **最大日志级别**,启用或排除二进制文件中的特定日志。
|
||||
根据 ``LOG_LOCAL_LEVEL`` 的定义,可使用此参数覆盖特定源文件或组件的 **最高日志级别**,而无需修改 Kconfig 选项。此参数能设置一个本地的 **最高日志级别**,从而启用或排除二进制文件中的特定日志。
|
||||
|
||||
通过此方法,能够有效为代码的特定部分提供更详细的日志,而无需全局提高 **最大日志级别**,避免了对二进制文件大小产生不必要的影响。
|
||||
通过此方法,能够有效为代码的特定部分提供更详细的日志,而无需全局提高 **最高日志级别**,避免了对二进制文件大小产生不必要的影响。
|
||||
|
||||
- 更改某个源文件的 **最大日志级别**(不要在头文件中添加该定义,因为头文件采用单次包含的机制,可能无法正常工作):在包含 ``esp_log.h`` 之前,使用 :cpp:type:`esp_log_level_t` 中的一个值来定义 ``LOG_LOCAL_LEVEL``,控制将哪些日志消息包含在该源文件的二进制文件中。
|
||||
- 更改某个源文件的 **最高日志级别** (不要在头文件中添加该定义,因为头文件采用单次包含的机制,可能无法生效):在包含 ``esp_log.h`` 之前,使用 :cpp:type:`esp_log_level_t` 中的一个值来定义 ``LOG_LOCAL_LEVEL``,指定将哪些日志消息包含在该源文件的二进制文件中。
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -85,21 +83,21 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#include "esp_log.h"
|
||||
|
||||
- 更改整个组件的 **最大日志级别**:在组件的 `CMakeLists.txt` 文件中定义 ``LOG_LOCAL_LEVEL``。指定的日志级别适用于组件内的所有源文件,控制将哪些日志消息包含在二进制文件中:
|
||||
- 更改整个组件的 **最高日志级别**:在组件的 `CMakeLists.txt` 文件中定义 ``LOG_LOCAL_LEVEL``。这确保指定的日志级别适用于组件内的所有源文件,指定将哪些日志消息包含在二进制文件中:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# 在组件的 CMakeLists.txt 文件中
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLOG_LOCAL_LEVEL=ESP_LOG_VERBOSE")
|
||||
|
||||
运行时 **日志级别** 设置
|
||||
运行时更改 ``日志级别``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
仅应用程序支持在运行时更改日志级别,启动引导加载程序不支持此功能。
|
||||
|
||||
默认情况下,系统启动时会启用 **日志级别** 以下的所有日志级别。可以使用函数 :cpp:func:`esp_log_level_set` 全局或按模块设置 **日志级别**。模块可通过标签识别,这些标签是人类可读以零结尾的 ASCII 字符串。此功能依赖于 :ref:`CONFIG_LOG_DYNAMIC_LEVEL_CONTROL`,此选项默认启用。如无需此功能,可以将其禁用,以减少代码量并提升性能。
|
||||
|
||||
例如,将所有组件的日志级别设置为 ``ERROR``(全局设置):
|
||||
例如,将所有组件的日志级别设置为 ``ERROR`` (全局设置):
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -107,7 +105,7 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
|
||||
根据模块(标签)调整日志输出的功能依赖于 :ref:`CONFIG_LOG_TAG_LEVEL_IMPL`,该选项默认启用。如不需要此功能,可以将其禁用,以减少代码量并提升性能。
|
||||
|
||||
例如,仅将 Wi-Fi 组件的日志级别设置为 ``WARNING``(模块特定设置):
|
||||
例如,仅将 Wi-Fi 组件的日志级别设置为 ``WARNING`` (特定模块设置):
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -116,17 +114,17 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
使用日志库
|
||||
---------------
|
||||
|
||||
在每个使用日志记录功能的 C 文件中定义 ``TAG`` 变量。
|
||||
在每个使用日志功能的 C 文件中定义 ``TAG`` 变量。
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE // Optional: Increase log level that will be included in binary (only for this file)
|
||||
// #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE // 可选:增加包含在二进制文件中的日志级别(仅适用于本文件)
|
||||
#include "esp_log.h"
|
||||
static const char* TAG = "MyModule";
|
||||
// ...
|
||||
ESP_LOGI(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real);
|
||||
ESP_EARLY_LOGW(TAG, "Early log message %d", i++);
|
||||
ESP_DRAM_LOGE(DRAM_STR("TAG_IN_DRAM"), "DRAM log message %d", i++); // Use DRAM_STR macro to put in DRAM if needed
|
||||
ESP_DRAM_LOGE(DRAM_STR("TAG_IN_DRAM"), "DRAM log message %d", i++); // 如果需要,使用 DRAM_STR 宏添加 DRAM
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -138,7 +136,7 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
|
||||
``TAG`` 变量指向存储在 flash 中的一个字符串字面量。如果在单个构建单元(翻译单元)中多次使用相同的 ``TAG`` 字符串,编译器和链接器通常会通过 **字符串池化** 过程将其优化为 flash 中的单个副本。然而,如果不同的组件或翻译单元使用了相同的 ``TAG`` 字符串,每个组件或单元在 flash 中都会存储一个副本,除非应用了全局链接器优化。
|
||||
|
||||
日志库提供了多种宏以适应不同的使用场景,包括通用日志记录、早期启动日志记录和受限环境日志等。选择合适的宏并据此构建相应的程序结构,有助于优化性能,确保可靠运行。但是,建议在设计程序结构时尽量避免在受限环境中进行日志记录。
|
||||
日志库提供了多种宏以适应不同的使用场景,例如通用日志记录、早期启动日志记录和受限环境日志等,如下所示。选择合适的宏并据此构建相应的程序结构,有助于优化性能,确保可靠运行。但是,建议在设计程序结构时尽量避免在受限环境中进行日志记录。
|
||||
|
||||
- Verbose: :c:macro:`ESP_LOGV`, :c:macro:`ESP_EARLY_LOGV`, :c:macro:`ESP_DRAM_LOGV`.
|
||||
- Debug: :c:macro:`ESP_LOGD`, :c:macro:`ESP_EARLY_LOGD`, :c:macro:`ESP_DRAM_LOGD`.
|
||||
@@ -166,13 +164,13 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
|
||||
- **Log V2**:
|
||||
|
||||
- 允许完全自定义日志格式,包括全局、按文件、按模块,甚至为单个日志消息禁用颜色、标签和时间戳格式。
|
||||
- 允许完全自定义日志格式,包括全局、按文件、按模块、为单个日志消息禁用颜色、标签和时间戳格式。
|
||||
- 更精细的日志输出控制,更适用于特定的用例和环境。
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// #define ESP_LOG_COLOR_DISABLED (1) /* For Log v2 only */
|
||||
// #define ESP_LOG_TIMESTAMP_DISABLED (1) /* For Log v2 only */
|
||||
// #define ESP_LOG_COLOR_DISABLED (1) /* 仅用于 Log v2 */
|
||||
// #define ESP_LOG_TIMESTAMP_DISABLED (1) /* 仅用于 Log v2 */
|
||||
#include "esp_log.h"
|
||||
static const char* TAG = "boot";
|
||||
// ...
|
||||
@@ -190,18 +188,18 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
|color | |user string
|
||||
|timestamp
|
||||
|
||||
日志系统支持以下格式化选项,并且同时适用于应用程序和引导加载程序:
|
||||
日志系统支持以下格式选项,并且同时适用于应用程序和引导加载程序:
|
||||
|
||||
- **Color**:增加颜色代码,全局增强日志的可见性。由 :ref:`CONFIG_LOG_COLORS` 控制,默认情况下禁用,因为 ESP-IDF 监视工具 `idf.py monitor` 可以通过 **级别名称** 检测日志级别并应用标准的 IDF 颜色方案。
|
||||
|
||||
- 对于 **Log V2**,选项 :ref:`CONFIG_LOG_COLORS_SUPPORT` 支持在运行时为特定日志、文件或组件添加颜色输出,即使全局颜色已禁用。要为特定上下文启用颜色,请使用 ``ESP_LOG_COLOR_DISABLED``。
|
||||
- 对于 **Log V2**,选项 :ref:`CONFIG_LOG_COLORS_SUPPORT` 支持在运行时为特定日志、文件或组件添加颜色输出,即使全局颜色已禁用。此时要为特定上下文启用颜色,请使用 ``ESP_LOG_COLOR_DISABLED``。
|
||||
|
||||
- **Level Name**:表示日志详细级别的单个字母(I, W, E, D, V),显示在每条日志消息的开头,用于识别日志级别。这在禁用颜色时非常有用,例如在禁用颜色时 ESP-IDF 监视工具就会使用该信息。
|
||||
|
||||
- **Timestamp**:为日志消息全局添加时间戳。由 :ref:`CONFIG_LOG_TIMESTAMP_SOURCE` 控制。
|
||||
|
||||
- **None**:不显示时间戳。在日志分析或调试中,当时间不关键时非常有用,还能够节省处理性能和内存。仅适用于 **Log V2**。
|
||||
- **Milliseconds since boot** `(18532)`(默认):通过 RTOS 时钟滴答计数乘以滴答周期得出。
|
||||
- **Milliseconds since boot** `(18532)` (默认):通过 RTOS 时钟 tick 计数乘以 tick 周期得出。
|
||||
- **System time (HH:MM:SS.sss)** `14:31:18.532`:以小时、分钟、秒和毫秒显示时间。
|
||||
- **System time (YY-MM-DD HH:MM:SS.sss)** `(2023-08-15 14:31:18.532)`:同上,还包括日期。
|
||||
- **Unix time in milliseconds** `(1692099078532)`:以毫秒显示 Unix 时间。
|
||||
@@ -217,17 +215,17 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
|
||||
- **ESP_LOG_CONSTRAINED_ENV**:
|
||||
|
||||
- 定义为 ``1``时,强制日志处理程序 :cpp:func:`esp_log` 使用适合指定作用域的安全 printf 函数。
|
||||
- 定义为 ``1`` 时,强制日志处理程序 :cpp:func:`esp_log` 使用适合指定作用域的安全 printf 函数。
|
||||
|
||||
- **ESP_LOG_FORMATTING_DISABLED**:
|
||||
|
||||
- 默认为 ``0``(启用所有格式化项,如颜色、时间戳、标记和末尾换行)。
|
||||
- 默认为 ``0``,即启用所有格式化项,如颜色、时间戳、标记和末尾换行。
|
||||
- 定义为 ``1`` 时,为指定范围禁用所有的格式化项。
|
||||
|
||||
- **ESP_LOG_COLOR_DISABLED**: 要求 :ref:`CONFIG_LOG_COLORS_SUPPORT` 启用。
|
||||
|
||||
- 如果全局颜色 (:ref:`CONFIG_LOG_COLORS`) 已禁用,则定义为 ``0``,以启用指定范围的颜色输出。
|
||||
- 如果启用了全局颜色(:ref:`CONFIG_LOG_COLORS`),则定义为 ``1``,表示禁用指定范围的颜色输出。
|
||||
- 如果启用了全局颜色 (:ref:`CONFIG_LOG_COLORS`),则定义为 ``1``,表示禁用指定范围的颜色输出。
|
||||
|
||||
- **ESP_LOG_TIMESTAMP_DISABLED**: 要求启用 :ref:`CONFIG_LOG_TIMESTAMP_SUPPORT`。
|
||||
|
||||
@@ -237,34 +235,34 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
设置每条日志的输出格式
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
上述定义与提供的日志宏可以无缝配合使用。如果需要更高的灵活性,或需要在运行时调整设置,例如根据某个值(例如温度)调整日志级别,可以使用其他的宏来实现。需要注意的是,在这种情况下,日志不能从二进制文件中丢弃,因为它们绕过了编译时的日志级别检查。
|
||||
上述定义可以与提供的日志宏无缝配合使用。如果需要更高的灵活性,或需要在运行时调整设置,例如根据某个值(例如温度)调整日志级别,可以使用其他的宏来实现。需要注意的是,在这种情况下,日志不能从二进制文件中丢弃,因为它们绕过了编译时的日志级别检查。
|
||||
|
||||
下面的示例演示了如何调整单独的日志消息的格式:
|
||||
下面的示例演示了如何调整单个日志消息的格式:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include "esp_log.h"
|
||||
esp_log_config_t configs = {
|
||||
.opts = {
|
||||
.log_level = ESP_LOG_INFO, // Set log level
|
||||
.constrained_env = false, // Specify constrained environment
|
||||
.require_formatting = true, // Enable formatting
|
||||
.dis_color = ESP_LOG_COLOR_DISABLED, // Use global color setting
|
||||
.dis_timestamp = ESP_LOG_TIMESTAMP_DISABLED, // Use global timestamp setting
|
||||
.reserved = 0, // Reserved for future use
|
||||
.log_level = ESP_LOG_INFO, // 设置 log level
|
||||
.constrained_env = false, // 指定是否为受限环境
|
||||
.require_formatting = true, // 启用格式处理
|
||||
.dis_color = ESP_LOG_COLOR_DISABLED, // 使用全局颜色设置
|
||||
.dis_timestamp = ESP_LOG_TIMESTAMP_DISABLED, // 使用全局时间戳设置
|
||||
.reserved = 0, // 保留后续使用
|
||||
}
|
||||
};
|
||||
// ...
|
||||
if (temperature > 55) {
|
||||
configs.opts.log_level = ESP_LOG_WARN;
|
||||
}
|
||||
// Similar to ESP_LOGx macros but allows applying custom configurations
|
||||
// If the configs var is constant, the compiler can exclude the log during compilation
|
||||
// if it is below the maximum log level, otherwise not.
|
||||
//与 ESP_LOGx 宏相似,但可以采用自定义配置
|
||||
// 如果 configs 变量为常量,编译器在编译过程中会排除低于 maximum log level 的日志
|
||||
//如果 configs 不是常量则不适用
|
||||
ESP_LOG_LEVEL_LOCAL(configs, TAG, "Temp = %dC", temperature);
|
||||
|
||||
// Note: The following calls bypass compile-time log level checks,
|
||||
// they cannot be discarded from the binary
|
||||
// // 注意:以下调用绕过了编译时日志级别检查
|
||||
// 这些日志无法从二进制文件中丢弃
|
||||
esp_log(configs, TAG, "Temp = %dC", temperature);
|
||||
ESP_LOG_LEVEL(configs, TAG, "Temp = %dC", temperature);
|
||||
|
||||
@@ -277,76 +275,72 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Set log level to ERROR for all components (global setting)
|
||||
// 将所有组件的日志级别设置为ERROR(全局设置)
|
||||
esp_log_level_set("*", ESP_LOG_ERROR);
|
||||
|
||||
// Set log level to WARNING for the WiFi component (module-specific setting)
|
||||
// 将 Wi-Fi 组件的日志级别设置为 WARNING(特定模块设置)
|
||||
esp_log_level_set("wifi", ESP_LOG_WARN);
|
||||
|
||||
// Set log level to INFO for the DHCP client (module-specific setting)
|
||||
// 将 DHCP 客户端的日志级别设置为 INFO(模块相关设置)
|
||||
esp_log_level_set("dhcpc", ESP_LOG_INFO);
|
||||
|
||||
有三种设置可控制在运行时更改全局或每个模块(标签)的日志级别:
|
||||
下列三种设置可在运行时全局更改日志级别,或为单个模块(标签)更改日志级别:
|
||||
|
||||
- **Dynamic Log Level Control**(:ref:`CONFIG_LOG_DYNAMIC_LEVEL_CONTROL`,默认已启用):动态日志级别控制。启用后,可以通过 :cpp:func:`esp_log_level_set` 函数在运行时更改日志级别。该功能提高了灵活性,但也增加了内存和性能开销。如需考虑二进制文件的大小,并且无需在运行时动态更改日志级别,建议禁用此选项,特别是在 :ref:`CONFIG_LOG_TAG_LEVEL_IMPL` 设置为 **None** 时,以尽量减小程序大小。
|
||||
- **Dynamic Log Level Control** (:ref:`CONFIG_LOG_DYNAMIC_LEVEL_CONTROL`,默认已启用):动态日志级别控制。启用后,可以通过 :cpp:func:`esp_log_level_set` 函数在运行时更改日志级别。该功能提高了灵活性,但也增加了内存和性能开销。如需考虑二进制文件的大小,并且无需在运行时动态更改日志级别,建议禁用此选项,特别是在 :ref:`CONFIG_LOG_TAG_LEVEL_IMPL` 设置为 **None** 时,以尽量减小程序大小。
|
||||
|
||||
如果你的应用程序不需要动态调整日志级别,禁用此选项可以提高效率:
|
||||
|
||||
- 降低内存消耗:
|
||||
|
||||
- **IRAM**: ~260 bytes
|
||||
- **DRAM**: ~264 bytes
|
||||
- **Flash**: ~1 KB
|
||||
- **IRAM**: 约 260 bytes
|
||||
- **DRAM**: 约 264 bytes
|
||||
- **Flash**: 约 1 KB
|
||||
|
||||
- 提高日志操作性能,最多提高 10 倍。
|
||||
|
||||
- **Tag-Level Checks**(:ref:`CONFIG_LOG_TAG_LEVEL_IMPL`,默认值为 **Cache + Linked List**):标签级别检查,决定了如何检查每个标签的日志级别,影响内存使用和查找速度:
|
||||
- **Tag-Level Checks** (:ref:`CONFIG_LOG_TAG_LEVEL_IMPL`,默认值为 **Cache + Linked List**):标签级别检查,决定了如何检查每个标签的日志级别,影响内存使用和查找速度:
|
||||
|
||||
- **None**:完全禁用按标签进行日志级别检查,减少了开销,但失去了运行时的灵活性。
|
||||
- **None**:完全禁用按标签进行日志级别检查,能够减少开销,但失去了运行时的灵活性。
|
||||
|
||||
- **Linked List**:仅使用链表实现每个标签的日志级别设置(不使用缓存)。这种方法会遍历链表中的所有标签来确定日志级别,因此,当标签数量较大时,会导致查找速度变慢,但与 **缓存** 方式相比,能节省更多内存空间。链表方法通过对日志标签进行完整的字符串比较来确定适当的日志级别。与 **缓存** 方法不同,链表方式不依赖于标签指针比较,因此更适合动态定义的标签。如需优先考虑节省内存、启用或禁用特定模块的日志,或希望使用定义为变量的标签,请选择此方法。选择此方法会自动启用 **Dynamic Log Level Control** 功能。
|
||||
- **Linked List**:仅使用链表实现按标签设置日志级别(不使用缓存)。这种方法会遍历链表中的所有标签来确定日志级别,因此当标签数量较大时,会导致查找速度变慢,但与 **Cache** 方式相比,能节省更多内存空间。链表方法对日志标签进行完整的字符串比较,从而识别日志级别。与 **Cache** 方法不同,链表方法不依赖于标签指针比较,因此更适用于动态的标签定义。如需优先考虑节省内存、对特定模块启用或禁用日志,或希望使用定义为变量的标签,请选择此方法。选择此方法会自动启用 **Dynamic Log Level Control** (动态日志级别控制)功能。运行 ``ESP_LOGx`` 宏遇到新标签时,链表中的项会分配到堆栈上。
|
||||
|
||||
.. note::
|
||||
|
||||
注意,链表方式实现的标签日志级别检查存在以下不足:运行 ``ESP_LOGx`` 宏遇到新标签时,会在任务栈中分配链表条目。如果删除了创建这些条目的任务,链表中可能包含无效项,并且在遍历时可能会导致崩溃。
|
||||
|
||||
- **Cache + Linked List**(默认):缓存 + 链表,采用缓存与链表结合的方式,进行日志标签级别的检查,在内存占用和速度直接提供了平衡。缓存中会存储最近访问的日志标签及其对应的日志级别,为常用标签实现了更快的查找速度。这是因为缓存方式会比较标签指针,与执行完整字符串相比速度更快。对不常用标签,通过链表进行日志级别查找。但是,使用动态标签定义时,此选项可能无法正常工作,因为它依赖缓存中的标签指针比较,不适用于动态定义的标签。此混合方法利用了常用标签的缓存速度优势和不常用标签的链表存储效率,提升了日志级别查找的总体效率。选择此选项会自动启用 **Dynamic Log Level Control**。
|
||||
- **Cache + Linked List** (默认):缓存 + 链表,通过缓存与链表结合的方式进行日志标签级别检查,实现了内存占用和运行速度之间的平衡。缓存用于存储最近访问的日志标签及其对应的日志级别,加速了常用标签的查找。这是因为缓存方式会比较标签指针,与执行完整字符串相比速度更快。对不常用标签,通过链表进行日志级别查找。注意,使用动态标签定义时,此选项可能无法正常工作,因为它依赖缓存中的标签指针比较,不适用于动态定义的标签。此混合方法利用了常用标签的缓存速度优势和不常用标签的链表存储效率,提升了日志级别查找的总体效率。选择此选项会自动启用 **Dynamic Log Level Control**。
|
||||
|
||||
有一些缓存配置可以平衡内存使用和查找性能。这些配置决定了日志标签级别的存储和访问方式,详见 :ref:`CONFIG_LOG_TAG_LEVEL_CACHE_IMPL`。
|
||||
|
||||
- **Array**:数组方式,实现简单,不进行重新排序,适合注重简洁性的低内存应用。
|
||||
|
||||
- **Binary Min-Heap**(默认)最小二叉堆,优化的实现方式,支持快速查找并自动重新排序,适用于具有充足内存的高性能应用。**缓存大小** (:ref:`CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE`) 定义了其容量,默认包含 31 个条目。
|
||||
- **Binary Min-Heap** (默认配置)最小二叉堆,优化的实现方式,支持快速查找并自动重新排序,适用于具有充足内存的高性能应用。其容量由 **缓存大小** (:ref:`CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE`) 定义,默认包含 31 个条目。
|
||||
|
||||
缓存容量越大,查找常用日志标签的性能越高,但内存消耗也会增加。相反,缓存容量越小越节省内存,但可能会淘汰更多使用较少的标签。
|
||||
缓存容量越大,查找常用日志标签的性能越高,但内存消耗也会增加。相反,缓存容量越小越节省内存,但可能导致不常用的日志标签被更频繁地移除。
|
||||
|
||||
- **Master Log Level**(:ref:`CONFIG_LOG_MASTER_LEVEL`,默认禁用):这是一个可选设置,专为特定调试场景设计。此设置启用后,会在生成时间戳和标签缓存查找之前,启用全局 master 日志级别检查。这一选项适用于编译大量日志的情况,可以在运行时有选择地启用或禁用日志,同时在不需要日志输出时,尽量减少对性能的影响。
|
||||
- **Master Log Level** (:ref:`CONFIG_LOG_MASTER_LEVEL`,默认禁用):这是一个可选设置,专为特定调试场景设计。此设置启用后,会在生成时间戳和标签缓存查找之前,启用全局 master 日志级别检查。这一选项适用于编译大量日志的情况,可以在运行时有选择地启用或禁用日志,同时在不需要日志输出时尽量减少对性能的影响。
|
||||
|
||||
例如,通常可以在在时间紧迫或 CPU 密集型操作期间临时禁用日志,并在之后重新启用日志。
|
||||
|
||||
.. note:: 对于 **Log V1**,此功能可能会基于已编译日志的数量而显著增加程序大小。对于 **Log V2** 影响很小,因为检查已集成到了日志处理程序中。
|
||||
|
||||
如果启用此功能,主日志级别默认为 :ref:`CONFIG_LOG_DEFAULT_LEVEL`,并可在运行时通过 :cpp:func:`esp_log_set_level_master` 进行调整。此全局检查优先于 ``esp_log_get_default_level``。
|
||||
如果启用此功能,master 日志级别默认为 :ref:`CONFIG_LOG_DEFAULT_LEVEL`,并可在运行时通过 :cpp:func:`esp_log_set_level_master` 进行调整。此全局检查优先于 ``esp_log_get_default_level``。
|
||||
|
||||
以下代码片段演示了此功能的原理。将 **Master Log Level** 设置为 ``ESP_LOG_NONE`` 会在全局范围内禁用所有日志。此时,:cpp:func:`esp_log_level_set` 不会影响日志输出。但是,当 **Master Log Level** 调整为更高级别后,日志会按照 :cpp:func:`esp_log_level_set` 的配置打印出来:
|
||||
以下代码片段演示了此功能的原理。将 **Master Log Level** 设置为 ``ESP_LOG_NONE``,会在全局范围内禁用所有日志。此时,:cpp:func:`esp_log_level_set` 不会影响日志输出。但是,当 **Master Log Level** 调整为更高级别后,日志会按照 :cpp:func:`esp_log_level_set` 的配置打印出来:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Master logging level is CONFIG_LOG_DEFAULT_LEVEL at start-up and = ESP_LOG_INFO
|
||||
ESP_LOGI("lib_name", "Message for print"); // Prints an INFO message
|
||||
esp_log_level_set("lib_name", ESP_LOG_WARN); // Enables WARN logs for lib_name
|
||||
// master 日志级别在启动时为 CONFIG_LOG_DEFAULT_LEVEL, 且等于 ESP_LOG_INFO
|
||||
ESP_LOGI("lib_name", "Message for print"); // 打印 INFO 消息
|
||||
esp_log_level_set("lib_name", ESP_LOG_WARN); // 为 lib_name 启用 WARN 级别日志
|
||||
|
||||
// Disables all logs globally. esp_log_level_set has no effect at the moment
|
||||
// 全局禁用所有日志,esp_log_level_set 目前没有作用
|
||||
esp_log_set_level_master(ESP_LOG_NONE);
|
||||
|
||||
ESP_LOGW("lib_name", "Message for print"); // No print, Master logging level blocks it
|
||||
esp_log_level_set("lib_name", ESP_LOG_INFO); // Enables INFO logs for lib_name
|
||||
ESP_LOGI("lib_name", "Message for print"); // No print, Master logging level blocks it
|
||||
ESP_LOGW("lib_name", "Message for print"); // master 日志级别阻止了打印
|
||||
esp_log_level_set("lib_name", ESP_LOG_INFO); // 开启 lib_name 的 INFO 日志
|
||||
ESP_LOGI("lib_name", "Message for print"); // master 日志级别阻止了打印
|
||||
|
||||
// Enables all INFO logs globally
|
||||
// 全局启用所有 INFO 日志
|
||||
esp_log_set_level_master(ESP_LOG_INFO);
|
||||
|
||||
ESP_LOGI("lib_name", "Message for print"); // Prints an INFO message
|
||||
ESP_LOGI("lib_name", "Message for print"); // 打印 INFO 信息
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -355,7 +349,7 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
缓冲区日志
|
||||
----------
|
||||
|
||||
日志系统提供用于记录缓冲区数据的宏。这些宏可在引导加载程序和应用程序中使用,且不限制日志版本。可用的宏包括:
|
||||
日志系统提供用于记录缓冲区数据的宏。这些宏可在引导加载程序和应用程序中使用,且不限制日志版本。可用的宏有:
|
||||
|
||||
- :c:macro:`ESP_LOG_BUFFER_HEX` 和 :c:macro:`ESP_LOG_BUFFER_HEX_LEVEL`:记录十六进制字节缓冲区。数据按每行 16 个字节分割。:c:macro:`ESP_LOG_BUFFER_HEX` 仅适用于 ``Info`` 日志级别。
|
||||
|
||||
@@ -389,7 +383,7 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
I (985) MyModule: fox jumps over
|
||||
I (990) MyModule: the lazy dog.
|
||||
|
||||
- :c:macro:`EP_LOG_BUFFER_HEXDUMP`:以格式化的十六进制转储方式转储缓冲区,同时显示内存地址和相应的 ASCII 值。适用于调试原始内存内容。
|
||||
- :c:macro:`EP_LOG_BUFFER_HEXDUMP`:以格式化的十六进制转储方式输出缓冲区内容,同时显示内存地址和相应的 ASCII 值。适用于调试原始内存内容。
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -406,87 +400,138 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
I (1013) MyModule: 0x3ffb5bc0 54 68 65 20 77 61 79 20 74 6f 20 67 65 74 20 73 |The way to get s|
|
||||
I (1024) MyModule: 0x3ffb5bd0 74 61 72 74 65 64 20 69 73 20 74 6f 20 71 75 69 |tarted is to qui|
|
||||
|
||||
输出的行数取决于缓冲区大小。
|
||||
输出中包含的行数取决于缓冲区的大小。
|
||||
|
||||
性能测量
|
||||
|
||||
性能测试
|
||||
----------
|
||||
|
||||
在任务中使用日志时,任务栈必须配置至少 2 KB 的空间,以确保日志操作内存充足。
|
||||
在任务中使用日志时,任务栈必须配置至少 2 KB 的空间,确保有足够的内存进行日志操作。
|
||||
|
||||
使用日志组件中的测试工具,基于默认设置(最大和默认日志级别设置为 INFO,禁用颜色支持,未启用主日志级别,启用时间戳),在不同芯片上进行了如下两组测量:
|
||||
使用日志组件中的测试工具,基于默认设置(最大和默认日志级别设置为 INFO,禁用颜色支持,未启用 master 日志级别,启用时间戳),在不同芯片上进行了如下两组测试:
|
||||
|
||||
- 日志 API 性能测量
|
||||
- 日志 API 堆栈用量
|
||||
- 日志 API 性能测试
|
||||
- 日志 API 堆栈用量测试
|
||||
|
||||
``esp_rom_printf`` 和 ``esp_rom_vprintf`` 的结果相似,同样,vprintf 和 printf 也得出相似结果。因此,下表仅包括了每对相似测试中的一个。
|
||||
``esp_rom_printf`` 和 ``esp_rom_vprintf`` 的结果相似,同样,``vprintf`` 和 ``printf`` 也得出相似结果。因此,下表仅展示每对相似测试中的一个结果。
|
||||
|
||||
**堆栈用(字节)**
|
||||
.. list-table:: **堆栈使用情况(单位:字节)**
|
||||
:header-rows: 1
|
||||
|
||||
+-------------------+-------+---------+---------+
|
||||
| 功能 | ESP32 | ESP32C2 | ESP32C3 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| esp_rom_printf | 128 | 192 | 192 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V1 | 128 | 192 | 192 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V2 | 336 | 324 | 324 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V1 | 128 | 192 | 192 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V2 | 336 | 324 | 324 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| vprintf | 1168 | 384 | 1344 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V1 | 1184 | 384 | 1344 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V2 | 1152 | 592 | 1504 |
|
||||
+-------------------+-------+---------+---------+
|
||||
* - 功能
|
||||
- ESP32
|
||||
- ESP32C2
|
||||
- ESP32C3
|
||||
* - esp_rom_printf
|
||||
- 128
|
||||
- 192
|
||||
- 192
|
||||
* - ESP_EARLY_LOGI V1
|
||||
- 128
|
||||
- 192
|
||||
- 192
|
||||
* - ESP_EARLY_LOGI V2
|
||||
- 336
|
||||
- 324
|
||||
- 324
|
||||
* - ESP_DRAM_LOGI V1
|
||||
- 128
|
||||
- 192
|
||||
- 192
|
||||
* - ESP_DRAM_LOGI V2
|
||||
- 336
|
||||
- 324
|
||||
- 324
|
||||
* - vprintf
|
||||
- 1168
|
||||
- 384
|
||||
- 1344
|
||||
* - ESP_LOGI V1
|
||||
- 1184
|
||||
- 384
|
||||
- 1344
|
||||
* - ESP_LOGI V2
|
||||
- 1152
|
||||
- 592
|
||||
- 1504
|
||||
|
||||
**Log V1** 和 **Log V2** 之间的堆栈使用量差异可以忽略不计。
|
||||
|
||||
**性能(无微秒输出)**
|
||||
.. list-table:: 性能(不包括输出,单位:微秒)
|
||||
:header-rows: 1
|
||||
|
||||
+-------------------+-------+---------+---------+
|
||||
| 功能 | ESP32 | ESP32C2 | ESP32C3 |
|
||||
+===================+=======+=========+=========+
|
||||
| esp_rom_printf | 1 | 2 | 1 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V1 | 15 | 24 | 14 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_EARLY_LOGI V2 | 28 | 36 | 25 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V1 | 6 | 9 | 5 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_DRAM_LOGI V2 | 19 | 22 | 14 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| vprintf | 15 | 9 | 7 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V1 | 27 | 16 | 12 |
|
||||
+-------------------+-------+---------+---------+
|
||||
| ESP_LOGI V2 | 77 | 54 | 40 |
|
||||
+-------------------+-------+---------+---------+
|
||||
* - 功能
|
||||
- ESP32
|
||||
- ESP32C2
|
||||
- ESP32C3
|
||||
* - esp_rom_printf
|
||||
- 1
|
||||
- 2
|
||||
- 1
|
||||
* - ESP_EARLY_LOGI V1
|
||||
- 15
|
||||
- 24
|
||||
- 14
|
||||
* - ESP_EARLY_LOGI V2
|
||||
- 28
|
||||
- 36
|
||||
- 25
|
||||
* - ESP_DRAM_LOGI V1
|
||||
- 6
|
||||
- 9
|
||||
- 5
|
||||
* - ESP_DRAM_LOGI V2
|
||||
- 19
|
||||
- 22
|
||||
- 14
|
||||
* - vprintf
|
||||
- 15
|
||||
- 9
|
||||
- 7
|
||||
* - ESP_LOGI V1
|
||||
- 27
|
||||
- 16
|
||||
- 12
|
||||
* - ESP_LOGI V2
|
||||
- 77
|
||||
- 54
|
||||
- 40
|
||||
|
||||
关于通过 UART 输出日志的性能,**Log V1** 和**Log V2** 的几乎完全相同。与通过 UART 发送日志所需的时间相比,**Log V2** 在处理开销方面带来的微小差异可以忽略不计。因此,在大多数实际用例中,切换到 **Log V2** 对性能的影响可以忽略。
|
||||
关于通过 UART 输出日志的性能,**Log V1** 和 **Log V2** 的几乎完全相同。与通过 UART 发送日志所需的时间相比,**Log V2** 在处理开销方面带来的微小差异可以忽略不计。因此,在大多数实际用例中,切换到 **Log V2** 对性能的影响可以忽略。
|
||||
|
||||
**内存占用(字节)**
|
||||
|
||||
以下测量使用了 ``esp_timer`` 示例和 ESP32 的默认设置,最大和默认日志级别设为 INFO,禁用颜色支持,启用时间戳。启用 **Log V2** 后重新构建了示例,然后使用以下命令比较内存占用的差异:
|
||||
以下测试使用了 ``esp_timer`` 示例和 ESP32 的默认设置,最大和默认日志级别为 INFO,禁用颜色支持,启用时间戳。启用 **Log V2** 后重新构建了示例,然后使用以下命令比较内存占用的差异:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py size --diff ~/esp/logv2/build_v1
|
||||
|
||||
+------------------------+---------------+--------------+---------------+------------+-----------------+
|
||||
| 日志系统版本 | IRAM | DRAM | flash 代码 | flash 数据 | App 二进制大小 |
|
||||
+========================+===============+==============+===============+============+=================+
|
||||
| Log V2 | +1772 | -36 | -956 | -1172 | 181104 (-384) |
|
||||
+------------------------+---------------+--------------+---------------+------------+-----------------+
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
+------------------------+--------------------------+
|
||||
| 日志系统版本 | 引导加载程序二进制大小 |
|
||||
+========================+==========================+
|
||||
| Log V2 | 26272 (+160) |
|
||||
+------------------------+-------------------------——+
|
||||
* - 日志系统版本
|
||||
- IRAM
|
||||
- DRAM
|
||||
- flash 代码
|
||||
- flash 数据
|
||||
- App 二进制大小
|
||||
* - Log V2
|
||||
- +1772
|
||||
- –36
|
||||
- –956
|
||||
- –1172
|
||||
- 181104 (–384)
|
||||
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:align: center
|
||||
|
||||
* - 日志系统版本
|
||||
- 引导加载程序二进制大小
|
||||
* - Log V2
|
||||
- 26272 (+160)
|
||||
|
||||
启用 **Log V2** 会增加 IRAM 的使用量,同时减少整个应用程序的二进制文件大小、flash 代码和数据量。
|
||||
|
||||
@@ -498,7 +543,7 @@ ESP-IDF 提供了一套灵活的日志系统,包括两个可配置版本:**L
|
||||
线程安全
|
||||
-------------
|
||||
|
||||
在受限环境(或 **ESP_EARLY_LOGx** 和 **ESP_DRAM_LOGx**)记录日志时,不使用锁机制。因此,如果其他任务并行记录日志,可能会导致日志损坏的罕见情况。为降低此类风险,建议尽可能使用通用宏。
|
||||
在受限环境(或 **ESP_EARLY_LOGx** 和 **ESP_DRAM_LOGx**)记录日志时不使用锁机制,因此,如果其他任务并行记录日志,可能会导致日志损坏的罕见情况。为降低此类风险,建议尽可能使用通用宏。
|
||||
|
||||
通用宏 (**ESP_LOGx**) 通过在日志输出过程中获取锁来确保线程安全。在 **Log V2** 中,``flockfile`` 在多个 ``vprintf`` 调用进行格式化处理时提供了额外保护。
|
||||
|
||||
|
Reference in New Issue
Block a user