EMQ X:日志與追蹤


日志與追蹤

控制日志輸出

EMQ X 支持將日志輸出到控制台或者日志文件,或者同時使用兩者。可在 emqx.conf 中配置:

log.to = both

log.to 默認值是 both,可選的值為:

  • off: 完全關閉日志功能
  • file: 僅將日志輸出到文件
  • console: 僅將日志輸出到標准輸出(emqx 控制台)
  • both: 同時將日志輸出到文件和標准輸出(emqx 控制台)

日志級別

EMQ X 的日志分 8 個等級 (RFC 5424 (opens new window)),由低到高分別為:

debug < info < notice < warning < error < critical < alert < emergency

EMQ X 的默認日志級別為 warning,可在 emqx.conf 中修改:

log.level = warning

此配置將所有 log handler 的配置設置為 warning。

日志文件和日志滾動

EMQ X 的默認日志文件目錄在 ./log (zip包解壓安裝) 或者 /var/log/emqx (二進制包安裝)。可在 emqx.conf 中配置:

log.dir = log

在文件日志啟用的情況下 (log.to = file 或 both),日志目錄下會有如下幾種文件:

  • emqx.log.N: 以 emqx.log 為前綴的文件為日志文件,包含了 EMQ X 的所有日志消息。比如 emqx.log.1, emqx.log.2 ...
  • emqx.log.siz 和 emqx.log.idx: 用於記錄日志滾動信息的系統文件。
  • run_erl.log:emqx start 方式后台啟動 EMQ X 時,用於記錄啟動信息的系統文件。
  • erlang.log.N: 以 erlang.log 為前綴的文件為日志文件,是以 emqx start 方式后台啟動 EMQ X 時,控制台日志的副本文件。比如 erlang.log.1, erlang.log.2 ...

可在 emqx.conf 中修改日志文件的前綴,默認為 emqx.log

log.file = emqx.log

EMQ X 默認在單日志文件超過 10MB 的情況下,滾動日志文件,最多可有 5 個日志文件:第 1 個日志文件為 emqx.log.1,第 2 個為 emqx.log.2,並以此類推。當最后一個日志文件也寫滿 10MB 的時候,將從序號最小的日志的文件開始覆蓋。文件大小限制和最大日志文件個數可在 emqx.conf 中修改:

#文件大小限制
log.rotation.size = 10MB
#最大日志文件個數
log.rotation.count = 5 

針對日志級別輸出日志文件

如果想把大於或等於某個級別的日志寫入到單獨的文件,可以在 emqx.conf 中配置 log.<level>.file

將 info 及 info 以上的日志單獨輸出到 info.log.N 文件中:

log.info.file = info.log

將 error 及 error 以上的日志單獨輸出到 error.log.N 文件中

log.error.file = error.log

日志格式

可在 emqx.conf 中修改單個日志消息的最大字符長度,如長度超過限制則截斷日志消息並用 ... 填充。默認不限制長度:

將單個日志消息的最大字符長度設置為 8192:

log.chars_limit = 8192
 
        Copied!
    

1

日志消息的格式為(各個字段之間用空格分隔):

date time level client_info module_info msg

  • date: 當地時間的日期。格式為:YYYY-MM-DD
  • time: 當地時間,精確到毫秒。格式為:hh:mm:ss.ms
  • level: 日志級別,使用中括號包裹。格式為:[Level]
  • client_info: 可選字段,僅當此日志消息與某個客戶端相關時存在。其格式為:ClientId@Peername 或 ClientId 或 Peername
  • module_info: 可選字段,僅當此日志消息與某個模塊相關時存在。其格式為:[Module Info]
  • msg: 日志消息內容。格式任意,可包含空格。

日志消息舉例 1:

2020-02-18 16:10:03.872 [debug] <<"mqttjs_9e49354bb3">>@127.0.0.1:57105 [MQTT/WS] SEND CONNACK(Q0, R0, D0, AckFlags=0, ReasonCode=0)

此日志消息里各個字段分別為:

  • date: 2020-02-18
  • time: 16:10:03.872
  • level: [debug]
  • client_info: <<"mqttjs_9e49354bb3">>@127.0.0.1:57105
  • module_info: [MQTT/WS]
  • msg: SEND CONNACK(Q0, R0, D0, AckFlags=0, ReasonCode=0)

#日志消息舉例 2:

2020-02-18 16:10:08.474 [warning] [Alarm Handler] New Alarm: system_memory_high_watermark, Alarm Info: []  

此日志消息里各個字段分別為:

  • date: 2020-02-18
  • time: 16:10:08.474
  • level: [warning]
  • module_info: [Alarm Handler]
  • msg: New Alarm: system_memory_high_watermark, Alarm Info: []

注意此日志消息中,client_info 字段不存在。

日志級別和 log handlers

EMQ X 使用了分層的日志系統,在日志級別上,包括全局日志級別 (primary log level)、以及各 log hanlder 的日志級別。

     [Primary Level]        -- global log level and filters
           / \
[Handler 1]  [Handler 2]    -- log levels and filters at each handler

