paint-brush
Análise de log eficiente: aproveitando o poder do Regex com BindPlane OP e OpenTelemetrypor@observiq
469 leituras
469 leituras

Análise de log eficiente: aproveitando o poder do Regex com BindPlane OP e OpenTelemetry

por observIQ6m2023/06/02
Read on Terminal Reader

Muito longo; Para ler

A análise de logs com regex é uma técnica valiosa para extrair informações essenciais de grandes volumes de dados de log. Ao empregar esse método, pode-se identificar com eficiência padrões, erros e outros insights importantes, simplificando a análise de log e aprimorando o desempenho do sistema. Nesta postagem, examinaremos as entradas de log que se assemelham aos exemplos fornecidos abaixo.
featured image - Análise de log eficiente: aproveitando o poder do Regex com BindPlane OP e OpenTelemetry
observIQ HackerNoon profile picture


A análise de logs com regex é uma técnica valiosa para extrair informações essenciais de grandes volumes de dados de log. Ao empregar esse método, pode-se identificar com eficiência padrões, erros e outros insights importantes, simplificando a análise de log e aprimorando o desempenho do sistema.


Pré-requisitos

  • BindPlane OP e um Agente BindPlane (Coletor OpenTelemetry Personalizado)

  • Um arquivo de log complexo que precisa de análise personalizada

  • Conhecimento de Regex

  • Uma seleção de amostras de log que correspondem a todas as variações possíveis.

  • (Opcional) Uma boa ferramenta de teste de regex, como regex101.com


Amostras de dados de registro complexos

