本地日志分析上報(bào)腳本實(shí)現(xiàn)思路梳理

一、背景

目前我們部門(mén)的日志查詢只能通過(guò)開(kāi)發(fā)人員登錄對(duì)應(yīng)的機(jī)器執(zhí)行日志分析趾徽,效率不夠高效续滋。對(duì)于現(xiàn)網(wǎng)問(wèn)題,由于運(yùn)維不理解后臺(tái)模塊的日志含義孵奶,因此只能由開(kāi)發(fā)去現(xiàn)網(wǎng)機(jī)器查詢?nèi)罩酒W茫粚?duì)于聯(lián)調(diào)環(huán)境,接入方調(diào)用接口出了問(wèn)題只能通過(guò)我們部門(mén)后臺(tái)開(kāi)發(fā)人員協(xié)助解決。這種強(qiáng)依賴指定開(kāi)發(fā)人員的情況朗恳,不利于問(wèn)題的快速解決湿颅。因此我們迫切的需要一個(gè)日志中心來(lái)處理和查詢所有的日志,并且由于需要在聯(lián)調(diào)時(shí)能夠讓接入方自己定位問(wèn)題粥诫,我們對(duì)實(shí)時(shí)性也有一定的要求油航。但是由于公司沒(méi)有提供這種系統(tǒng),所以我們決定自己做一個(gè)日志模塊來(lái)處理上述問(wèn)題怀浆。
這篇文章主要是寫(xiě)一下日志模塊客戶端的實(shí)現(xiàn)思路谊囚,對(duì)于日志存儲(chǔ)查詢服務(wù)由于不是我開(kāi)發(fā),所以只做簡(jiǎn)單介紹执赡。

二镰踏、在模塊內(nèi)部實(shí)現(xiàn)

最開(kāi)始的實(shí)現(xiàn)方式是修改業(yè)務(wù)邏輯代碼,在需要上報(bào)日志的地方增加日志上報(bào)邏輯沙合,但是由于php語(yǔ)言不支持裝飾器和注解這樣的語(yǔ)法奠伪,因此這樣的實(shí)現(xiàn)對(duì)于業(yè)務(wù)代碼的入侵度極高,同時(shí)需要大量修改業(yè)務(wù)代碼已有的處理流程首懈,也存在著很大的風(fēng)險(xiǎn)绊率。同時(shí)由于增加了日志上報(bào)邏輯,因此多了一次網(wǎng)絡(luò)調(diào)用猜拾,如果日志服務(wù)存在故障即舌,那么網(wǎng)絡(luò)調(diào)用超時(shí)會(huì)影響業(yè)務(wù)邏輯,這是很不合理的實(shí)現(xiàn)方案挎袜,因此我這樣寫(xiě)了兩天代碼就寫(xiě)不下去了。

三肥惭、優(yōu)化

后來(lái)看了下CI框架的文檔盯仪,發(fā)現(xiàn)CI也支持鉤子語(yǔ)法,因此可以通過(guò)設(shè)置一個(gè)全局的鉤子來(lái)實(shí)現(xiàn)對(duì)關(guān)鍵日志的監(jiān)控蜜葱,所謂鉤子全景,其實(shí)就是框架主流程埋幾個(gè)點(diǎn),這樣你就可以在框架執(zhí)行流程中增加自己的邏輯來(lái)影響框架執(zhí)行流程牵囤,我當(dāng)時(shí)掛鉤點(diǎn)是控制器初始化完成爸黄,但調(diào)用構(gòu)造器之前。這樣的實(shí)現(xiàn)看起來(lái)很簡(jiǎn)單揭鳞,也減少了代碼入侵炕贵,但是僅僅是減少代碼入侵而已,對(duì)于所有的流程還是會(huì)經(jīng)過(guò)日志判斷野崇,運(yùn)行流程上面還是和最開(kāi)始的實(shí)現(xiàn)方式一樣称开,是全局的。另外一點(diǎn)很不好的地方就是需要設(shè)置幾個(gè)全局變量來(lái)存儲(chǔ)一些鉤子獲取不到的數(shù)據(jù),如網(wǎng)絡(luò)調(diào)用鳖轰,這樣對(duì)于后來(lái)的維護(hù)者很難理解為什么這里會(huì)有一個(gè)全局變量賦值清酥,然后就吐槽一番這個(gè)代碼順便刪除,然后我們的日志監(jiān)控就呵呵了蕴侣。因此這樣的實(shí)現(xiàn)方案也是不太好的焰轻。所以我把代碼回滾,放棄了這種做法昆雀。辱志。

四、通過(guò)本地日志agent腳本實(shí)現(xiàn)

