2015-09-16 73 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]”日志文件