O que é uma boa maneira de classificar dois arquivos de log à medida que são criados?

5

Eu tenho dois scripts em execução, os quais produzem um arquivo de log. Eu gostaria de fazer um terceiro script que possa ordenar esses registros pelo registro de data e hora e mesclá-los em um arquivo à medida que eles são criados. O que é uma boa maneira de fazer isso, idealmente sem sobrescrever o arquivo constantemente?

    
por Kathy 08.06.2016 / 21:58

2 respostas

1

Se você usar tail -f para completar 2 ou mais arquivos, o comando mostrará os dados linha por linha e gerará o nome do arquivo toda vez que a origem dos dados for alterada. Usando isso, você pode escrever um script para mesclar a saída intercalada da cauda de acordo com o timestamp mantendo cada linha até ver uma linha do outro arquivo com um registro de data e hora posterior.

Por exemplo, usando dois arquivos de log padrão ( /var/log/messages e /var/log/cron ) que no meu sistema têm o mesmo formato para o registro de data e hora no início da linha (por exemplo, Jun 9 02:55:01 ), você pode fazer o seguinte: / p>

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
}'

O awk vira entre os 2 arquivos quando vê o cabeçalho ==> do arquivo da cauda. Ele mantém dados, em 4 matrizes, separadamente para cada arquivo, chamados arbitrariamente de aa e bb e numerados 0 e 1. dates contém o registro de data e hora (em segundos da época), lines mantém a linha de registro de entrada , num contém a contagem de linhas e maxes a data mais alta de um arquivo. Os dois primeiros arrays são bidimensionais indexados por arquivo (0 ou 1) e contagem de linhas retidas.

Conforme cada linha de log é lida, o registro de data e hora é convertido em segundos e salvo em uma nova entrada no final de dates , e a linha também é salva. O mínimo das duas datas atuais é definido em minmax . Todos os dados armazenados são digitalizados e impressos de acordo com a ordem de registro de data e hora até este mínimo. As entradas impressas são limpas e, no final do loop while, as matrizes são comprimidas para remover essas entradas limpas.

    
por 09.06.2016 / 21:19
0

Considerando as suposições de que os arquivos de log têm a mesma origem de registro de data e hora, que cada registro é gravado em ordem de horário no momento em que a entrada de log é criada e que o registro de data leva a linha, você pode fazer algo tão simples quanto este :

tail -qF log1 log2 > summarylog

Se as suposições não forem válidas para sua situação, atualize sua pergunta para esclarecimentos e exemplos.

    
por 21.06.2016 / 00:23

Tags