接下來(lái)就是本文的重點(diǎn)啦~

最后決定通過(guò)本地寫(xiě)個(gè)腳本來(lái)實(shí)時(shí)分析日志并且上傳到日志模塊來(lái)實(shí)現(xiàn)日志的監(jiān)控忆肾。這個(gè)方案是我認(rèn)為最合理的方案荸频,同時(shí)也是很多企業(yè)的做法。實(shí)現(xiàn)方案確定好了以后客冈,接下來(lái)的就是評(píng)估技術(shù)方案了旭从。

python腳本循環(huán)讀取日志存儲(chǔ)目錄實(shí)現(xiàn)監(jiān)控
由于之前有位大神給我講過(guò)他之前是怎么做一個(gè)日志監(jiān)控的,他當(dāng)時(shí)告訴我是本地寫(xiě)了一個(gè)腳本來(lái)實(shí)現(xiàn)场仲,所以我第一想法就是寫(xiě)個(gè)python腳本和悦。但是寫(xiě)了一段時(shí)間發(fā)現(xiàn)越寫(xiě)越?jīng)]譜,主要是因?yàn)楝F(xiàn)網(wǎng)的日志一天的量是以T為單位渠缕,而我的邏輯里面包含了很多的文件IO(因?yàn)橐獙?shí)時(shí)監(jiān)控鸽素,所以要一直讀取文件夾監(jiān)控內(nèi)部的變化)。所以這樣做的話亦鳞,很可能會(huì)出現(xiàn)分析跟不上產(chǎn)生的節(jié)奏馍忽,這樣實(shí)時(shí)性很差且會(huì)產(chǎn)生一定的系統(tǒng)負(fù)載,因此這種實(shí)現(xiàn)被放棄了燕差。

后來(lái)想了想遭笋,突然記起之前在學(xué)校做得一個(gè)項(xiàng)目,項(xiàng)目里面有個(gè)知識(shí)點(diǎn)是關(guān)于linux文件系統(tǒng)監(jiān)控的徒探,即linux文件系統(tǒng)的inotify機(jī)制瓦呼,關(guān)于該機(jī)制的介紹我就不做過(guò)多篇幅的描述了,參見(jiàn)這篇wikiinotify测暗。

所以我完全可以去網(wǎng)上下個(gè)python實(shí)現(xiàn)的文件系統(tǒng)notify庫(kù)央串,然后就可以很方便的監(jiān)控到文件系統(tǒng)的變化了。但是突然想起后面還有那么多的字符分析碗啄,好像用python的話性能不能滿足我們對(duì)實(shí)時(shí)性要求高的需求质和,因此我決定使用shell命令來(lái)做這個(gè)腳本。那些設(shè)計(jì)優(yōu)美且性能高效的文本分析命令完全可以很方便的實(shí)現(xiàn)我對(duì)于日志分析的要求挫掏。而且這樣我的全部工作就是組裝命令侦另,維護(hù)日志分析的主邏輯了。

shell通過(guò)notify_tools實(shí)現(xiàn)日志分析
shell實(shí)現(xiàn)有幾個(gè)技術(shù)問(wèn)題需要解決,第一是文本處理命令的選擇褒傅;第二是notify_tools是否真能滿足要求弃锐;第三則是性能測(cè)試了

文本命令的選擇

# 普通字符過(guò)濾性能比較
[root@mcs/data/log/trade.logical]# time grep ".*atom" log-2016-07-16.log>/dev/null
real    0m0.194s
user    0m0.188s
sys 0m0.004s

[root@mcs /data/log/trade.logical]# time sed "/.*atom/p" log-2016-07-16.log>/dev/null
real    0m0.201s
user    0m0.192s
sys 0m0.008s

[root@mcs/data/log/trade.logical]# time awk "/.*atom/" log-2016-07-16.log>/dev/null
real    0m1.502s
user    0m1.484s
sys 0m0.016s

可以看出來(lái)這三者的性能排序?yàn)間rep>sed>awk,awk基本不考慮使用了殿托,最然它給我們提供了可編程的空間霹菊,但是太慢了。至于最快的grep支竹,由于它在命令上支持不夠豐富旋廷,所以也不考慮使用。因此選取性能和功能相對(duì)而言優(yōu)于其他兩者的sed命令礼搁。
當(dāng)然饶碘,這只是一個(gè)簡(jiǎn)單的測(cè)試,由于我缺乏對(duì)這三個(gè)命令高級(jí)選項(xiàng)的認(rèn)識(shí)馒吴,因此這三個(gè)命令在加了高級(jí)選項(xiàng)以后的性能排序可能有所不同扎运。但是對(duì)目前的需求而言,執(zhí)行這樣的測(cè)試然后選擇sed是沒(méi)有問(wèn)題的饮戳。

