nxlog號(hào)稱“日志收集神器”蜜另。nxlog 2.8社區(qū)版存在一個(gè)bug,此bug會(huì)導(dǎo)致明顯的內(nèi)存泄漏。
重現(xiàn)方法
采用支持自動(dòng)字符集轉(zhuǎn)化的擴(kuò)展轮蜕,對(duì)日志數(shù)據(jù)進(jìn)行轉(zhuǎn)化時(shí):
<Extension charconv>
Module xm_charcov
AutodetectCharsets gbk, utf-8, euc-jp, utf-16, utf-32, iso8859-2
</Extension>
<Input filein>
Module im_file
File "tmp/input"
Exec convert_fields("AUTO", "utf-8");
</Input>
...
nxlog對(duì)配置了AUTO
源字符集的日志數(shù)據(jù)進(jìn)行轉(zhuǎn)化時(shí),會(huì)按照順序從AutodetectCharsets
羅列的候選字符集從左到右依次嘗試進(jìn)行轉(zhuǎn)化(采用libiconv
)良姆,直到成功肠虽。
如果源文件的字符集無(wú)法匹配第一個(gè)AutodetectCharsets
,那么將導(dǎo)致內(nèi)存泄漏玛追,使用valgrind
測(cè)試得到下面輸出:
可以看到税课,在這個(gè)測(cè)試下,泄漏的字節(jié)盡然高達(dá)150M
痊剖,如果測(cè)試?yán)^續(xù)下去韩玩,可能更高。在壓力測(cè)試下陆馁,泄漏的速度甚至高達(dá)30M/s
找颓。而泄漏的根源是iconv_open
沒(méi)有對(duì)應(yīng)的iconv_close
。
問(wèn)題分析
通過(guò)源碼分析叮贩,可以發(fā)現(xiàn)在src/modules/extension/charconv/charconv.c
中_nx_convert
負(fù)責(zé)iconv_open
击狮,并調(diào)用iconv
佛析,但是轉(zhuǎn)化失敗會(huì)導(dǎo)致拋出異常(long jump
)。于是iconv_close
將被跳過(guò):
修復(fù)方法
修復(fù)這個(gè)問(wèn)題有兩個(gè)方面:
- 盡量避免使用
AUTO
源彪蓬,通過(guò)觀察AUTO
的邏輯寸莫,可以發(fā)現(xiàn)效率比較低下,最好能夠提前知道源文件的字符編碼档冬。夏洛克采集程序
將Mozilla Firefox
瀏覽器中對(duì)文檔字符集自動(dòng)探測(cè)算法集成到了產(chǎn)品中膘茎,從而盡可能避免使用AUTO
。 - 在
_nx_convert
方法內(nèi)部catch
住異常酷誓,并在保證關(guān)閉后rethrow披坏。由于C語(yǔ)言無(wú)法模擬finally
,如果考慮到代碼的優(yōu)雅性盐数,那么應(yīng)避免在iconv_close
之前throw
異常棒拂。