Nesta postagem, examinaremos entradas de log semelhantes aos exemplos fornecidos abaixo. Ao utilizar um script para gravar essas entradas em um arquivo com os registros de data e hora atuais, podemos trabalhar efetivamente com dados em tempo real.


 May 01 14:31:11 loggen-app10 test-system[712]: Mon May 01 14:31:11 UTC 2023|TEST_PROC|[result=Service Access Granted,service=https://portal.fakeuni.edu/uPortal/Login?...,requiredAttributes={}]|SERVICE_ACCESS_ENFORCEMENT_TRIGGERED|camillec1997|172.13.49.165|172.16.156.55 May 01 14:31:11 loggen-app10 test-system[712]: Mon May 01 14:31:11 UTC 2023|TEST_PROC|[result=Service Access Granted,service=https://portal.fakeuni.edu/uPortal/Login?...,requiredAttributes={}]|SERVICE_ACCESS_ENFORCEMENT_TRIGGERED|camillec1997|172.13.49.165|172.16.156.55 May 01 14:31:11 loggen-app10 test-system[712]: Mon May 01 14:31:11 UTC 2023|TEST_PROC|[event=success,timestamp=May 01 14:31:11 UTC 2023,source=RankedMultifactorAuthenticationProviderWebflowEventResolver]|AUTHENTICATION_EVENT_TRIGGERED|audit:unknown|172.25.178.6|172.16.156.55 May 01 14:31:11 loggen-app08 test-system[780]: Mon May 01 14:31:11 UTC 2023|TEST_PROC|Supplied credentials: [UsernamePasswordCredential(username=dawsonb, source=null, customFields={})]|AUTHENTICATION_SUCCESS|dawsonb|172.12.154.117|172.16.156.53 May 01 14:31:11 loggen-app10 test-system[712]: Mon May 01 14:31:11 UTC 2023|TEST_PROC|[event=success,timestamp=May 01 14:31:11 UTC 2023,source=RankedMultifactorAuthenticationProviderWebflowEventResolver]|AUTHENTICATION_EVENT_TRIGGERED|audit:unknown|172.25.178.6|172.16.156.55

Dissecando os dados

Agora podemos pegar a primeira entrada de log acima e começar a dissecá-la em seções que desejamos analisar.


Primeiro, notamos que temos dois timestamps:


**May 01 14:31:11** loggen-app10 test-system[712]: **Mon May 01 14:31:11 UTC 2023**|TEST_PROC|[result=Service Access Granted,service=https://portal.fakeuni.edu/uPortal/Login?...,requiredAttributes={}]|SERVICE_ACCESS_ENFORCEMENT_TRIGGERED|camillec1997|172.13.49.165|172.16.156.55


O segundo registro de data e hora é aquele que preservaremos para se tornar nosso registro de data e hora oficial porque contém mais informações (fuso horário e ano são úteis, enquanto o dia da semana não é realmente) que podemos usar para obter a maior precisão.


Analisando isso, escreveremos um padrão de não captura para corresponder ao primeiro carimbo de data/hora.

^\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s+The caret “^” no início da linha. Isso é seguido por “ \w{3} ”, que captura a abreviação de 3 letras do mês. Após o mês, fica “ \s\d{2}\s ”, que é para capturar um espaço; os 2 dígitos, 0 dias preenchidos do mês; e outro espaço. Finalmente, temos “ \d{2}:\d{2}:\d{2}\s+ ” – para hora com 2 dígitos, minuto com 2 dígitos, segundo com 2 dígitos e 1 ou mais espaços.


Para o segundo timestamp, queremos um grupo de captura nomeado. Isso se tornará um campo nomeado no blob JSON de campos analisados.


(?P<timestamp>\w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\d{4})


Chamamos esse grupo de captura de “carimbo de data/hora”. Ele contém o mesmo regex básico que o outro timestamp, com a adição de “ \w{3}\s ” no início para capturar o dia abreviado da semana e “ \s\w{3}\s\d{4} ” substituindo o “ \s+ ” no final para capturar o fuso horário de 3 caracteres e o ano de 4 dígitos.





Indo mais longe na mensagem de log, queremos analisar o nome do host e o sistema:


May 01 14:31:11 **loggen-app10 test-system[712]**: Mon May 01 14:31:11 UTC 2023|TEST_PROC|[result=Service Access Granted,service=https://portal.fakeuni.edu/uPortal/Login?...,requiredAttributes={}]|SERVICE_ACCESS_ENFORCEMENT_TRIGGERED|camillec1997|172.13.49.165|172.16.156.55


Nesta mensagem, nosso nome de host é **loggen-app10** e nosso sistema é **test-system[712]** . Não me disseram o que era o [712] quando recebi esses logs. Presumi que fosse o PID (ID do processo), mas optei por não analisá-lo separadamente por enquanto. A análise desses campos é bastante simples e terminamos com: “ (?P<hostname>[^\s]+)\s+(?P<system>.*?):\s+ ”. Temos um par de grupos de captura nomeados, nome de host e sistema.


O padrão para o nome do host é “ [^\s]+ ”, que diz capturar qualquer caractere que não seja espaço e capturar o máximo possível (ganancioso). Isso é seguido por “ \s+ ”, que captura pelo menos um, mas o máximo possível (novamente ganancioso) de espaço(s).


O grupo de captura para o sistema é ainda mais fácil porque após o(s) espaço(s) capturamos tudo até dois pontos. Para fazer isso, usamos “ .*? ”. O que esse padrão diz é capturar qualquer caractere 0 ou mais vezes, mas não seja ganancioso.


Depois disso, temos o caractere de dois pontos e mais 1 ou mais espaços gananciosos. Eles não são capturados, mas são necessários para preencher entre esta seção e a seção de registro de data e hora que escrevemos acima.





Isso resulta no seguinte padrão inicial:


^\w{3}\s*\d{2}\s*\d{2}:\d{2}:\d{2}\s+(?P<hostname>[^\s]+)\s+(?P<system>.*?):\s+(?P<timestamp>\w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\d{4})


Não vou passar por todo o processo de criação do padrão, mas continuo a dividi-lo como fiz acima.


O padrão final resultante é:


^\w{3}\s*\d{2}\s*\d{2}:\d{2}:\d{2}\s+(?P<hostname>[^\s]+)\s+(?P<system>.*?):\s+(?P<timestamp>\w{3}\s\w{3}\s\d{2}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\d{4})\|(?P<app_name>\w*)\|((?P<message_type>.*?):\s+)?\[?(?P<message>.*)\]?\|(?P<event_message>.*?)\|(?P<username>.*?)\|(?P<external_ip>[\d\.:]*)\|(?P<internal_ip>[\d\.:]*)


Esse padrão final inclui os seguintes grupos de captura nomeados, que se tornam campos em nosso blob JSON de dados analisados:


  • nome de anfitrião
  • sistema
  • carimbo de data/hora
  • nome do aplicativo
  • tipo de mensagem
  • mensagem
  • mensagem_evento
  • nome de usuário
  • ip_externo
  • ip_interno




Implementando o Regex

No BindPlane, crio uma fonte de arquivo. Isso examina meu arquivo de log gerado em /root/complex.log. Selecionei regex em Formato de análise. Sob o padrão Regex, coloquei o padrão final acima. Eu marquei a caixa para Parse Timestamp, escolhi Manual para o formato e coloquei os códigos de análise de tempo para o padrão do meu timestamp.


Feito isso, fica assim:



Enviando e verificando os dados

Para concluir o teste, preciso criar um destino e verificar os dados lá. Para meu caso de uso, escolhi um destino do Google Cloud Logging.


Depois que minha configuração de pipeline é concluída, eu a anexo a um agente. Após a execução por alguns instantes, clico no botão "Exibir botão de telemetria recente" na página do agente




A exibição de telemetria me mostra o seguinte log analisado:



Por fim, verifico também no console do Google Cloud Logging:





Isso exibe a mesma entrada de log e tem uma carga JSON do objeto de mapa JSON do nosso corpo da exibição de telemetria recente.


Próximos passos

Para as próximas etapas, gostaria de examinar a análise desse valor de mensagem. Frequentemente é um conjunto de chave/valor; como nas capturas de tela e amostras acima. Eu poderia passar os dados para um processador que analisa essas entradas de chave/valor em outra camada de JSON. No exemplo acima, body.message seria analisado de volta em si mesmo e você poderia ter campos como:


 body.message.result=Service Access Granted body.message.service=https://innosoftfusiongo.com/sso/logi… body.message.principal=SimplePrincipal(id=dawsonb, attributes={mail=[[email protected]], eduPersonAffiliation=[Staff], ou=[Recreation/Student Rec Center], givenName=[Dawson], cn=[Dawson Branden], title=[Asst. Director], employeeNumber=[5000000], o=[Vice ChancellorStudent Affairs], fakeuniOrg=[Vice ChancellorStudent Affairs], casMFARequired=[YES], uid=[dawsonb], eduPersonPrimaryAffiliation=[Staff], fakeuniCid=[5000000], fakeuniSeparationDate=[99991231000000Z], UDC_IDENTIFIER=[dawsonb], sn=[Branden], organizationalStatus=[Staff]}) body.message.requiredAttributes=””


Mesmo isso poderia ser analisado ainda mais, colocando body.message.principle através de um analisador de chave/valor também.


Agora, alguém certamente se perguntará: "Por que você simplesmente não usou a análise regex dos subcampos body.message também?" A resposta: é muito inconsistente. O regex seria incrivelmente e excessivamente complexo quando já temos a capacidade de analisar pares de chave/valor.


Conclusão

Muitas formas de dados podem ser encontradas em arquivos de log. Esses dados geralmente precisam ser analisados para torná-los mais facilmente legíveis para os humanos e mais fáceis para automação e ferramentas mais tarde na cadeia para agir.


Embora o exemplo com o qual trabalhei tenha sido executado em um log de arquivo simples, as técnicas aqui contidas podem ser usadas em qualquer fluxo de log. Além da análise de regex, o BindPlane também suporta JSON ,XML , pares chave/valor e valores separados por caracteres. Com o uso de processadores, esses analisadores podem ser encadeados para analisar dados incorporados e manipulá-los em um formato utilizável.


Também publicado aqui.