Criando um monitor de logs em Go - parte 1

roqueando

Vítor Roque

Posted on April 20, 2023

Criando um monitor de logs em Go - parte 1

Esse é um post onde vou mostrar como eu desenvolvi esse monitor de logs, que você pode estar acompanhando nesse repositório.

Protocolo AWO e Parser

Eu precisava de uma estrutura para esse protocolo, como seria uma aplicação que muitas apps podem utilizar essa estrutura precisava de um padrão. Segue um exemplo:

LOG abc@123 AWO1.1
02:30:22
This is my LOG message content!
Enter fullscreen mode Exit fullscreen mode

Como todo protocolo em cima do TCP, tudo isso é um texto, então eu precisava converte-lo em alguma estrutura.

Em Go, criei um parser para tratar todo tipo de mensagem que enviarem para a aplicação. Caso ele não siga esse padrão, um erro deve ser gerado.

type Log struct {
  Header Header
  Timer string
  Message string
}

type Header struct {
  Verb, AppKey, Version string
}
Enter fullscreen mode Exit fullscreen mode

Essas estruturas serão a base da mensagem, onde Header tem sua verificação, pois se algo estiver errado antes da validação, não queremos receber a mensagem.

Validando o Header

Precisamos também criar um construtor para esse Header.

func NewHeader(head string) (Header, error) {
        parts := strings.Split(head, " ")
        if len(parts) != 3 {
                return Header{}, errors.New("malformed header")
        }

        verb := parts[0]
        app_key := parts[1]
        version := parts[2]

        return Header{Verb: verb, AppKey: app_key, Version: version}, nil
}
Enter fullscreen mode Exit fullscreen mode

Aqui apenas divido o header em 3 pelo whitespace, e caso ele venha mais ou venha menos partes, ele está errado. Aqui também poderia adicionar alguma forma de validação da app_key ou se o verb não faz parte dos verbos do protocolo que estamos criando (o que implementarei mais para frente).

Criando a função Parse

Agora que tenho o Header com sua validação preciso transformar a mensagem numa estrutura.

func Parse(packet string) (Log, error) {
        parts := strings.Split(packet, "\n")
        if len(parts) != 3 {
                return Log{}, errors.New("malformed packet")
        }

        header, header_error := NewHeader(parts[0])

        if header_error != nil {
                return Log{}, header_error
        }

        timer := parts[1]
        if timer == "" {
                return Log{}, errors.New("timer is empty")
        }
        message := parts[2]

        return Log{
                Header:  header,
                Timer:   timer,
                Message: message,
        }, nil

}
Enter fullscreen mode Exit fullscreen mode

Esse parser irá validar se a mensagem tem também 3 partes, pois só tenho a estrutura: Header, Timer e Message. Então caso não siga isso, irei trata-lo como inválido.

Logo depois crio o Header e também checo se o timer está vazio ou não, pois preciso do tempo que esse log chegou na aplicação.

Por fim, coloco ele numa estrutura Log como já definido e o retorno.

Na próxima publicação sobre esse projeto irei abordar como criei o sistema de regras para a monitoração customizada usando o Oluwoye.

O ṣeun, e até a próxima!

💖 💪 🙅 🚩
roqueando
Vítor Roque

Posted on April 20, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related