深入浅出 NXLog (二)
轉自 http://www.jianshu.com/p/392ab60aa5b0
1. Nxlog 模塊簡介
在之前的文章當中我已經提到過 Nxlog 的 module 共分為4種,它們分別是 input, output, processor, extension。 Input module 負責從各種數據源(如 file, archive, tcp, udp等)中采集數據,Output module 定義了該如何處理采集的數據,我們可以以文件的方式保存下來,也可能通過 tcp,udp 發出去。Processor module 負責對采集的數據進行處理,比如做一些內容過濾,格式轉換之類的。Extension module 主要是用來擴展讀寫數據的接口,它可以針對特定的數據類型進行特定的處理,比如多行合并,將csv文件解析成不能的fields等,我的解釋可能不太準確,官方的說法是:‘These modules can enhance the features of nxlog in different ways, such as exporting new functions and procedures, registering additional I/O reader and writer functions to be used with modules supporting the OutputType and InputType directives’。
這里面 input 和 output 模塊是必不可少的,processor 和 extension 可有可無。下面我以 im_file 模塊為例來講解一下每個模塊的工作流程。im_file 是個 Input 模塊,它主要是用來采集文件的。
2. Module 狀態機
說到工作流程,那不得不提 狀態機(FSM, Finite State Machines),通過狀態機可以幫我們很好的理解 module 的工作過程。
如上圖所示,每個 Module 總共有 4 種狀態,它們分別是UNINITIALIZED, STOPPED, RUNNING, PAUSED。每個 Module 創建成功之后會通過 nx_module_config 調用自己 config 接口加載配置,這個時候還處在 UNINITIALIZED 狀態。然后通過 nx_module_init 調用自己 init 接口進行初始化,狀態轉換為 STOPPED。接著通過 nx_module_start_shelf 調用自己 start 接口啟動該 module,狀態轉換為 RUNNING。這時模塊就開始產生各種 event 來工作,在這個過程中它的狀態也可能會變為 PAUSED,比如當 im_file 模塊采集了很多數據而 Output 模塊又沒有及時處理時,它的狀態會變成 PAUSED,等緩存的數據被消費后它的狀態會再變為 RUNNING。
當進程要退出時,會通過 nx_module_stop_self 接口調用各個模塊的 stop 接口,狀態轉換為 STOPPED,接著通過 nx_module_shutdown_self 調用 shutdown 接口回歸到最初的 UNINITIALIZED 狀態。
3. im_file 詳解
接下來我詳細講一下 im_file 的配置,啟動,工作,停止流程。
3.1 im_file 配置
每個模塊在啟動的過程中都要加載配置,針對 im_file 模塊,比較重要的配置有以下這些。
- File
指定需要采集的文件名,可以使用通配符。
- SavePos
指定是否需要保存文件的采集位置,以防止下一次啟動后重采,默認是 TRUE。
- ReadFromLast
指定是否從文件末尾處開始采集。如果是 TRUE,就從文件尾開始采集,忽略存量數據。如果是 FALSE,要看保存的是否有文件位置,如果有就從上一次采集后的地方開始采集,如果沒有就從文件首開始采集,默認是 TRUE。
3.2 im_file 啟動
im_file_check_new(module, imconf->readfromlast);im_file_add_poll_event(module, FALSE);im_file_add_dircheck_event(module, FALSE);start 接口主要干了 3 件事。
1. 將配置文件中 File 指定的所有文件打開(當文件數目大于 ActiveFiles 時,其它的文件會關閉),然后把所有的 file 結構體保存在 imconf->files 哈希表中,其中 key 是文件名,value 是 file 結構體地址。當文件個數很多時,這個過程會很慢。
2. 產生一個 poll event,這個 event 是用來讀取所有 open_files 的數據。
3. 產生一個 dircheck event, 這個 event 是用來檢查有沒有未處理的文件以及已處理的文件有沒有新數據可讀。
3.3 im_file 工作
im_file 的工作主要是處理啟動階段產生的兩個 event。其中 NX_EVENT_READ 就是上面的 poll event, NX_EVENT_MODULE_SPECIFIC 就是上面的 dircheck event。
static void im_file_event(nx_module_t *module, nx_event_t *event) {ASSERT(event != NULL);switch ( event->type ){case NX_EVENT_READ:im_file_read(module);break;case NX_EVENT_MODULE_SPECIFIC:im_file_dircheck_event_cb(module);break;default:nx_panic("invalid event type: %d", event->type);} }上面已經介紹了這兩個 event 的主要工作,下面再詳細說一下他們的流程。
NX_EVENT_READ
首先從 open_files 哈希表中取出一個 file,然后讀取數據放到 buf 里,接著將這些數據一行行提取出來產生很多 logdata,logdata 會首先按照 Exec 的配置進行處理,如果沒有被 drop 就根據 Router 的配置查看需要發送到哪個 module (Processor 或者 Output),然后再看要發送的 module queue 的 size,當 queue 滿了(size >= NX_LOGQUEUE_LIMIT) 會根據 FlowControl 的配置,要么 free 該 logdata(FlowControl disable),要么將 im_file module 的狀態置成 PAUSE(FlowControl enable),從而不再產生新的 logdata,以達到流控的目的。當 queue 未滿就將該 logdata 放到要發送的module 的 queue 里,最后向這個 module 發送一個 NX_EVENT_DATA_AVAILABLE event,提醒它處理該 logdata,這樣每個 logdata 的處理流程就算走完了。
當這個 file 里的數據被處理完后,會從 open_files 列表中取出下一個 file 來處理,如此循環往復。為了防止文件很大導致這個過程占用很長時間,在外面就加了一個限制,最多循環 IM_FILE_MAX_READ 次。
當這次 READ 執行完后會再產生一個 NX_EVENT_READ event,至于下一個 event 何時執行取決于 imconf->files 列表中是否有沒有讀取完的文件,如果有就立即執行,如果沒有就等待 poll_interval 秒后執行。
NX_EVENT_MODULE_SPECIFIC
if ( im_file_check_new(module, FALSE) == TRUE ){//log_info("dircheck_event_cb detected new files in check_new()");got_data = TRUE;}if ( im_file_check_files(module, FALSE) == TRUE ){//log_info("dircheck_event_cb detected new files in check_files()");got_data = TRUE;}首先通過 im_file_check_new 接口檢查有沒有未曾處理的文件,如果 File 配置指定了一個文件夾,并且 recursive 是 TRUE,該接口會遍歷這個文件夾下所有的文件,包括子目錄。im_file 啟動過程中就干過這件事,那次是將所有的存量文件加入到 imconf->files 哈希表中,這次則是基于存量文件檢查有沒有新增文件。
新增文件檢查完后,還要通過 im_file_check_files 接口查看已處理的文件有沒有新數據可讀,它會檢查文件的 size 和偏移 filepos,當 size > filepos 代表有未處理的數據。當找到 active_files 個可讀文件后,這個接口會退出,以免耗費太多時間。其實在處理 NX_EVENT_READ event 快結束的時候也干過這件事,不過那時是只檢查 imconf->files,這次是連 open_files 也一起檢查。
通過上面兩步如果發現有新增文件或者有新數據可讀,got_data 會被置成 TRUE,這時會立即產生一個 NX_EVENT_READ event 去讀取數據。接著再產生一個 NX_EVENT_MODULE_SPECIFIC event,等待 dircheck_interval 秒后執行下一次檢查。
3.4 im_file 停止
stop 就比較簡單了,首先將所有的 open_files 關閉,然后銷毀所有的 imconf->files 結構,釋放內存,這時會判斷 savepos 是否為 TRUE,如果是 TRUE 會將文件的 filepos 保存到 ctx->config_cache 結構中,最后等所有的 module 退出后會將 ctx->config_cache 寫入磁盤。這樣
nxlog 下次啟動時就知道上一次文件采集到了什么位置,不會重采。
總結
以上是生活随笔為你收集整理的深入浅出 NXLog (二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TeamViewer 远程连接一直显示正
- 下一篇: 网吧母盘的制作(2007详细)