<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vítor Roque</title>
    <description>The latest articles on DEV Community by Vítor Roque (@roqueando).</description>
    <link>https://dev.to/roqueando</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F55458%2F3a02a76f-6e4a-4898-9743-f35083ad8b3a.jpeg</url>
      <title>DEV Community: Vítor Roque</title>
      <link>https://dev.to/roqueando</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roqueando"/>
    <language>en</language>
    <item>
      <title>Criando um servidor de tracing distribuído (parte 1)</title>
      <dc:creator>Vítor Roque</dc:creator>
      <pubDate>Mon, 11 Sep 2023 04:30:14 +0000</pubDate>
      <link>https://dev.to/roqueando/criando-um-servidor-de-tracing-distribuido-parte-1-1jp4</link>
      <guid>https://dev.to/roqueando/criando-um-servidor-de-tracing-distribuido-parte-1-1jp4</guid>
      <description>&lt;p&gt;Em Haskell tudo começa pelas tipagens e dados que você precisa. Primeiramente certifique-se que tenha instalado o &lt;code&gt;cabal&lt;/code&gt; ou &lt;code&gt;stack&lt;/code&gt; para criar projetos em Haskell.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando projeto
&lt;/h3&gt;

&lt;p&gt;Para criar o projeto é simples&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cabal init &lt;span class="nt"&gt;-n&lt;/span&gt; tracer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O cabal irá criar um projeto de modo interativo (bem como o &lt;code&gt;npm init&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos e dados
&lt;/h3&gt;

&lt;p&gt;Primeiro precisamos definir o que será cada coisa, os componentes e a implementação.&lt;/p&gt;

&lt;p&gt;Na estrutura temos o que chamaremos de ISO ou EDIO (Estrutura de instrumentação da observabilidade) que é nada mais que um mapa chave-valor, onde a chave é a ação originária e o valor é a uma lista de ações possíveis (ou ações alvos possíveis).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Instrumentation&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;newtype&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;])]&lt;/span&gt; &lt;span class="kr"&gt;deriving&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Eq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Map, bem utilizado em outras linguagens, se resume a uma lista de tuplas com apenas 2 valores, a chave e o valor em si. E pra isso teremos que criar algumas funções auxiliares para inserir, procurar ou deletar entradas nesse mapa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Funções auxiliares
&lt;/h3&gt;

&lt;p&gt;No caso, por agora, precisamos ter uma função para criar um ISO vazio e um para inserir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;newISO&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt;
&lt;span class="n"&gt;newISO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função de criação é bem simples pois só precisamos ter uma função que usa o método construtor &lt;code&gt;ISO&lt;/code&gt; com uma lista vazia.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt;
&lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="n"&gt;newIso&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;newIso&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função de inserção seria apenas a concatenação da lista anterior com uma lista nova. Em Haskell, podemos ter N formas de criar essa função, usei a notação &lt;code&gt;where&lt;/code&gt;, pois ela nos dá uma forma mais fácil de compreender o que é cada parte da função. Nesse caso eu separei a concatenação de listas numa variável desse &lt;code&gt;where&lt;/code&gt; para facilitar a legibilidade da função em si.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testes, pois sem testes não viveríamos
&lt;/h3&gt;

&lt;p&gt;Em Haskell, testes são feitos por, acredite ou não, funções! Essas funções podem ser escritas de várias maneiras mas aqui usarei o mais comum na comunidade, que é o HUnit.&lt;/p&gt;

&lt;p&gt;Primeiro nós instalamos o HUnit pelo cabal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cabal &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--lib&lt;/span&gt; HUnit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E precisamos alterar no nosso arquivo &lt;code&gt;tracer.cabal&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test-suite tracer-test
    import:           warnings
    default-language: Haskell2010
    type:             exitcode-stdio-1.0
    hs-source-dirs:   test
    main-is:          Main.hs
    other-modules:    InstrumentationTest -- novo
    build-depends:
        base ^&amp;gt;=4.18.0.0,
        tracer,
        HUnit -- novo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse arquivo adicionamos um novo módulo além do Main que o cabal cria para nós, e o que depende do build desse teste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teste da estrutura ISO
&lt;/h2&gt;

&lt;p&gt;Com isso precisamos criar os testes nesse arquivo &lt;code&gt;test/InstrumentationTest.hs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;InstrumentationTest&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Instrumentation&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;newISO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Test.HUnit&lt;/span&gt;

