# entangled/utils/logger_helper 使用注意
## logger 的等級
在 [logger_helper.h](https://github.com/iotaledger/entangled/blob/develop/utils/logger_helper.h) 可發現 `log_debug()` 、`log_info()` ... 等 macro 皆是呼叫 `logger_helper_print()`,並傳入對應的 level。
而 `logger_helper_print()` 原始碼如下 :
```c=
void logger_helper_print(logger_id_t const logger_id, logger_level_t const level, char const* const format, ...) {
va_list argp;
if (level < logger_output_level_get(stdout)) {
return;
}
va_start(argp, format);
lock_handle_lock(&lock);
logger_va(logger_id, level, format, argp);
lock_handle_unlock(&lock);
va_end(argp);
}
```
在第 4 行可發現若使用的 logger level 小於 stdout 的 level,便會直接 return ,不會印出任何訊息。
> 附上 logger 等級表 (由低至高排序)
> LOGGER_DEBUG
> LOGGER_INFO
> LOGGER_NOTICE
> LOGGER_WARNING
> LOGGER_ERR
> LOGGER_CRIT
> LOGGER_ALERT
> LOGGER_EMERG
>
## git repository 使用舊版 entangled
首先,原本在 tangle-accelerator/WORKSPACE 裡可以看到使用 entangled 的 commit 版本如下
```
git_repository(
name = "entangled",
commit = "46cab95db5fa1e03274446d9f2df9a4b7ba12462",
remote = "https://github.com/iotaledger/entangled.git",
)
```
在這個 commit 版本中的 `logger_helper_init()` 如下:
```c=
retcode_t logger_helper_init() {
if (LOGGER_VERSION != logger_version()) {
return RC_UTILS_INVALID_LOGGER_VERSION;
}
logger_init();
logger_color_prefix_enable();
logger_color_message_enable();
logger_output_register(stdout);
logger_output_level_set(stdout, LOGGER_WARNING);
lock_handle_init(&lock);
return RC_OK;
}
```
可以注意到 : 第 9 行將 stdout 註冊為一個 logger 的 output stream,<font color ="orange">第 10 行將 stdout 的 level 設定為 LOGGER_WARNING</font>,這代表透過 `log_debug()`、 `log_info()`、`log_notice()` 印出的訊息將無法顯示在 stdout 上,因為這三者的等級低於 LOGGER_WARNING。
因此當時在使用 logger 的時候,若呼叫 `logger_helper_init()` ,那麼 stdout 不會顯示任何透過 `log_debug()`、 `log_info()`、`log_notice()` 印出的訊息。當時的解決方法便是將 `logger_helper_init()` 裡的程式碼抽出來用,其中
```c=
logger_output_level_set(stdout, LOGGER_WARNING);
```
改寫成
```c=
logger_output_level_set(stdout, LOGGER_DEBUG);
```
也就是將 stdout 的 level 設定成 LOGGER_DEBUG (最低等級),如此一來等級在 LOGGER_DEBUG 以上(含)的 logger 訊息便都能顯示在 stdout 上。
因此整個程式碼如下:
```c=
// Initialize logger
if (LOGGER_VERSION != logger_version()) {
return EXIT_FAILURE;
}
logger_init();
logger_color_prefix_enable();
logger_color_message_enable();
logger_output_register(stdout);
logger_output_level_set(stdout, LOGGER_DEBUG);
```
## git repository 使用 tag 為 "cclient-v1.0.0-beta" 版本的 entangled
在 entangled 這個版本中的 [logger_helper.c](https://github.com/iotaledger/entangled/blob/cclient-v1.0.0-beta/utils/logger_helper.c) 中可發現,`logger_helper_init()` <font color ="orange">不再將 stdout 的等級寫死成 LOGGER_WARNING 了</font>,而是透過參數設定 stdout 的 level (下方程式碼第 10 行)。此版本的 `logger_helper_init()` 程式碼如下 :
```c=
retcode_t logger_helper_init(logger_level_t level) {
if (LOGGER_VERSION != logger_version()) {
return RC_UTILS_INVALID_LOGGER_VERSION;
}
logger_init();
logger_color_prefix_enable();
logger_color_message_enable();
logger_output_register(stdout);
logger_output_level_set(stdout, level);
lock_handle_init(&lock);
return RC_OK;
}
```
## 在 tag 為 "cclient-v1.0.0-beta" 版本下 ,TA 使用 logger 的方法
- 原本 accelerator/mqtt_interface.c 的 `main()`
```c=
int main(int argc, char *argv[]) {
status_t ret;
mosq_config_t cfg;
struct mosquitto *mosq = NULL;
// Initialize logger
if (LOGGER_VERSION != logger_version()) {
return EXIT_FAILURE;
}
logger_init();
logger_color_prefix_enable();
logger_color_message_enable();
logger_output_register(stdout);
logger_output_level_set(stdout, LOGGER_DEBUG);
logger_id = logger_helper_enable(MQTT_INTERFACE_LOGGER, LOGGER_DEBUG, true);
.
.
.
}
```
應改寫成
```c=
int main(int argc, char *argv[]) {
status_t ret;
mosq_config_t cfg;
struct mosquitto *mosq = NULL;
// Initialize logger
if (logger_helper_init(LOGGER_DEBUG) != RC_OK) {
return EXIT_FAILURE;
}
logger_id = logger_helper_enable(MQTT_INTERFACE_LOGGER, LOGGER_DEBUG, true);
.
.
.
}
```
---
- 原本 accelerator/server.cc 的 `main()`
```c=
int main(int argc, char* argv[]) {
served::multiplexer mux;
mux.use_after(served::plugin::access_log);
// Initialize logger
if (LOGGER_VERSION != logger_version()) {
return EXIT_FAILURE;
}
logger_init();
logger_color_prefix_enable();
logger_color_message_enable();
logger_output_register(stdout);
logger_output_level_set(stdout, LOGGER_DEBUG);
server_logger_id = logger_helper_enable(SERVER_LOGGER, LOGGER_DEBUG, true);
.
.
.
}
```
應改寫成
```c=
int main(int argc, char* argv[]) {
served::multiplexer mux;
mux.use_after(served::plugin::access_log);
// Initialize logger
if (logger_helper_init(LOGGER_DEBUG) != RC_OK) {
return EXIT_FAILURE;
}
server_logger_id = logger_helper_enable(SERVER_LOGGER, LOGGER_DEBUG, true);
.
.
.
}
```
---
- 原本 accelerator/main.c 的 `main()`
```c=
int main(int argc, char* argv[]) {
if (signal_handle_register(SIGINT, ta_stop) == SIG_ERR || signal_handle_register(SIGTERM, ta_stop) == SIG_ERR) {
return EXIT_FAILURE;
}
// Initialize logger
if (LOGGER_VERSION != logger_version()) {
return EXIT_FAILURE;
}
logger_init();
logger_color_prefix_enable();
logger_color_message_enable();
logger_output_register(stdout);
logger_output_level_set(stdout, LOGGER_DEBUG);
logger_id = logger_helper_enable(MAIN_LOGGER, LOGGER_DEBUG, true);
.
.
.
}
```
應改寫成
```c=
int main(int argc, char* argv[]) {
if (signal_handle_register(SIGINT, ta_stop) == SIG_ERR || signal_handle_register(SIGTERM, ta_stop) == SIG_ERR) {
return EXIT_FAILURE;
}
// Initialize logger
if (logger_helper_init(LOGGER_DEBUG) != RC_OK) {
return EXIT_FAILURE;
}
logger_id = logger_helper_enable(MAIN_LOGGER, LOGGER_DEBUG, true);
.
.
.
}
```
## 小提醒
1. `logger_helper_enable()` 中的
```c=
logger_id_level_set(logger_id, level);
```
此行是設定傳入的 logger_id 的 level ,而非設定 output stream 的 level。
2. `logger_helper_init()` 中的
```c=
logger_output_level_set(stdout, level);
```
才是設定 output stream (在此為 stdout) 的 level。
## 參考
- https://bitbucket.org/embear/logger/src/default/
###### tags: `DLTcollab`