在创建两个日志文件时对其进行排序的好方法是什么?

在创建两个日志文件时对其进行排序的好方法是什么?

我正在运行两个脚本,它们都输出一个日志文件。我想制作第三个脚本,它可以按时间戳对这些日志进行排序,并在创建它们时将它们合并到一个文件中。有什么好方法可以做到这一点,最好不要不断覆盖文件?

答案1

如果您使用tail -ftail 2 个或更多文件,则该命令将逐行显示数据,并在每次数据源更改时输出文件名。使用此功能,您可以编写一个脚本,通过保留每一行,根据时间戳合并来自 tail 的交错输出,直到看到另一个文件中具有较晚时间戳的行。

例如,使用两个标准日志文件(/var/log/messages/var/log/cron),它们在我的系统上具有相同的行开头时间戳格式(例如Jun 9 02:55:01),您可以执行以下操作:

tail -f /var/log/messages /var/log/cron |
awk '
BEGIN { num[0] = 0; num[1] = 0; }
/^==> /{
  file = $2; aa = file~/messages/?0:1; bb = 1-aa; 
  aanum = num[aa]; bbnum = num[bb];
  next }
/^$/{ next }
{ "date --date \"" $1 " " $2 " " $3 "\" +%s" | getline date
  lines[aa,aanum] = $0
  dates[aa,aanum++] = date
  maxes[aa] = date
  minmax = maxes[aa]
  if(maxes[bb]<minmax)minmax = maxes[bb]

  i = 0; j = 0;
  while(1){
    aaok = (i<aanum && dates[aa,i]<=minmax)
    bbok = (j<bbnum && dates[bb,j]<=minmax)
    if(aaok && bbok){
      if(dates[aa,i]<=dates[bb,j]){
           print lines[aa,i]; dates[aa,i++] = ""
      }else{
           print lines[bb,j]; dates[bb,j++] = ""
      }
    }else if(aaok){
           print lines[aa,i]; dates[aa,i++] = ""
    }else if(bbok){
           print lines[bb,j]; dates[bb,j++] = ""
    }else break
  }
  i = 0
  for(j = 0; j<aanum;j++)
    if(dates[aa,j]!=""){
      dates[aa,i] = dates[aa,j]; lines[aa,i++] = lines[aa,j]
    }
  aanum = num[aa] = i
  i = 0
  for(j = 0; j<bbnum;j++)
    if(dates[bb,j]!=""){
      dates[bb,i] = dates[bb,j]; lines[bb,i++] = lines[bb,j]
    }
  bbnum = num[bb] = i
}'

当 awk 看到文件头从尾部开始时,它会在两个文件之间翻转==>。它将数据保存在 4 个数组中,分别为每个文件,任意调用aaandbb并编号为 0 和 1。dates保存时间戳(以从纪元开始的秒数为单位),lines保存输入日志行,num保存行数以及maxes最高日期一份文件。前 2 个数组是按文件(0 或 1)和保留行数进行二维索引的。

读取每个日志行时,时间戳会转换为秒,并保存在 末尾的新条目中dates,并且该行也会被保存。当前两个日期中的最小值设置在 中minmax。根据时间戳顺序扫描并打印整个保存的数据,直至达到该最小值。打印的条目被清除,并且在 while 循环结束时,数组被压缩以删除这些清除的条目。

答案2

假设日志文件具有相同的时间戳源,每个日志都是在创建日志条目时按时间顺序写入的,并且时间戳领先,您可以执行如下简单的操作:

tail -qF log1 log2 > summarylog

如果这些假设不适合您的情况,请更新您的问题以提供说明和示例。

相关内容