log handler 是負責日志處理和輸出的工作進程,它由 log handler id 唯一標識,並負有如下任務:

  • 接收什么級別的日志
  • 如何過濾日志消息
  • 將日志輸出到什么地方

我們來看一下 emqx 默認安裝的 log handlers:

$ emqx_ctl log handlers list

LogHandler(id=ssl_handler, level=debug, destination=console, status=started)
LogHandler(id=file, level=warning, destination=log/emqx.log, status=started)
LogHandler(id=default, level=warning, destination=console, status=started)
  • file: 負責輸出到日志文件的 log handler。它沒有設置特殊過濾條件,即所有日志消息只要級別滿足要求就輸出。輸出目的地為日志文件。
  • default: 負責輸出到控制台的 log handler。它沒有設置特殊過濾條件,即所有日志消息只要級別滿足要求就輸出。輸出目的地為控制台。
  • ssl_handler: ssl 的 log handler。它的過濾條件設置為當日志是來自 ssl 模塊時輸出。輸出目的地為控制台。

日志消息輸出前,首先檢查消息是否高於 primary log level,日志消息通過檢查后流入各 log handler,再檢查各 handler 的日志級別,如果日志消息也高於 handler level,則由對應的 handler 執行相應的過濾條件,過濾條件通過則輸出。

設想一個場景,假設 primary log level 設置為 info,log handler default (負責輸出到控制台) 的級別設置為 debug,log handler file (負責輸出到文件) 的級別設置為 warning:

  • 雖然 console 日志是 debug 級別,但此時 console 日志只能輸出 info 以及 info 以上的消息,因為經過 primary level 過濾之后,流到 default 和 file 的日志只剩下 info 及以上的級別;
  • emqx.log.N 文件里面,包含了 warning 以及 warning 以上的日志消息。

在 日志級別章節中提到的 log.level 是修改了全局的日志級別。這包括 primary log level 和各個 handlers 的日志級別,都設置為了同一個值。

Primary Log Level 相當於一個自來水管道系統的總開關,一旦關閉則各個分支管道都不再有水流通過。這個機制保證了日志系統的高性能運作。

運行時修改日志級別

你可以使用 EMQ X 的命令行工具 emqx_ctl 在運行時修改 emqx 的日志級別:

修改全局日志級別:

例如,將 primary log level 以及所有 log handlers 的級別設置為 debug:

$ emqx_ctl log set-level debug

修改主日志級別:

例如,將 primary log level 設置為 debug:

$ emqx_ctl log primary-level debug

修改某個 log handler 的日志級別:

例如,將 log handler file 設置為 debug:

$ emqx_ctl log handlers set-level file debug

停止某個 log handler:

例如,為了讓日志不再輸出到 console,可以停止 log handler default:

$ emqx_ctl log handlers stop default

啟動某個已經停止的 log handler:

例如,啟動上面已停止的 log handler default:

$ emqx_ctl log handlers start default 

日志追蹤

EMQ X 支持針對 ClientID 或 Topic 過濾日志並輸出到文件。在使用日志追蹤功能之前,必須將 primary log level 設置為 debug:

$ emqx_ctl log primary-level debug

開啟 ClientID 日志追蹤,將所有 ClientID 為 'my_client' 的日志都輸出到 log/my_client.log:

$ emqx_ctl log primary-level debug
debug

$ emqx_ctl trace start client my_client log/my_client.log
trace clientid my_client successfully

開啟 Topic 日志追蹤,將主題能匹配到 't/#' 的消息發布日志輸出到 log/topic_t.log:

$ emqx_ctl log primary-level debug
debug

$ emqx_ctl trace start topic 't/#' log/topic_t.log
trace topic t/# successfully

即使 emqx.conf 中,log.level 設置為 error,使用消息追蹤功能仍然能夠打印出某 client 或 topic 的 debug 級別的信息。這在生產環境中非常有用。

日志追蹤的原理

日志追蹤的原理是給 emqx 安裝一個新的 log handler,並設置 handler 的過濾條件。在 日志級別和 log handlers小節,我們討論過 log handler 的細節。

比如使用如下命令啟用 client 日志追蹤:

$ emqx_ctl log primary-level debug && emqx_ctl trace start client my_client log/my_client.log

然后查詢已經開啟的追蹤:

$ emqx_ctl trace list
Trace(clientid=my_client, level=debug, destination="log/my_client.log", status=started)

在后台,emqx 會安裝一個新的 log handler,並給其指定過濾條件為:僅當 ClientID 為 "my_client" 的時候,輸出日志:

$ emqx_ctl log handlers list
LogHandler(id=trace_clientid_my_client, level=debug, destination=log/my_client.log, status=started)
...  

這里看到新添加的 log handler 的 id 為 trace_clientid_my_client,並且 handler level 為 debug。這就是為什么在 trace 之前,我們必須將 primary log level 設置為 debug。

如果使用默認的 primary log level (warning),這個log handler 永遠不會輸出 warning 以下的日志消息。

另外,由於我們是啟用了一個新的 log handler,所以我們的日志追蹤不受控制台日志和 emqx.log.N 文件日志的級別的約束。即使 log.level = warning,我們仍然可以追蹤到 my_client 的 debug 級別的日志。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM