Eu tenho várias entradas que descrevem um evento em um arquivo de log muito grande, digamos A.log . Eu gostaria de fazer duas coisas com as entradas de eventos no arquivo de log:
- Conte o número de ocorrências de cada uma dessas entradas (esse não é um requisito obrigatório, mas seria bom ter).
- Extraia as entradas reais em um arquivo separado e estude-as posteriormente.
Uma entrada típica de evento teria a seguinte aparência e terá outros textos entre eles. Portanto, no exemplo abaixo, existem duas entradas de eventos , a primeira contendo duas DataChangeEntry
cargas úteis e a segunda contendo uma DataChangeEntry
carga útil.
Data control raising event :DataControl@263c015d[[
#### DataChangeEvent #### on [DataControl name=PatternMatch_LegendTimeAxis, binding=.dynamicRegion1. beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxisPageDef_beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxis_xml_ps_taskflowid.dynamicRegion58. beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxisPageDef_beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxis_xml_ps_taskflowid.QueryIterator]
Filter/Collection Id : 0
Collection Level : 0
Sequence Id : 616
ViewSetId : PatternMatch.LegendTimeAxis_V1_0_SN49
==== DataChangeEntry (#1)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 11, StrAvgCallWaitTimeGreaterThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
==== DataChangeEntry (#2)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 9, AverageCallWaitingTimeGreateThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
]]
someother non useful text
spanning multiple lines
Data control raising event :DataControl@263c015d[[
#### DataChangeEvent #### on [DataControl name=PatternMatch_LegendTimeAxis, binding=.dynamicRegion1. beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxisPageDef_beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxis_xml_ps_taskflowid.dynamicRegion58. beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxisPageDef_beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxis_xml_ps_taskflowid.QueryIterator]
Filter/Collection Id : 0
Collection Level : 0
Sequence Id : 616
ViewSetId : PatternMatch.LegendTimeAxis_V1_0_SN49
==== DataChangeEntry (#1)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 11, StrAvgCallWaitTimeGreaterThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
]]
Observe que o número de ==== DataChangeEntry
linhas em uma entrada de evento pode ser variável. Também pode estar completamente ausente, o que indicaria carga útil de eventos vazios e é uma condição de erro e, definitivamente, também gostaria de capturar esse caso.
Como nesse caso a saída da entrada se estende por várias linhas, não estou indo muito longe usando o plain vanilla grep. Então, eu estou procurando aconselhamento especializado.
PS:
- Deixe-me ser mais explícito sobre minha exigência. Gostaria de capturar todo o bloco de texto mostrado acima literalmente e, opcionalmente, contar o número de instâncias desses blocos encontrados. É bom ter a opção de contar o número de instâncias, mas não um requisito obrigatório.
- Se a solução para o problema estiver usando o awk, eu gostaria de salvar o arquivo awk e reutilizá-lo. Portanto, mencione as etapas para executar o script também. Eu sei regex e grep, mas não estou familiarizado com sed e / ou awk.
fonte
Data control raising event
?Respostas:
Isso faria isso, espero. Os eventos vão para o
events
arquivo. E as mensagens vão para stdout.Salve este arquivo em myprogram.awk (por exemplo):
Você pode invocá-lo de diferentes maneiras:
myprogram.awk inputfile.txt
awk -f myprogram.awk inputfile.txt
Saída de amostra:
Você pode verificar todos os eventos juntos no arquivo chamado
events
no diretório de trabalho.fonte
awk -f findEvents.awk A.log
:?Uma abordagem muito simples seria
Isso criará um arquivo separado para cada entrada e imprimirá o número de entradas encontradas na saída padrão.
Explicação
NR
é o número da linha atual emawk
.RS="]]"
define o separador de registros (o que define uma "linha") como]]
. Isso significa que cada entrada será tratada como uma única linha porawk
.{print > NR".entry"}
: imprime a linha atual (entrada) em um arquivo chamado[LineNumber].entry
. Então,1.entry
conterá o primeiro,2.entry
o segundo e assim por diante.END{print NR" entries"}
: o bloco END é executado após todo o arquivo de entrada ter sido processado. Portanto, nesse pontoNR
, será o número de entradas processadas.Você pode salvar isso como um alias ou transformá-lo em um script como este:
Você executaria o script (assumindo que ele seja chamado
foo.sh
e esteja no seu $ PATH) com o arquivo de destino como argumento:Você também pode ajustar os nomes dos arquivos de saída. Por exemplo, para que os arquivos sejam chamados,
[date].[entry number].[entry]
use isso:O acima pressupõe que seu arquivo de log consiste exclusivamente em entradas "Evento". Se esse não for o caso, e você pode ter outras linhas, e essas linhas devem ser ignoradas, use isso:
Ou, como uma linha:
fonte