notify_tools是否滿足要求
這個(gè)就簡(jiǎn)單了豪治,通過(guò)執(zhí)行man inotifywait看了下文檔,發(fā)現(xiàn)這個(gè)工具是滿足我們的要求的

性能測(cè)試
待補(bǔ)充....

shell腳本實(shí)現(xiàn)方案

有幾點(diǎn)需要首先明確扯罐,這個(gè)日志分析腳本由于是在本機(jī)運(yùn)行负拟,所以必然會(huì)部署多份,雖然我們部門(mén)只有幾臺(tái)服務(wù)器歹河,但也勉強(qiáng)算個(gè)分布式了==掩浙。所以腳本的運(yùn)行應(yīng)該足夠簡(jiǎn)單,所以決定通過(guò)配置文件來(lái)控制腳本的運(yùn)行秸歧。

另外一點(diǎn)就是如何保證日志文件都是被處理完了涣脚,不會(huì)出現(xiàn)漏處理或者處理速度跟不上的問(wèn)題。這個(gè)的實(shí)現(xiàn)我是通過(guò)維護(hù)一個(gè)處理偏移量的文件來(lái)記錄腳本處理的文件位置信息寥茫,方便腳本中斷后能夠從上次的處理位置繼續(xù)處理。

由于一次產(chǎn)生的日志量很大矾麻,所以不能夠一行一行的處理纱耻,這樣或許能夠跟上日志的產(chǎn)生速度,但是不太合理险耀,我采用的方案如下:

  1. 循環(huán)的執(zhí)行監(jiān)聽(tīng)命令弄喘,當(dāng)收到文件變化的通知后便立刻進(jìn)行處理
  2. 如果通知的變化文件和偏移量中記錄的文件一致,則計(jì)算出當(dāng)前文件總行數(shù)(主要是為了避免一直變化的行數(shù)造成處理混亂)甩牺,從上次記錄的偏移量處理到當(dāng)前文件的總行數(shù)
  3. 如果通知的變化文件和偏移量中記錄的文件不一致蘑志,這個(gè)時(shí)候說(shuō)明發(fā)生了新建日志文件的動(dòng)作,則一次性處理完偏移量文件中記錄的文件的剩下的所有內(nèi)容,并且開(kāi)始處理新創(chuàng)建的日志文件
  4. 更新偏移量和指向文件

這樣的實(shí)現(xiàn)有個(gè)特點(diǎn)就是急但,在日至量增加特別特別快的情況下(萬(wàn)行每秒)澎媒,處理腳本可能會(huì)出現(xiàn)延后,且日志增量如果不降下去波桩,處理會(huì)越來(lái)越延后戒努,但是當(dāng)新建文件時(shí),腳本會(huì)一次性將所有延后處理的日志一次性全部處理了镐躲,通過(guò)動(dòng)態(tài)獲取處理量來(lái)避免大量日志產(chǎn)生對(duì)于實(shí)時(shí)性的降低储玫。

當(dāng)然缺點(diǎn)也是很明顯的,如果日志量增加的速率一直增加萤皂,那么日志處理肯定是會(huì)有延后的撒穷,同時(shí)如果是通過(guò)調(diào)用接口上報(bào)日志的話,日志仍然會(huì)有幾秒甚至幾十秒左右的延后裆熙。但是對(duì)于我們的系統(tǒng)端礼,目前這樣實(shí)現(xiàn)是夠用了,業(yè)務(wù)量上去還可以通過(guò)優(yōu)化腳本和優(yōu)化日志服務(wù)的方式來(lái)提高日志的處理速度弛车。對(duì)于聯(lián)調(diào)環(huán)境的日志量齐媒,這樣的實(shí)現(xiàn)完全可以勝任。

接下來(lái)的事情就是讓時(shí)間去驗(yàn)證這樣實(shí)現(xiàn)的優(yōu)缺點(diǎn)纷跛。

后續(xù)改進(jìn)方案

  1. 目前這個(gè)腳本的耗時(shí)主要在日志的網(wǎng)絡(luò)傳輸上(即傳到日志中心的這個(gè)過(guò)程)喻括,采用的直接插入數(shù)據(jù)庫(kù)或者調(diào)用接口。
  2. 日志中心廢棄數(shù)據(jù)庫(kù)的存儲(chǔ)方式贫奠,采用更適合文本檢索的文件存儲(chǔ)方式來(lái)分析存儲(chǔ)日志唬血。
  3. 本地不再分析日志,只負(fù)責(zé)將日志提取出來(lái)發(fā)送給日至中心唤崭,分析由日至中心處理完成拷恨,但是降低了實(shí)時(shí)性。
  4. 傳輸協(xié)議上面可以用thrift協(xié)議谢肾,而不是現(xiàn)在的http協(xié)議或者直插數(shù)據(jù)庫(kù)腕侄。
  5. 規(guī)范化系統(tǒng)后臺(tái)日志格式,提高程序的整潔和日志信息的可讀性芦疏。