&lt;span class="n"&gt;createNewISOTest&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Test&lt;/span&gt;
&lt;span class="n"&gt;createNewISOTest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;TestCase&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assertEqual&lt;/span&gt; &lt;span class="s"&gt;"should return empty ISO"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;newISO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;insertEntryTest&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Test&lt;/span&gt;
&lt;span class="n"&gt;insertEntryTest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;TestCase&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assertEqual&lt;/span&gt; &lt;span class="s"&gt;"should return a ISO with entry"&lt;/span&gt; &lt;span class="n"&gt;desired&lt;/span&gt; &lt;span class="n"&gt;appliedFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="kr"&gt;where&lt;/span&gt;
     &lt;span class="n"&gt;desired&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ISO&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s"&gt;"chave"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"valor1"&lt;/span&gt;&lt;span class="p"&gt;])]&lt;/span&gt;
     &lt;span class="n"&gt;appliedFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"chave"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"valor1"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="n"&gt;newISO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse arquivo criamos tanto o teste para checar a criação de uma nova ISO e a inserção de uma entrada. E agora precisamos colocar ele no arquivo &lt;code&gt;test/Main.hs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;

&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Test.HUnit&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;InstrumentationTest&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;createNewISOTest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;insertEntryTest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="k"&gt;qualified&lt;/span&gt; &lt;span class="nn"&gt;System.Exit&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;Exit&lt;/span&gt;

&lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Test&lt;/span&gt;
&lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;TestList&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;TestLabel&lt;/span&gt; &lt;span class="s"&gt;"createNewISO"&lt;/span&gt; &lt;span class="n"&gt;createNewISOTest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;TestLabel&lt;/span&gt; &lt;span class="s"&gt;"insertEntryTest"&lt;/span&gt; &lt;span class="n"&gt;insertEntryTest&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;runTestTT&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;
  &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;failures&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="kt"&gt;Exit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exitFailure&lt;/span&gt; &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="kt"&gt;Exit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exitSuccess&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse arquivo nós criamos uma suite de testes para que ele rode todos os testes do módulo &lt;code&gt;InstrumentationTest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para rodar os testes apenas rodamos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cabal &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E ele terá um resultado parecido com esse (além dos logs de build)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Test suite eyaara-test: RUNNING...
Cases: 2  Tried: 2  Errors: 0  Failures: 0
Test suite tracer-test: PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por hoje é só! Nessa série de artigos eu irei recriar o sistema e estrutura que desenvolvi baseado no algoritmo Drain para parsing de logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  O ṣeun! 👋🏾
&lt;/h2&gt;

</description>
      <category>haskell</category>
      <category>webdev</category>
      <category>cybertank</category>
      <category>programming</category>
    </item>
    <item>
      <title>Criando um monitor de logs em Go - parte 1</title>
      <dc:creator>Vítor Roque</dc:creator>
      <pubDate>Thu, 20 Apr 2023 21:49:30 +0000</pubDate>
      <link>https://dev.to/roqueando/criando-um-monitor-de-logs-em-go-parte-1-1ml9</link>
      <guid>https://dev.to/roqueando/criando-um-monitor-de-logs-em-go-parte-1-1ml9</guid>
      <description>&lt;p&gt;Esse é um post onde vou mostrar como eu desenvolvi esse monitor de logs, que você pode estar acompanhando nesse &lt;a href="//github.com/roqueando/oluwoye"&gt;repositório&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocolo AWO e Parser
&lt;/h2&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOG abc@123 AWO1.1
02:30:22
This is my LOG message content!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;
  &lt;span class="n"&gt;Timer&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
  &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Verb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AppKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validando o Header
&lt;/h2&gt;

&lt;p&gt;Precisamos também criar um construtor para esse Header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"malformed header"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;verb&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;app_key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Verb&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;verb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AppKey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;app_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 &lt;code&gt;app_key&lt;/code&gt; ou se o &lt;code&gt;verb&lt;/code&gt; não faz parte dos verbos do protocolo que estamos criando (o que implementarei mais para frente).&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando a função Parse
&lt;/h2&gt;

&lt;p&gt;Agora que tenho o Header com sua validação preciso transformar a mensagem numa estrutura.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"malformed packet"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header_error&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;NewHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;header_error&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;header_error&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"timer is empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

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

&lt;p&gt;Por fim, coloco ele numa estrutura Log como já definido e o retorno.&lt;/p&gt;

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

&lt;p&gt;O ṣeun, e até a próxima!&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
