2015-09-16 116 views
1

我試圖寫一個shell腳本來提取它們相同的話行之間從日誌文件中查找間隔時間間隔。 條目很簡單:日誌文件中

19:38:24077 INFO [...](HTTP - 0.0.0.0-8443-17)用戶XXX得到REQUEST_CODE = wCv4cbch 19:38:24083 INFO [.. ](HTTP - 0.0.0.0-8443-17)用戶XXX釋放REQUEST_CODE = wCv4cbch 19:38:24091 INFO [...](HTTP - 0.0.0.0-8443-17)用戶XXX GET REQUEST_CODE = sZhegruu 19:38:24098 INFO [...](HTTP - 0.0.0.0-8443-17)用戶XXX釋放REQUEST_CODE = sZhegruu

我需要找到相同的密鑰之間的時間間隔,其中鍵是代碼'='操作符後。例如

19:38:24077 INFO [...](HTTP - 0.0.0.0-8443-17)用戶XXX得到REQUEST_CODE = wCv4cbch

19:38:24,083 INFO [(HTTP - 0.0.0.0-8443-17)]用戶xxx發佈REQUEST_CODE = wCv4cbch

任何想法?

感謝的很多

+0

即使是相同的用戶,每個獲取/釋放對都有唯一的代碼嗎? – sokin

+0

是的,即使在同一用戶上,代碼也是唯一的。 – stegada

回答

0

以下awk腳本解析日誌文件,並且執行時間增量的計算(間隔)

#!/usr/bin/awk -f 

# converts milliseconds to HH:MM:SS,mmm format 
function msecs2date(msc) { 
    h = msc/3600000 
    m = (msc%3600000)/60000 
    s = (msc%60000)/1000 
    ms = msc%1000 
    printf("%02d:%02d:%02d,%03d\n", h, m, s, ms) 
} 

# converts HH:MM:SS,mmm to milliseconds 
function date2msecs(dat) { 
    split(dat,d,":") 
    split(d[3],sx,",") 
    return d[1]*3600000 + d[2]*60000 + sx[1]*1000 + sx[2] 
} 

# parses the logfile and generates 2 space-separated columns: 
# Col.1 > displays the get/release pair REQUEST_CODE 
# Col.2 > displays the time delta between the 'get' and 'release' 
#  events for the respective REQUEST_CODE in Col.1 
BEGIN {FS=" "} 
{ 
    one = $1 
    ten = $NF 
    getline 
    if ($10 == ten){ 
     printf("%s ",ten) 
     msecs2date(date2msecs($1)-date2msecs(one)) 
    } 
} 

您可以將其保存爲使用它,例如,logdelta,然後使其可執行文件並運行它:

$ chmod +x logdelta 
$ ./logdelta logfile > outputfile 

這是輸出當你的日誌文件提取物(保存爲日誌)被送入腳本:

$ ./logdelta log 
wCv4cbch 00:00:00,006 
sZhegruu 00:00:00,007 

這個腳本做什麼,本質上,是很簡單的(檢查也是在腳本中的註釋):

它分析日誌文件裏NE-通過線使用空格爲定界符(FS=" "),獲取從該相關的一個特定的代碼(使用getline特技)兩者線的適當的令牌,然後,轉移到檢查從兩條線的請求代碼是否相等。如果他們是它首先計算在利用兩個時間戳date2msecs功能毫秒的時間差,然後這個時間差轉換回HH:MM:使用msecs2date功能SS,嗯格式,依此類推,直到日誌文件結束。

這兩個轉換器功能非常簡單,您可以在split()函數here以及here中找到更多信息。現在


,如果你要使用這個腳本生產服務器日誌文件,有一些事情值得一提:

一個 - 不能完全信任的代碼在互聯網上找到(和這也適用於這個非常腳本)

這意味着一兩件事:一次又一次的測試,通過各種角落案件像損壞的日誌文件s和其他畸形或異常,然後再採用任何解決方案(見注)。

- 性能事項

這就是我爲什麼選擇awk來執行這個腳本。爲了測試它的性能,我創建基於您提供的提取物的整天日誌文件,使用以下c++(當然,c實際上)程序:

#include <cstdio> 
#include <algorithm> // for rand() 

# creates len-sized random alphanumeric codes 
void gen_random(char* s, const int len) { 
    static const char alphanum[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 
    for (int i = 0; i < len; ++i) s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; 
    s[len] = 0; 
} 

int main(int argc, char* argv[]){ 
    char* filler="INFO [...] (http--0.0.0.0-8443-17) User xxx"; 
    char* coda="REQUEST_CODE ="; 
    char* action; 
    char gc[9]; 

    for (int i=0;i<24;i++){ 
     for (int j=0;j<60;j++){ 
      for (int k=0;k<60;k++){ 
       for (int l=0;l<1001;l=l+7){ 
        l % 2 == 0 ? (action="get", gen_random(gc,8)):(action="release", void(0)); 
        printf("%02d:%02d:%02d,%003d %s %s %s %s\n",i,j,k,l,filler,action,coda,gc); 
       }; 
       printf("%02d:%02d:%02d,999 %s release %s %s\n",i,j,k,filler,coda,gc); 
      }; 
     }; 
    }; 
    return 0; 
} 

建立這樣的:

$ g++ -o logen logen.cpp 

和運行:

$ ./logen > logfile 

它創建了一個1.1GB(12441600線)人造日誌文件:

$ head -n 4 logfile 
00:00:00,000 INFO [...] (http--0.0.0.0-8443-17) User xxx get REQUEST_CODE = fa37JncC 
00:00:00,007 INFO [...] (http--0.0.0.0-8443-17) User xxx release REQUEST_CODE = fa37JncC 
00:00:00,014 INFO [...] (http--0.0.0.0-8443-17) User xxx get REQUEST_CODE = HryDsbza 
00:00:00,021 INFO [...] (http--0.0.0.0-8443-17) User xxx release REQUEST_CODE = HryDsbza 

...

$ tail -n 4 logfile 
23:59:59,980 INFO [...] (http--0.0.0.0-8443-17) User xxx get REQUEST_CODE = AI9xRoPQ 
23:59:59,987 INFO [...] (http--0.0.0.0-8443-17) User xxx release REQUEST_CODE = AI9xRoPQ 
23:59:59,994 INFO [...] (http--0.0.0.0-8443-17) User xxx get REQUEST_CODE = LEAeMTva 
23:59:59,999 INFO [...] (http--0.0.0.0-8443-17) User xxx release REQUEST_CODE = LEAeMTva 

具有(或多或少)一個真正的日誌文件的代表尺寸。

當供給到腳本它有,性能明智的,結果如下:

$ time ./logdelta logfile > ouputfile 

real 0m35.776s 
user 0m30.364s 
sys  0m2.312s 

即〜35秒1.1 GB日誌文件,這是一個相當令人滿意的性能(在單核測試運行Xubuntu 14.04的2GB虛擬機)。

這裏也是一些樣本輸出:

$ head -n 2 outputfile 
fa37JncC 00:00:00,007 
HryDsbza 00:00:00,007 

...

$ tail -n 2 outputfile 
AI9xRoPQ 00:00:00,007 
LEAeMTva 00:00:00,005 

注:我發佈了代號爲人造日誌生成的原因是爲了鼓勵你修改它並嘗試將各種人工錯誤合併到生成的日誌文件中,以便能夠測試此腳本(原樣或與您的修改)的對應方式與其他角落案件。

0

使用grep和正則表達式,例如,如果你想記錄3分鐘間隔

grep的 「16 /月/ 2002:19:3 [1-4]」日誌文件