最后貼一段腳本的部分代碼來(lái)湊湊篇幅

#!/bin/sh

# 偏移量文件格式:偏移量 指向文件

configFile=$1
declare -a configArr

while IFS='' read -r line || [[ -n "$line" ]]; do
   IFS='=' read -r key value <<< "$line"
   configArr[$key]=$value
done < "$configFile"
echo -e "parse config file succ \n\nstart watch log file[log path:${configArr['logCategoryPath']}]\n"

while watchInfo=`inotifywait -q --format '%e %f' -e modify,create ${configArr['logCategoryPath']}`;do
    watchInfo=($watchInfo)
    lines=`wc -l ${watchInfo[1]}`
    offsetInfo=`cat ${configArr['offsetFilePath']}`
    # 如果偏移量文件不存在冕杠,則創(chuàng)建偏移量文件
    if [ $? ]; then
        # 如果偏移量記錄文件為空,則初始化偏移量酸茴,從第0行讀取變更的文件
        if [ $offsetInfo -eq "" ]; then
            process 1 ${lines} $watchInfo[1]
        # 如果偏移量文件不為空分预,則取出偏移量和指向的文件
        else
            offsetInfo=($offsetInfo)
            if [ ${offsetInfo[1]} -eq ${watchInfo[1]} ]; then
                # 處理上一個(gè)日志文件
                process ${offset} $ $offsetFile 
                # 處理從第0行開(kāi)始處理新創(chuàng)建的文件
                process 1 ${lines} $watchInfo[1]
            else
                # 繼續(xù)處理偏移量文件中記錄的文件
                process ${offset} ${lines} $watchInfo[1]
            fi
        fi
        # 處理完成,更新偏移量和指向的文件
        cat "$lines ${watchInfo[1]}" > ${configArr['offsetFilePath']}
    else
        touch ${configArr['offsetFilePath']}
    fi
done
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末薪捍,一起剝皮案震驚了整個(gè)濱河市笼痹,隨后出現(xiàn)的幾起案子配喳,更是在濱河造成了極大的恐慌,老刑警劉巖凳干,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晴裹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡纺座,警方通過(guò)查閱死者的電腦和手機(jī)息拜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)净响,“玉大人少欺,你說(shuō)我怎么就攤上這事〔鱿停” “怎么了赞别?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)配乓。 經(jīng)常有香客問(wèn)我仿滔,道長(zhǎng),這世上最難降的妖魔是什么犹芹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任崎页,我火速辦了婚禮,結(jié)果婚禮上腰埂,老公的妹妹穿的比我還像新娘飒焦。我一直安慰自己,他們只是感情好屿笼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布牺荠。 她就那樣靜靜地躺著,像睡著了一般驴一。 火紅的嫁衣襯著肌膚如雪休雌。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天肝断,我揣著相機(jī)與錄音杈曲,去河邊找鬼。 笑死胸懈,一個(gè)胖子當(dāng)著我的面吹牛鱼蝉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播箫荡,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼渔隶!你這毒婦竟也來(lái)了羔挡?” 一聲冷哼從身側(cè)響起洁奈,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绞灼,沒(méi)想到半個(gè)月后利术,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡低矮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年印叁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片军掂。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轮蜕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蝗锥,到底是詐尸還是另有隱情跃洛,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布终议,位于F島的核電站汇竭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏穴张。R本人自食惡果不足惜细燎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望皂甘。 院中可真熱鬧玻驻,春花似錦、人聲如沸叮贩。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)益老。三九已至彪蓬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捺萌,已是汗流浹背档冬。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桃纯,地道東北人酷誓。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像态坦,于是被迫代替她去往敵國(guó)和親盐数。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理伞梯,服務(wù)發(fā)現(xiàn)玫氢,斷路器帚屉,智...
    卡卡羅2017閱讀 134,672評(píng)論 18 139
  • linux資料總章2.1 1.0寫(xiě)的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 12,168評(píng)論 2 33
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,826評(píng)論 6 342
  • 當(dāng)2016年9月份的時(shí)候,葉老師在群里說(shuō)要組織一群人在100天里專(zhuān)注做一件事漾峡。當(dāng)時(shí)我毫不猶豫的就參加了攻旦。在100天...
    澤濱閱讀 233評(píng)論 0 0