<?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>Forem: Rafa Mori</title>
    <description>The latest articles on Forem by Rafa Mori (@rafa_mori).</description>
    <link>https://forem.com/rafa_mori</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%2F2602953%2F0ac2039b-2121-446a-b72f-fc9ed0950dfa.jpg</url>
      <title>Forem: Rafa Mori</title>
      <link>https://forem.com/rafa_mori</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rafa_mori"/>
    <language>en</language>
    <item>
      <title>🚀 LookAtni File Markers — Invisible Markers to Structure Your Files Like Magic</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Sun, 13 Jul 2025 04:33:32 +0000</pubDate>
      <link>https://forem.com/rafa_mori/lookatni-file-markers-invisible-markers-to-structure-your-files-like-magic-mfl</link>
      <guid>https://forem.com/rafa_mori/lookatni-file-markers-invisible-markers-to-structure-your-files-like-magic-mfl</guid>
      <description>&lt;p&gt;Have you ever needed to extract specific parts of code to create a tutorial, technical documentation, or even educational content?&lt;/p&gt;

&lt;p&gt;What if you could do this &lt;strong&gt;by marking directly in the file itself&lt;/strong&gt;, without breaking your workflow, and even &lt;strong&gt;automate the extraction&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Allow me to introduce &lt;strong&gt;LookAtni File Markers&lt;/strong&gt; — a VSCode extension that gives you superpowers using just comments!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 How it works
&lt;/h2&gt;

&lt;p&gt;You mark blocks using a simple, visual syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//␜/ docs/start.md /␜//&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension recognizes this as a “visual marker.” It lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate through these points as if they were anchors in VSCode&lt;/li&gt;
&lt;li&gt;Extract the marked blocks to external files&lt;/li&gt;
&lt;li&gt;Validate, reorder, synchronize… all automatically&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📸 See it in action
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Frafa-mori%2Flookatni-file-markers%2Frefs%2Fheads%2Fmain%2Fdocs%2Fdemo%2Fdemo_md.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Frafa-mori%2Flookatni-file-markers%2Frefs%2Fheads%2Fmain%2Fdocs%2Fdemo%2Fdemo_md.gif" alt="LookAtni Demo" width="720" height="392"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 Use cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📘 Technical documentation&lt;/strong&gt; — extract snippets directly from code to keep examples always updated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;👨‍🏫 Educational content&lt;/strong&gt; — assemble lessons, tutorials, and PDF materials from live code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Code reviews&lt;/strong&gt; — mark crucial points for reviewers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⚙️ CI/CD pipelines&lt;/strong&gt; — use markers to generate temporary files or validate structure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Built-in CLI (coming soon)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lookatni extract src/
lookatni validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for integration with GitHub Actions or build pipelines.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Install now
&lt;/h2&gt;

&lt;p&gt;Get it from the &lt;a href="https://marketplace.visualstudio.com/items?itemName=rafa-mori.lookatni-file-markers" rel="noopener noreferrer"&gt;VSCode Marketplace&lt;/a&gt; or via the Command Palette:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ext &lt;span class="nb"&gt;install &lt;/span&gt;rafa-mori.lookatni-file-markers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ❤️ Open Source
&lt;/h2&gt;

&lt;p&gt;This project is fully open source:&lt;br&gt;
&lt;a href="https://github.com/rafa-mori/lookatni-file-markers" rel="noopener noreferrer"&gt;https://github.com/rafa-mori/lookatni-file-markers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you enjoy it, please ⭐ the repo and share any feedback—you’re more than welcome!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Create living structure within your files.&lt;br&gt;
Mark. Extract. Automate.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>vscode</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 LookAtni File Markers — Marcadores invisíveis para estruturar seus arquivos como mágica</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Sun, 13 Jul 2025 04:26:50 +0000</pubDate>
      <link>https://forem.com/rafa_mori/lookatni-file-markers-marcadores-invisiveis-para-estruturar-seus-arquivos-como-magica-3jm2</link>
      <guid>https://forem.com/rafa_mori/lookatni-file-markers-marcadores-invisiveis-para-estruturar-seus-arquivos-como-magica-3jm2</guid>
      <description>&lt;p&gt;Já precisou extrair partes específicas de um código para criar um tutorial, uma documentação técnica ou até um conteúdo didático?&lt;/p&gt;

&lt;p&gt;E se você pudesse fazer isso &lt;strong&gt;marcando diretamente no próprio arquivo&lt;/strong&gt;, sem quebrar o fluxo de trabalho, e ainda &lt;strong&gt;automatizar a extração&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Apresento o &lt;strong&gt;LookAtni File Markers&lt;/strong&gt; — uma extensão do VSCode que te dá superpoderes usando apenas comentários!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Como funciona?
&lt;/h2&gt;

&lt;p&gt;Você marca blocos com uma sintaxe simples e visual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//␜/ docs/inicio.md /␜//&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;E a extensão reconhece isso como um “marcador visual”.&lt;br&gt;
Ela permite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navegar por esses pontos como se fossem âncoras no VSCode&lt;/li&gt;
&lt;li&gt;Extrair os blocos marcados para arquivos externos&lt;/li&gt;
&lt;li&gt;Validar, reordenar, sincronizar… tudo automaticamente&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📸 Veja em ação
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Frafa-mori%2Flookatni-file-markers%2Frefs%2Fheads%2Fmain%2Fdocs%2Fdemo%2Fdemo_md.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Frafa-mori%2Flookatni-file-markers%2Frefs%2Fheads%2Fmain%2Fdocs%2Fdemo%2Fdemo_md.gif" alt="LookAtni Demo" width="720" height="392"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 Casos de uso
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📘 Documentação técnica&lt;/strong&gt; — extraia trechos direto do código para manter exemplos sempre atualizados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;👨‍🏫 Conteúdo educacional&lt;/strong&gt; — monte aulas, tutoriais e PDFs com base em código vivo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Revisões de código&lt;/strong&gt; — marque pontos importantes para revisores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⚙️ CI/CD pipelines&lt;/strong&gt; — use markers para gerar arquivos temporários ou validar estrutura&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 CLI embutido (em breve)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
lookatni extract src/&lt;br&gt;
lookatni validate&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ideal pra integrar com GitHub Actions ou ferramentas de build.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Instale agora
&lt;/h2&gt;

&lt;p&gt;Acesse o &lt;a href="https://marketplace.visualstudio.com/items?itemName=rafa-mori.lookatni-file-markers" rel="noopener noreferrer"&gt;Marketplace do VSCode&lt;/a&gt; ou via Command Palette:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
ext install rafa-mori.lookatni-file-markers&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ❤️ Open Source
&lt;/h2&gt;

&lt;p&gt;O projeto é totalmente open source:&lt;br&gt;
&lt;a href="https://github.com/rafa-mori/lookatni-file-markers" rel="noopener noreferrer"&gt;https://github.com/rafa-mori/lookatni-file-markers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você curtir, ⭐️ no repositório e feedbacks são mais que bem-vindos!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Crie uma estrutura viva dentro dos seus arquivos.&lt;br&gt;
Marque. Extraia. Automatize.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>vscode</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 Ollama Dev Stack: WebUI + Benchmark + Docker + Fallback (Open Source)</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Fri, 20 Jun 2025 17:45:09 +0000</pubDate>
      <link>https://forem.com/rafa_mori/ollama-dev-stack-webui-benchmark-docker-fallback-open-source-294</link>
      <guid>https://forem.com/rafa_mori/ollama-dev-stack-webui-benchmark-docker-fallback-open-source-294</guid>
      <description>&lt;h2&gt;
  
  
  Um ambiente local completo para rodar LLMs como &lt;code&gt;deepseek-coder&lt;/code&gt; e &lt;code&gt;mistral&lt;/code&gt; com Docker, Open-WebUI, benchmarks automáticos, fallback inteligente e uma DX otimizada via Makefile ou script Bash — tudo open source, tudo fácil de estender!
&lt;/h2&gt;




&lt;h2&gt;
  
  
  🧠 Por que criei isso?
&lt;/h2&gt;

&lt;p&gt;Eu queria um ambiente de IA local que fosse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💡 Simples de iniciar (&lt;code&gt;make dev&lt;/code&gt; ou &lt;code&gt;setup-dev.sh&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🔁 Resiliente (reinicia containers com falha automaticamente)&lt;/li&gt;
&lt;li&gt;🧪 Benchmarkado (testa o tempo de resposta logo após subir)&lt;/li&gt;
&lt;li&gt;🐳 Totalmente Dockerizado&lt;/li&gt;
&lt;li&gt;🤖 Rodando modelos como DeepSeek Coder e Mistral direto no meu PC&lt;/li&gt;
&lt;li&gt;🧰 Personalizável para qualquer outro uso com LLMs offline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Então eu criei o &lt;a href="https://github.com/rafa-mori/mori-ollama-srv" rel="noopener noreferrer"&gt;&lt;code&gt;mori-ollama-srv&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 O que tem no stack?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; com suporte a modelos como &lt;code&gt;deepseek-coder:6.7b&lt;/code&gt;, &lt;code&gt;mistral&lt;/code&gt;, &lt;code&gt;llama&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Open-WebUI (interface para chats)&lt;/li&gt;
&lt;li&gt;✅ Benchmarks automáticos via script&lt;/li&gt;
&lt;li&gt;✅ Docker Compose + Makefile para facilitar tudo&lt;/li&gt;
&lt;li&gt;✅ Ativação de modo “performance” na CPU (Linux)&lt;/li&gt;
&lt;li&gt;✅ Execução local ou remota via SSH&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧪 Exemplos de uso
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Rodar com modelo padrão (deepseek)&lt;/span&gt;
make dev

&lt;span class="c"&gt;# Rodar com modelo leve (mistral)&lt;/span&gt;
make &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;ARGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--light"&lt;/span&gt;

&lt;span class="c"&gt;# Pular benchmark&lt;/span&gt;
make &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;ARGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--no-benchmark"&lt;/span&gt;

&lt;span class="c"&gt;# Rodar tudo remotamente&lt;/span&gt;
make &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;ARGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--remote=me@192.168.100.10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌍 Acesse o WebUI
&lt;/h2&gt;

&lt;p&gt;Depois de subir tudo, o painel estará acessível em:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📁 Repositório e Gist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/rafa-mori/mori-ollama-srv" rel="noopener noreferrer"&gt;https://github.com/rafa-mori/mori-ollama-srv&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gist: &lt;a href="https://gist.github.com/faelmori/463092315840a09417268b13f8fee1a8" rel="noopener noreferrer"&gt;https://gist.github.com/faelmori/463092315840a09417268b13f8fee1a8&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📄 Licença
&lt;/h2&gt;

&lt;p&gt;MIT © Rafael Mori&lt;br&gt;
Contribuições são super bem-vindas 🙌&lt;/p&gt;




&lt;p&gt;Se curtir, deixa uma estrela ⭐ lá no GitHub e comenta aqui como pretende usar!&lt;/p&gt;

</description>
      <category>ollama</category>
      <category>docker</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>TimeCraft: Simplifying Time Series Analysis and Automation</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Fri, 16 May 2025 06:01:55 +0000</pubDate>
      <link>https://forem.com/rafa_mori/timecraft-simplifying-time-series-analysis-and-automation-hhb</link>
      <guid>https://forem.com/rafa_mori/timecraft-simplifying-time-series-analysis-and-automation-hhb</guid>
      <description>&lt;p&gt;Today is one of those days when I'm really excited! I've just launched &lt;strong&gt;TimeCraft&lt;/strong&gt;, a tool written in Python that integrates time series analysis, database connections, and task automation into a single package. If you're looking for agility and flexibility for your data projects, come and see what I've created!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why TimeCraft?
&lt;/h2&gt;

&lt;p&gt;During recent projects, I realized that integrating forecasting models, querying databases, and automating workflows could become a challenge – especially if each of these functions were isolated in different tools. That's when TimeCraft was born: to &lt;strong&gt;simplify&lt;/strong&gt; complex tasks and provide an integrated experience, without sacrificing robustness and good programming practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Features
&lt;/h2&gt;

&lt;p&gt;TimeCraft was developed with a focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time Series Analysis:&lt;/strong&gt; Robust scripts for modeling, forecasting, and evaluating temporal data. Ideal for projecting trends and anticipating changes in various areas, such as finance, logistics and much more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Integration:&lt;/strong&gt; Efficient tools for connecting, consulting and extracting information from various database systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation &amp;amp; Notifications:&lt;/strong&gt; Automate your processes and receive alerts via webhooks – perfect for integrating with platforms such as Slack or Discord, keeping your team always up to date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out the project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;timecraft/
├── /src/ # Core logic and modules
├── /docs/ # Documentation (README, INSTALL, CONTRIBUTING)
├── /tutorials/ # Practical guides and advanced use cases
├── /data/ # Example datasets and generated results
├── /assets/ # Visual content for dissemination
├── /venv/ # Virtual environment and dependency management
└── requirements.txt # Python dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scheduling Executions
&lt;/h3&gt;

&lt;p&gt;TimeCraft allows you to schedule model execution, similar to cronjob, but integrated with your Python environment. For example, to run a model every 10 minutes, just use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; timecraft_ai schedule 600 timecraft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, directly in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;timecraft_ai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TimeCraftAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_scheduled&lt;/span&gt;

&lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TimeCraftAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_timecraft_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/hist_cambio_float.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;date_column&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;value_columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purchaseValue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;saleValue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="n"&gt;is_csv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;run_scheduled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval_seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Runs every 10 minutes
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notifications via Webhook
&lt;/h3&gt;

&lt;p&gt;One of the most interesting features is the native integration with notifications via webhooks. So, when you finish an analysis or training your model, a notification is sent to the platform of your choice, be it Slack, Discord or a custom endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;webhook_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://hooks.slack.com/services/XXX/YYY/ZZZ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;webhook_payload_extra&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TimeCraft model finished!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flexibility allows you to keep your workflow monitored and integrated, without additional effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring New Possibilities
&lt;/h2&gt;

&lt;p&gt;In addition to the immediate uses presented in the documentation, TimeCraft can be transformed into a base for even more functionalities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integration with Dashboards:&lt;/strong&gt; Create an optional module to visualize the results in real time using frameworks such as Dash or Streamlit. Imagine monitoring your models with interactive and dynamic graphs! - &lt;strong&gt;Cloud Data Source Support:&lt;/strong&gt; Extend the reach of TimeCraft by connecting to services like BigQuery and Snowflake. This would allow you to analyze large volumes of data without compromising performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine Learning Pipeline:&lt;/strong&gt; Use TimeCraft in conjunction with popular machine learning libraries (like scikit-learn or TensorFlow) to build complete pipelines, from collection and preprocessing to evaluation of advanced models (ARIMA, Prophet, LSTM).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Notifications:&lt;/strong&gt; Continue exploring integrations, for example, implementing email or SMS notifications, as well as richer interactions with third-party APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-Based Automation:&lt;/strong&gt; Combine scheduling with real-time monitoring to create triggers that execute analyses when certain events occur, taking automation to the next level.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TimeCraft&lt;/strong&gt; is a realization that merges data analysis, automation and integration into a single tool, and was designed to make the work of developers and data scientists easier. Whether you are a professional who needs to automate processes, make predictions or just explore new ways to integrate multiple technologies, TimeCraft has something to offer.&lt;/p&gt;

&lt;p&gt;If you are interested in collaborating, experimenting or suggesting new features, feel free to access the repository, contribuit with ideas and be part of this journey!&lt;/p&gt;




&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Experimentation:&lt;/strong&gt; Test the modules, analyze the results and discover how TimeCraft can fit into your workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback &amp;amp; Contributions:&lt;/strong&gt; The community is essential to make this project even bigger. Leave your feedback and share your experiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Integrations:&lt;/strong&gt; Explore integration with other tools, create dashboards and develop new features to expand the reach of this tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm excited to see how each of you will leverage this project in your daily solutions!&lt;/p&gt;




&lt;p&gt;I hope these ideas inspire you to explore new ways to leverage TimeCraft. And if you have other perspectives or ideas for expanding this tool, share them in the comments – the exchange of experiences is what really drives innovation in the development world.&lt;/p&gt;

&lt;p&gt;Happy coding and until next time!&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>automation</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>TimeCraft: Simplificando Análise de Séries Temporais e Automação</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Fri, 16 May 2025 05:56:52 +0000</pubDate>
      <link>https://forem.com/rafa_mori/timecraft-simplificando-analise-de-series-temporais-e-automacao-57gd</link>
      <guid>https://forem.com/rafa_mori/timecraft-simplificando-analise-de-series-temporais-e-automacao-57gd</guid>
      <description>&lt;p&gt;Hoje é um daqueles dias em que a empolgação bate forte! Acabo de lançar o &lt;strong&gt;TimeCraft&lt;/strong&gt;, uma ferramenta feita em Python que integra análise de séries temporais, conexão com bancos de dados e automação de tarefas num único pacote. Se você busca agilidade e flexibilidade para seus projetos de dados, venha conhecer o que criei!&lt;/p&gt;

&lt;h2&gt;
  
  
  Por Que TimeCraft?
&lt;/h2&gt;

&lt;p&gt;Durante projetos recentes, percebi que integrar modelos de previsão, efetuar consultas em bancos de dados e automatizar fluxos de trabalho podia se tornar um desafio – especialmente se cada uma dessas funções estivesse isolada em ferramentas diferentes. Foi aí que o TimeCraft nasceu: para &lt;strong&gt;simplificar&lt;/strong&gt; tarefas complexas e proporcionar uma experiência integrada, sem abrir mão da robustez e das boas práticas de programação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos Principais
&lt;/h2&gt;

&lt;p&gt;O TimeCraft foi desenvolvido com foco em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Análise de Séries Temporais:&lt;/strong&gt; Scripts robustos para modelagem, previsão e avaliação de dados temporais. Ideal para projetar tendências e antecipar mudanças em diversas áreas, como finanças, logística e muito mais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integração com Bancos de Dados:&lt;/strong&gt; Ferramentas eficientes para conectar, consultar e extrair informações de diversos sistemas de banco de dados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automação &amp;amp; Notificações:&lt;/strong&gt; Automatize seus processos e receba alertas via webhooks – perfeito para integrar com plataformas como Slack ou Discord, mantendo sua equipe sempre atualizada.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Confira a estrutura do &lt;a href="https://github.com/faelmori/timecraft" rel="noopener noreferrer"&gt;projeto&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;timecraft/
├── /src/                # Lógica central e módulos
├── /docs/               # Documentação (README, INSTALL, CONTRIBUTING)
├── /tutorials/          # Guias práticos e casos avançados de uso
├── /data/               # Conjuntos de dados de exemplo e resultados gerados
├── /assets/             # Conteúdo visual para divulgação
├── /venv/               # Ambiente virtual e gerenciamento de dependências
└── requirements.txt     # Dependências em Python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplos de Uso
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Agendamento de Execuções
&lt;/h3&gt;

&lt;p&gt;O TimeCraft permite que você agende a execução de modelos, algo semelhante ao cronjob, mas de forma integrada ao seu ambiente Python. Por exemplo, para rodar um modelo a cada 10 minutos, basta utilizar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; timecraft_ai schedule 600 timecraft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou, diretamente em seu código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;timecraft_ai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TimeCraftAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run_scheduled&lt;/span&gt;

&lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TimeCraftAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_timecraft_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/hist_cambio_float.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;date_column&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;value_columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purchaseValue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;saleValue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;is_csv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;run_scheduled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval_seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Executa a cada 10 minutos
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notificações via Webhook
&lt;/h3&gt;

&lt;p&gt;Uma das funcionalidades mais interessantes é a integração nativa com notificações via webhooks. Assim, ao finalizar uma análise ou o treinamento do seu modelo, uma notificação é enviada para a plataforma de sua escolha, seja Slack, Discord ou um endpoint personalizado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;webhook_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://hooks.slack.com/services/XXX/YYY/ZZZ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;webhook_payload_extra&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TimeCraft model finished!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa flexibilidade permite que você mantenha seu fluxo de trabalho monitorado e integrado, sem esforço adicional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explorando Novas Possibilidades
&lt;/h2&gt;

&lt;p&gt;Além dos usos imediatos apresentados na documentação, o TimeCraft pode se transformar em uma base para ainda mais funcionalidades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integração com Dashboards:&lt;/strong&gt; Crie um módulo opcional para visualização dos resultados em tempo real usando frameworks como Dash ou Streamlit. Imagine monitorar seus modelos com gráficos interativos e dinâmicos!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suporte a Fontes de Dados na Nuvem:&lt;/strong&gt; Amplie o alcance do TimeCraft conectando-se a serviços como BigQuery e Snowflake. Isso permitiria análises em grandes volumes de dados sem comprometer a performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline de Machine Learning:&lt;/strong&gt; Utilize o TimeCraft em conjunto com bibliotecas populares de machine learning (como scikit-learn ou TensorFlow) para construir pipelines completos, desde a coleta e pré-processamento até a avaliação de modelos avançados (ARIMA, Prophet, LSTM).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notificações Avançadas:&lt;/strong&gt; Siga explorando integrações, por exemplo, implementando notificações por e-mail ou SMS, bem como interações mais ricas com APIs de terceiros.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automação Baseada em Eventos:&lt;/strong&gt; Combine o agendamento com monitoramento em tempo real para criar triggers que executem análises quando determinados eventos ocorrerem, elevando o nível da automação.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considerações Finais
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;TimeCraft&lt;/strong&gt; é uma realização que funde análise de dados, automação e integração em uma única ferramenta, e foi pensado para facilitar o trabalho dos desenvolvedores e cientistas de dados. Seja você um profissional que precisa automatizar processos, fazer previsões ou apenas explorar novas formas de integrar múltiplas tecnologias, o TimeCraft tem algo a oferecer.&lt;/p&gt;

&lt;p&gt;Se você tem interesse em colaborar, experimentar ou sugerir novas funcionalidades, fique à vontade para acessar o repositório, contribuir com ideias e fazer parte dessa jornada!&lt;/p&gt;




&lt;h3&gt;
  
  
  Próximos Passos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Experimentação:&lt;/strong&gt; Teste os módulos, analise os resultados e descubra como o TimeCraft pode se encaixar nos seus fluxos de trabalho.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feedback &amp;amp; Contribuições:&lt;/strong&gt; A comunidade é fundamental para transformar o projeto em algo ainda maior. Deixe seu feedback e compartilhe suas experiências.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Novas Integrações:&lt;/strong&gt; Explore a integração com outras ferramentas, crie dashboards e desenvolva novas funcionalidades para ampliar o alcance desta ferramenta. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estou animado para ver como cada um de vocês aproveitará esse projeto em suas soluções diárias!&lt;/p&gt;




&lt;p&gt;Espero que essas ideias inspirem você a explorar novas maneiras de aproveitar o TimeCraft. E se você tiver outras perspectivas ou ideias para expandir essa ferramenta, compartilhe nos comentários – a troca de experiências é o que realmente impulsiona a inovação no mundo do desenvolvimento.&lt;/p&gt;

&lt;p&gt;Bons códigos e até a próxima!&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>automation</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Logz (Logger Global em Golang) [pt-BR]</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Sun, 02 Mar 2025 08:24:44 +0000</pubDate>
      <link>https://forem.com/rafa_mori/logz-logger-global-em-golang-pt-br-lm</link>
      <guid>https://forem.com/rafa_mori/logz-logger-global-em-golang-pt-br-lm</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introdução ao Logz: Um Logger Seguro e Flexível para Desenvolvedores Go e Uso Geral! 🚀&lt;/strong&gt;
&lt;/h2&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Abertura&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Você está cansado de lidar com sistemas de log complicados e inseguros em suas aplicações Go? Imagine ter um logger que, além de repleto de recursos poderosos e segurança robusta, oferece uma experiência de uso incrivelmente suave para o desenvolvedor. Conheça o &lt;strong&gt;Logz&lt;/strong&gt;—a solução open source que transforma totalmente seu fluxo de logging, combinando flexibilidade, segurança e integração com notificações. Seja durante o desenvolvimento local ou em ambientes de produção, o Logz está aqui para tornar seu processo de logging simples e eficaz.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conteúdo Principal&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Por que Logz?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Toda aplicação de qualidade precisa possuir um sistema de log confiável, mas na prática, o logging frequentemente é relegado a um segundo plano. Com o Logz, transformamos essa experiência ao dar ênfase a dois pilares essenciais: &lt;strong&gt;experiência do desenvolvedor&lt;/strong&gt; e &lt;strong&gt;segurança&lt;/strong&gt;. Veja o que diferencia o Logz:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logging Orientado a Metadados:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Anexe facilmente informações contextuais—como &lt;code&gt;requestId&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt;, ou outros campos relevantes—a cada entrada de log. Esses dados não são apenas informações extras: eles fornecem inteligência acionável, agilizando a depuração e o monitoramento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Práticas de Build Seguras:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Logz utiliza a flag &lt;code&gt;-trimpath&lt;/code&gt; do Go para remover caminhos absolutos sensíveis dos binários, além de recomendar a compressão dos executáveis com &lt;strong&gt;UPX&lt;/strong&gt; para garantir que sejam leves e seguros. Aqui, a segurança não é opcional—ela é parte fundamental do design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Opções de Saída Flexíveis:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Seja para exibir logs no console durante o desenvolvimento ou para gravá-los em arquivos em produção, o Logz oferece total controle. Suas flags de linha de comando permitem mudar facilmente a saída ou o formato, sem impor um único fluxo rígido.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Principais Funcionalidades&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O Logz vem carregado de recursos para atender todas as suas necessidades de logging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Suporte a Múltiplos Formatos de Log:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Escolha entre logs em texto, que facilitam a leitura humana, ou JSON, ideal para integração com sistemas de monitoramento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Saída Alinhada e Amigável:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Desfrute de logs formatados de forma bonita, onde timestamps, níveis e metadados permanecem alinhados e organizados. Em logs de texto, os metadados são impressos em uma segunda linha (com indentação), garantindo clareza sem poluir a mensagem principal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Controle Completo via CLI:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Com flags como &lt;code&gt;--msg&lt;/code&gt;, &lt;code&gt;--output&lt;/code&gt;, &lt;code&gt;--metadata&lt;/code&gt; e &lt;code&gt;--format&lt;/code&gt;, você tem controle total sobre cada entrada de log, podendo customizar a saída conforme necessário.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrações de Notificação:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Logz vai além do simples registro de mensagens, suportando notificações via webhooks HTTP, ZeroMQ e DBus. Assim, você pode configurar alertas em tempo real para eventos críticos, integrando com seus sistemas de monitoramento de forma transparente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Instalador Inteligente no Primeiro Uso:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Para tornar a experiência ainda mais fluida, Logz inclui um instalador inteligente que, na primeira execução, verifica se o binário está instalado corretamente. Se não estiver, ele pode copiar o binário para o diretório apropriado (por exemplo, &lt;code&gt;$HOME/.local/bin&lt;/code&gt; para usuários não-root ou &lt;code&gt;/usr/local/bin&lt;/code&gt; para root) e atualizar o PATH automaticamente, garantindo que sua ferramenta esteja pronta para uso imediato.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Exemplos de Código Avançados&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Exemplo 1: Logging Básico com Metadados&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Execute o seguinte comando para registrar uma mensagem de debug com metadados contextuais:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logz debug &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--msg&lt;/span&gt; &lt;span class="s2"&gt;"Depurando a nova funcionalidade com facilidade!"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; &lt;span class="s2"&gt;"stdout"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metadata&lt;/span&gt; &lt;span class="nv"&gt;requestId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12345,user&lt;span class="o"&gt;=&lt;/span&gt;admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída Esperada:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2025-03-02T03:35:13Z] 🐛 DEBUG - Depurando a nova funcionalidade com facilidade!
                     {"requestId":"12345","user":"admin"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Explicação:&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Cada log exibe um timestamp, o nível (com um emoji para facilitar a identificação visual) e a mensagem principal. Os metadados são exibidos logo abaixo, com uma indentação que mantém a saída limpa e organizada.&lt;/p&gt;


&lt;h4&gt;
  
  
  &lt;strong&gt;Exemplo 2: Logging em Arquivo no Formato JSON&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Para ambientes de produção, é comum utilizar JSON para facilitar a integração com sistemas de monitoramento. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logz info &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--msg&lt;/span&gt; &lt;span class="s2"&gt;"Serviço iniciado com sucesso."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; &lt;span class="s2"&gt;"/var/log/meuapp/servico.log"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--format&lt;/span&gt; json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metadata&lt;/span&gt; &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auth,version&lt;span class="o"&gt;=&lt;/span&gt;v1.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Saída Esperada (JSON):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-03-02T03:40:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INFO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Serviço iniciado com sucesso."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1.0.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Explicação:&lt;/em&gt;&lt;br&gt;&lt;br&gt;
As entradas de log são formatadas em JSON, permitindo que sejam facilmente processadas por agregadores de logs e sistemas de monitoramento.&lt;/p&gt;


&lt;h4&gt;
  
  
  &lt;strong&gt;Exemplo 3: Integração do Logz em um Microserviço Web&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Veja como integrar Logz em um servidor HTTP no Go:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/faelmori/logz/logger"&lt;/span&gt; &lt;span class="c"&gt;// Ajuste o caminho conforme necessário&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Inicializa o logger com um prefixo customizado.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebAPI: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Define um handler HTTP que loga os detalhes de cada requisição.&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&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;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Requisição recebida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&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="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;
            &lt;span class="s"&gt;"método"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"caminho"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Olá, mundo!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c"&gt;// Inicia o servidor HTTP, logando seu início.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Iniciando servidor na porta 8080"&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;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&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;span class="n"&gt;err&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="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Falha ao iniciar servidor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&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="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;&lt;span class="s"&gt;"erro"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Explicação:&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Cada requisição é logada com informações úteis que facilitam a análise do tráfego e a depuração de problemas. Se ocorrer um erro crítico, o log dispara um alerta via o método &lt;code&gt;Fatal&lt;/code&gt;, que encerra o servidor.&lt;/p&gt;


&lt;h4&gt;
  
  
  &lt;strong&gt;Exemplo 4: Integração de Notificadores para Alertas em Tempo Real&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Veja como você pode configurar notificadores para enviar alertas quando ocorrerem erros críticos:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/faelmori/logz/logger"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Inicializa o logger e define metadados globais.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AlertService: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"payment"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Simula um erro que dispara um alarme.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Falha na transação de pagamento"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&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="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;
        &lt;span class="s"&gt;"transactionId"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"txn_987654321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"timestamp"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RFC3339&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Explicação:&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Com os notificadores configurados no Logz, esta mensagem de erro pode, por exemplo, disparar um alerta via um webhook HTTP ou enviar uma notificação por DBus, garantindo uma resposta rápida a problemas críticos.&lt;/p&gt;


&lt;h4&gt;
  
  
  &lt;strong&gt;Exemplo 5: Instalador Inteligente no Primeiro Uso&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Para aprimorar a experiência do usuário, Logz possui um instalador inteligente. No primeiro uso, o binário verifica se está corretamente instalado; se não estiver, ele se copia para o diretório apropriado e atualiza o PATH:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"os/exec"&lt;/span&gt;
    &lt;span class="s"&gt;"path/filepath"&lt;/span&gt;
    &lt;span class="s"&gt;"strings"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;isInPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pathEnv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PATH"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;exePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Executable&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;err&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="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;exeDir&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exePath&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;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pathEnv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exeDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;updatePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetDir&lt;/span&gt; &lt;span class="kt"&gt;string&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="n"&gt;shell&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHELL"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;

    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;shell&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"bash"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".bashrc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"zsh"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".zshrc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".profile"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Adicione a seguinte linha ao seu %s para incluir %s no PATH:&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="n"&gt;shellConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"export PATH=%s:$PATH&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="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&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;func&lt;/span&gt; &lt;span class="n"&gt;firstRunInstaller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;configFile&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".logzconfig"&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNotExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Parece que é a primeira vez que você executa o Logz."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deseja instalar o Logz no seu sistema para facilitar o uso? (Y/n): "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scanln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;resp&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;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"y"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;resp&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="n"&gt;exePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Executable&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;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao obter o caminho do executável: %v&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="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;targetDir&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"/usr/local/bin"&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Geteuid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&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;targetDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"logz"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&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;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro durante a instalação: %v&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="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Logz instalado em: %s&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="n"&gt;target&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;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;updatePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Falha ao atualizar o PATH: %v&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="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"installed=true&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="m"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"skip_install=true&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="m"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Instalação ignorada. Você pode instalá-lo manualmente depois."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;firstRunInstaller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Logz está pronto para uso!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Explicação:&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Neste trecho, o programa verifica se um arquivo de configuração existe para determinar se é a primeira execução. Se for, ele questiona o usuário para instalar automaticamente o binário no diretório adequado e guia a atualização do PATH, proporcionando uma experiência “mágica” e sem complicações.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Destaques do Projeto&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Source no GitHub:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Explore o código, contribua com melhorias ou simplesmente dê uma estrela se o Logz fizer sentido para você. &lt;a href="https://github.com/faelmori/logz" rel="noopener noreferrer"&gt;Confira no GitHub&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentação Detalhada:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Toda a documentação está disponível em &lt;strong&gt;pkg.go.dev&lt;/strong&gt;, proporcionando referências claras e guias de integração para facilitar sua adoção.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusão e Chamada para Ação&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O Logz não é apenas um logger—é uma ferramenta completa de observabilidade projetada para aplicações modernas em Go. Ao combinar práticas de build seguras, opções de saída flexíveis, manipulação rica de metadados e integrações inteligentes de notificações, o Logz capacita os desenvolvedores a monitorar e depurar suas aplicações com mais eficiência.&lt;/p&gt;

&lt;p&gt;Experimente o Logz no seu próximo projeto Go e descubra como ele pode simplificar o seu fluxo de logging. Se o Logz facilitar sua vida, considere dar uma estrela no repositório do GitHub e compartilhar seu feedback. Juntos, podemos construir um ecossistema de logging mais inteligente, rápido e seguro—um log por vez!&lt;/p&gt;

</description>
      <category>logging</category>
      <category>go</category>
      <category>github</category>
      <category>newborn</category>
    </item>
    <item>
      <title>Logz (Global Logger in Golang)</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Sun, 02 Mar 2025 08:07:01 +0000</pubDate>
      <link>https://forem.com/rafa_mori/logz-global-logger-in-golang-2661</link>
      <guid>https://forem.com/rafa_mori/logz-global-logger-in-golang-2661</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introducing Logz: A Secure and Flexible Logger for Go Developers and General Use! 🚀&lt;/strong&gt;
&lt;/h2&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Opening Hook&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Are you tired of wrestling with clunky, insecure logging systems in your Go applications? Imagine having a logger that not only packs powerful features and robust security into a single package but also delivers an incredibly smooth developer experience. Meet &lt;strong&gt;Logz&lt;/strong&gt;—the open-source logging solution that transforms your logging workflow with flexibility, security, and integrated notification capabilities. Whether you’re developing locally or deploying in production, Logz is here to make your logging process seamless.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Main Content&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Logz?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every good application needs reliable logging. Yet too often, logging is treated as an afterthought. With Logz, we’ve turned logging into a first-class experience by focusing on two essential pillars: &lt;strong&gt;developer experience&lt;/strong&gt; and &lt;strong&gt;security&lt;/strong&gt;. Here’s how Logz stands out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metadata-Driven Logging:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Easily attach context—like &lt;code&gt;requestId&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt;, or other relevant fields—to every log entry. This isn’t just extra data; it’s actionable intelligence that speeds up debugging and monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Secure Build Practices:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Logz leverages Go’s &lt;code&gt;-trimpath&lt;/code&gt; flag to strip sensitive build paths from binaries, and we recommend compressing your executables with &lt;strong&gt;UPX&lt;/strong&gt; to ensure they’re lightweight and secure. With these practices built in, secure logging isn’t an afterthought—it’s part of the design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexible Output Options:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Whether you prefer logging to the console during development or to files in production, Logz gives you full control. Its CLI flags let you easily switch outputs, adjust formats, and don’t force you into one rigid workflow.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Key Features&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Logz is built to cover all your logging needs while extending its functionality further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiple Log Formats:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Choose between human-friendly text logs and machine-parsable JSON to fit your workflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Neatly Aligned Output:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Enjoy output where timestamps, log levels, and metadata are neatly aligned. For text logs, metadata is printed on a new indented line, enhancing readability without cluttering your primary log message.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comprehensive CLI Control:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
With flags such as &lt;code&gt;--msg&lt;/code&gt;, &lt;code&gt;--output&lt;/code&gt;, &lt;code&gt;--metadata&lt;/code&gt;, and &lt;code&gt;--format&lt;/code&gt;, you have fine-grained control over every aspect of your log entries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notification Integrations:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Logz can do more than just print logs. Its built-in notifier system supports HTTP webhooks, ZeroMQ, and DBus. This means you can set up real-time alerts whenever critical events occur, directly integrating with your existing monitoring systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Advanced First-Run Installer:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For a truly seamless experience, Logz features an intelligent first-run installer. Upon initial execution, Logz checks if it’s properly installed—and if not, it can automatically copy itself to the appropriate directory (e.g., &lt;code&gt;$HOME/.local/bin&lt;/code&gt; for non-root users or &lt;code&gt;/usr/local/bin&lt;/code&gt; for root users), and update the PATH so the tool is immediately accessible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Extended Code Examples&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Example 1: Basic Debug Logging with Metadata&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Log a debug message with contextual metadata using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logz debug &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--msg&lt;/span&gt; &lt;span class="s2"&gt;"Debugging the latest feature with ease!"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; &lt;span class="s2"&gt;"stdout"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metadata&lt;/span&gt; &lt;span class="nv"&gt;requestId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12345,user&lt;span class="o"&gt;=&lt;/span&gt;admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2025-03-02T03:35:13Z] 🐛 DEBUG - Debugging the latest feature with ease!
                     {"requestId":"12345","user":"admin"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each log entry is timestamped and clearly displays the log level along with your message. The metadata, shown on an indented new line, ensures additional context is visible without cluttering the primary message.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Example 2: Logging to File in JSON Format&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For production, you can output logs in JSON format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logz info &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--msg&lt;/span&gt; &lt;span class="s2"&gt;"Service started successfully."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; &lt;span class="s2"&gt;"/var/log/myapp/service.log"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--format&lt;/span&gt; json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metadata&lt;/span&gt; &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auth,version&lt;span class="o"&gt;=&lt;/span&gt;v1.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected Output (JSON):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-03-02T03:40:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INFO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Service started successfully."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1.0.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This format is ideal for integration with log aggregators and monitoring systems.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Example 3: Integrating Logz in a Microservice Web Application&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Below is a snippet showing how to integrate Logz in an HTTP server:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/faelmori/logz/logger"&lt;/span&gt; &lt;span class="c"&gt;// Adjust the import path as needed&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Initialize the logger with a custom prefix.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebAPI: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Define an HTTP handler to log request details.&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&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;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&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="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;
            &lt;span class="s"&gt;"method"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"path"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c"&gt;// Start the HTTP server.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting server on port 8080"&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;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&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;span class="n"&gt;err&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="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server failed to start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&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="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example shows how every request and error is logged with useful metadata, making troubleshooting much easier.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Example 4: Notifier Integration for Real-Time Alerts&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Logz’s notifier system allows you to send alerts via webhooks, ZeroMQ, or DBus. Here’s a brief example of how you might set up a notifier for critical errors:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/faelmori/logz/logger"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Initialize the logger and set global metadata.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AlertService: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"payment"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Simulate an error to trigger a notifier.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Payment transaction failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;map&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="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;
        &lt;span class="s"&gt;"transactionId"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"txn_987654321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"timestamp"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RFC3339&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the notifier setup in your configuration, this log entry might trigger an HTTP alert, a ZeroMQ message, or a DBus notification—whatever best suits your environment.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Example 5: Advanced First-Run Installer Logic&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;To address environment configuration automatically, Logz includes a first-run installer that checks if the binary is properly installed and, if not, copies itself to an appropriate directory and updates the PATH:&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"os/exec"&lt;/span&gt;
    &lt;span class="s"&gt;"path/filepath"&lt;/span&gt;
    &lt;span class="s"&gt;"strings"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// isInPath checks if the current executable's directory is present in the PATH.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;isInPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pathEnv&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PATH"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;exePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Executable&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;err&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="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;exeDir&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exePath&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;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pathEnv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exeDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// firstRunInstaller checks if Logz is installed in the expected location and updates the PATH if necessary.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;firstRunInstaller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;configFile&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".logzconfig"&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNotExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"It looks like this is your first time using Logz."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Would you like to install Logz for easier access? (Y/n): "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scanln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;response&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;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"y"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;response&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="n"&gt;exePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Executable&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;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error obtaining executable path: %v&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="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;targetDir&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"/usr/local/bin"&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Geteuid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&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;targetDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"logz"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&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;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Installation error: %v&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="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Logz installed to %s.&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="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c"&gt;// Update PATH automatically by determining the user's shell config.&lt;/span&gt;
            &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
            &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHELL"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"bash"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".bashrc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"zsh"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".zshrc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;shellConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;".profile"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Adding %s to PATH in %s...&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="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shellConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_APPEND&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;O_WRONLY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0644&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;err&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="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&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;export PATH=%s:$PATH&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="n"&gt;targetDir&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;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PATH updated in %s. Run 'source %s' to apply changes.&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="n"&gt;shellConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shellConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to update %s. Please add %s to your PATH manually.&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="n"&gt;shellConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targetDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c"&gt;// Write to config file to avoid asking again.&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"installed=true&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="m"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"skip_install=true&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="m"&gt;0644&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Installation skipped. You can install it later manually."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Try to run the first-run installer&lt;/span&gt;
    &lt;span class="n"&gt;firstRunInstaller&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Continue with the normal program flow&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Logz is ready to use."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code checks whether it's the first time Logz is being run, asks the user if they’d like it installed for easier access, and then automatically copies the executable and updates the PATH by modifying the appropriate shell configuration file. This automation greatly improves usability for users who may not be comfortable with manual PATH configuration.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Project Highlights&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Source on GitHub:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Dive into the source, contribute your improvements, or star the repository if Logz resonates with you. &lt;a href="https://github.com/faelmori/logz" rel="noopener noreferrer"&gt;See it on GitHub&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Detailed Documentation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Comprehensive API references and integration guides are fully available on &lt;strong&gt;pkg.go.dev&lt;/strong&gt;, making Logz easy to integrate into your projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion and Call-to-Action&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Logz is not just a logger—it’s a complete observability tool for modern Go applications. It combines secure build practices, flexible output, rich metadata handling, and even smart notification integrations. Its advanced first-run installer ensures that Logz is set up perfectly on your system without the usual hassles. &lt;/p&gt;

&lt;p&gt;If Logz simplifies your logging, consider giving it a try in your next Go project and sharing your thoughts on GitHub. Your feedback and support help us build a smarter, faster, and more secure logging ecosystem—one log entry at a time!&lt;/p&gt;

</description>
      <category>logging</category>
      <category>go</category>
      <category>github</category>
      <category>newborn</category>
    </item>
    <item>
      <title>Changing the Login Shell with Security and Interactivity</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Wed, 08 Jan 2025 16:34:52 +0000</pubDate>
      <link>https://forem.com/rafa_mori/changing-the-login-shell-with-security-and-interactivity-1iib</link>
      <guid>https://forem.com/rafa_mori/changing-the-login-shell-with-security-and-interactivity-1iib</guid>
      <description>&lt;p&gt;Changing a user's login shell can be a simple task, but it involves several considerations to ensure security and convenience. This article presents a Bash script that exemplifies how to perform this change interactively and securely, using the &lt;code&gt;dialog&lt;/code&gt; tool for user interaction and detailed validations to prevent errors or unsafe configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of the Script
&lt;/h2&gt;

&lt;p&gt;The script changes the login shell in multiple steps, ensuring each action is validated before being applied. Among the main features of the script are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Permission verification:&lt;/strong&gt; The script requires the user to be in the &lt;code&gt;sudo&lt;/code&gt; group, ensuring that only users with administrative privileges can make changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactivity with &lt;code&gt;dialog&lt;/code&gt;:&lt;/strong&gt; The &lt;code&gt;dialog&lt;/code&gt; tool is used to display interactive menus, making it easy for the user to choose the new shell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation of available and safe shells:&lt;/strong&gt; The script checks if the chosen shell is listed in &lt;code&gt;/etc/shells&lt;/code&gt; and is considered safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shell change:&lt;/strong&gt; Multiple methods are implemented to perform the shell change, with checks at each step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirmation and feedback:&lt;/strong&gt; The user is informed about the success or failure of the operation and instructed to restart the session if necessary.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Script Components and Functionality
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Dependency Check
&lt;/h3&gt;

&lt;p&gt;Before starting, the script checks if the user belongs to the &lt;code&gt;sudo&lt;/code&gt; group and if the &lt;code&gt;dialog&lt;/code&gt; command is installed:&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;groups&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s1"&gt;'\bsudo\b'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"The user is not in the sudo group.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; dialog &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"The dialog command is not available. Do you want to install it? (y/n) "&lt;/span&gt;
    &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; response
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ ^[Yy]&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"Dialog installation canceled.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Package required to continue.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="nb"&gt;exit &lt;/span&gt;0
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; dialog&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Could not install dialog."&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;1
    &lt;span class="k"&gt;fi
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This initial validation prevents the script from running without the necessary prerequisites, reducing the likelihood of failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Listing Available Shells
&lt;/h3&gt;

&lt;p&gt;The script uses the &lt;code&gt;/etc/shells&lt;/code&gt; file to retrieve the list of available shells and display them to the user in an interactive menu:&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;_AVAILABLE_SHELLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s1"&gt;'^#'&lt;/span&gt; &lt;span class="s2"&gt;"/etc/shells"&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;_SHELL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dialog &lt;span class="nt"&gt;--menu&lt;/span&gt; &lt;span class="s2"&gt;"Choose the shell you want to use:"&lt;/span&gt; 15 50 10 &lt;span class="nv"&gt;$_AVAILABLE_SHELLS&lt;/span&gt; 3&amp;gt;&amp;amp;1 1&amp;gt;&amp;amp;2 2&amp;gt;&amp;amp;3&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method ensures that only valid shells can be selected.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Safe Shell Validation
&lt;/h3&gt;

&lt;p&gt;Before performing the change, the script checks if the chosen shell is safe by comparing it with a predefined list of allowed shells:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;check_shell_safe&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;shell&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;allowed_shells&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
      &lt;span class="s2"&gt;"/bin/sh"&lt;/span&gt; &lt;span class="s2"&gt;"/usr/bin/sh"&lt;/span&gt;
      &lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt; &lt;span class="s2"&gt;"/usr/bin/bash"&lt;/span&gt;
      &lt;span class="s2"&gt;"/bin/zsh"&lt;/span&gt; &lt;span class="s2"&gt;"/usr/bin/zsh"&lt;/span&gt;
      &lt;span class="c"&gt;# Other allowed shells&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;forbidden_shells&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"/bin/false"&lt;/span&gt; &lt;span class="s2"&gt;"/usr/sbin/nologin"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;allowed_shells&lt;/span&gt;&lt;span class="p"&gt;[*]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="nv"&gt;$shell&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nv"&gt;$shell&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$shell&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; /&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;forbidden_shells&lt;/span&gt;&lt;span class="p"&gt;[*]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="nv"&gt;$shell&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This validation prevents unsafe or non-functional shells from being set as default.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Changing the Shell
&lt;/h3&gt;

&lt;p&gt;The script implements three methods to change the user's shell:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Using the &lt;code&gt;chsh&lt;/code&gt; command:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   chsh &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SHELL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Using the &lt;code&gt;usermod&lt;/code&gt; command:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;--shell&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SHELL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-un&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Directly editing the &lt;code&gt;/etc/passwd&lt;/code&gt; file:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s|&lt;/span&gt;&lt;span class="nv"&gt;$_OLD_LINE&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;$_NEW_LINE&lt;/span&gt;&lt;span class="s2"&gt;|"&lt;/span&gt; &lt;span class="s2"&gt;"/etc/passwd"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These methods are applied in sequence, ensuring redundancy if one of them fails.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Verification and Feedback
&lt;/h3&gt;

&lt;p&gt;After changing the shell, the script verifies whether the change was applied successfully and informs the user:&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="k"&gt;if &lt;/span&gt;verify_shell_change &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SHELL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;dialog &lt;span class="nt"&gt;--msgbox&lt;/span&gt; &lt;span class="s2"&gt;"Shell successfully changed to &lt;/span&gt;&lt;span class="nv"&gt;$SHELL&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt; 10 50
&lt;span class="k"&gt;else
    &lt;/span&gt;dialog &lt;span class="nt"&gt;--msgbox&lt;/span&gt; &lt;span class="s2"&gt;"Could not change the shell."&lt;/span&gt; 10 50
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Importance of Validations
&lt;/h2&gt;

&lt;p&gt;The validations implemented in the script ensure that only valid and safe shells are configured. This prevents issues such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting a nonexistent or invalid shell, making it impossible for the user to log in.&lt;/li&gt;
&lt;li&gt;Using unsafe or disabled shells by default (e.g., &lt;code&gt;/bin/false&lt;/code&gt; or &lt;code&gt;/usr/sbin/nologin&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This script demonstrates how to automate and simplify the process of changing login shells with security and interactivity. It can be adapted to meet the specific needs of an environment, but best practices for validation and user feedback should be maintained to ensure its reliability and usability.&lt;/p&gt;

&lt;p&gt;If you have questions or want to customize the script for your system, feel free to adjust the lists of allowed and forbidden shells or add new validation methods!&lt;/p&gt;

&lt;p&gt;For more details, check out the script on GitHub: &lt;a href="https://gist.github.com/faelmori/e42b3c06a901622f0d538cfd7e56b15b" rel="noopener noreferrer"&gt;View the Gist&lt;/a&gt;. Feel free to follow me on GitHub, leave a comment, or contribute to the discussion!&lt;/p&gt;

</description>
      <category>bash</category>
      <category>scripting</category>
      <category>linux</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Go Serialization Essentials: Struct Tags, Error Handling, and Real-World Use Cases</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Mon, 06 Jan 2025 03:20:56 +0000</pubDate>
      <link>https://forem.com/rafa_mori/go-serialization-essentials-struct-tags-error-handling-and-real-world-use-cases-59p4</link>
      <guid>https://forem.com/rafa_mori/go-serialization-essentials-struct-tags-error-handling-and-real-world-use-cases-59p4</guid>
      <description>&lt;ol&gt;
&lt;li&gt;
Introduction: Understanding Serialization and Deserialization in Go
&lt;/li&gt;
&lt;li&gt;Basic Concepts: Working with &lt;code&gt;encoding/json&lt;/code&gt; and &lt;code&gt;gopkg.in/yaml.v2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Practical Examples: Serialization and Deserialization in Go

&lt;ul&gt;
&lt;li&gt;
3.1 Basic Serialization and Deserialization
&lt;/li&gt;
&lt;li&gt;
3.2 Handling Complex and Nested Structures
&lt;/li&gt;
&lt;li&gt;
3.3 Customization with Struct Tags
&lt;/li&gt;
&lt;li&gt;
3.4 Error Handling
&lt;/li&gt;
&lt;li&gt;
3.5 Generating Dynamic Code
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Full Scenario: Real-World Use Case&lt;/li&gt;
&lt;li&gt;
Best Practices: Writing Efficient and Maintainable Serialization Code
&lt;/li&gt;
&lt;li&gt;
Conclusion
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;1. Introduction: Understanding Serialization and Deserialization in Go&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Serialization and deserialization are key concepts in software development that help in the storage, transmission, and manipulation of data. In Go, serialization refers to the process of converting a data structure into a format that can be easily stored or transmitted (e.g., JSON, YAML, or binary). Deserialization is the reverse process, where serialized data is converted back into a Go data structure.&lt;/p&gt;

&lt;p&gt;In Go, serialization and deserialization are made easy through standard libraries and third-party packages. This article will explore the basic concepts of these processes and show you how to effectively work with data in Go using popular packages like &lt;code&gt;encoding/json&lt;/code&gt; and &lt;code&gt;gopkg.in/yaml.v2&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2. Basic Concepts: Working with&lt;/strong&gt; &lt;code&gt;encoding/json&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;gopkg.in/yaml.v2&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Go provides built-in support for handling JSON through the &lt;code&gt;encoding/json&lt;/code&gt; package, which offers functions like &lt;code&gt;Marshal&lt;/code&gt; (to serialize) and &lt;code&gt;Unmarshal&lt;/code&gt; (to deserialize). Similarly, &lt;code&gt;gopkg.in/yaml.v2&lt;/code&gt; is a popular third-party package used for working with YAML data, providing functions like &lt;code&gt;yaml.Marshal&lt;/code&gt; and &lt;code&gt;yaml.Unmarshal&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;encoding/json&lt;/code&gt;:&lt;/strong&gt; This package allows you to easily convert Go objects into JSON format and vice versa. It supports encoding/decoding both simple and complex data structures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;gopkg.in/yaml.v2&lt;/code&gt;:&lt;/strong&gt; This package is widely used for working with YAML in Go. YAML is a human-readable data serialization format, often used in configuration files, and Go’s YAML package allows you to encode and decode Go structs with ease.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These packages allow you to work with different data formats in Go seamlessly, enabling easier data exchange, storage, and processing.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. Practical Examples: Serialization and Deserialization in Go&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now, let's explore practical examples of how serialization and deserialization work in Go.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;3.1 Basic Serialization and Deserialization&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;First, let's look at how to serialize and deserialize basic data structures in JSON and YAML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"gopkg.in/yaml.v2"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Basic data structure.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Person&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;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name" yaml:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Age&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"age" yaml:"age"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Create an instance of Person&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Serialize to JSON&lt;/span&gt;
    &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JSON:"&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="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Serialize to YAML&lt;/span&gt;
    &lt;span class="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YAML:"&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="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Deserialize JSON&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;jsonPerson&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;jsonPerson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deserialized from JSON:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonPerson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Deserialize YAML&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;yamlPerson&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;
    &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;yamlPerson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deserialized from YAML:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yamlPerson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This example demonstrates basic serialization and deserialization of a simple &lt;code&gt;Person&lt;/code&gt; struct into both JSON and YAML formats. The &lt;code&gt;json.Marshal&lt;/code&gt; and &lt;code&gt;yaml.Marshal&lt;/code&gt; functions are used to serialize the data, while &lt;code&gt;json.Unmarshal&lt;/code&gt; and &lt;code&gt;yaml.Unmarshal&lt;/code&gt; are used for deserialization.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;3.2 Handling Complex and Nested Structures&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Go allows us to serialize and deserialize more complex data structures, including nested structs, arrays, and slices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&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;Address&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;Street&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"street" yaml:"street"`&lt;/span&gt;
    &lt;span class="n"&gt;City&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"city" yaml:"city"`&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;PersonWithAddress&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;Name&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"name" yaml:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Age&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="s"&gt;`json:"age" yaml:"age"`&lt;/span&gt;
    &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="s"&gt;`json:"address" yaml:"address"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Street&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"123 Main St"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Gotham"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;PersonWithAddress&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Bruce Wayne"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Serialize to JSON&lt;/span&gt;
    &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JSON:"&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="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Serialize to YAML&lt;/span&gt;
    &lt;span class="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YAML:"&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="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Here, we serialize and deserialize a nested structure &lt;code&gt;PersonWithAddress&lt;/code&gt;, which contains an embedded struct &lt;code&gt;Address&lt;/code&gt;. Both JSON and YAML serialization are handled automatically by the respective packages.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;3.3 Customization with Struct Tags&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Go structs can include tags that specify how fields are serialized into different formats. These tags allow for customization, such as renaming fields or excluding them from serialization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&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;CustomPerson&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;Name&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"full_name" yaml:"full_name"`&lt;/span&gt;
    &lt;span class="n"&gt;Age&lt;/span&gt;     &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"-" yaml:"-"`&lt;/span&gt; &lt;span class="c"&gt;// Exclude from serialization&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"email,omitempty" yaml:"email,omitempty"`&lt;/span&gt; &lt;span class="c"&gt;// Omit if empty&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;CustomPerson&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Email&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="c"&gt;// Serialize to JSON&lt;/span&gt;
    &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JSON:"&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="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Serialize to YAML&lt;/span&gt;
    &lt;span class="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YAML:"&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="n"&gt;yamlData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In this example, the &lt;code&gt;CustomPerson&lt;/code&gt; struct uses tags to control how the fields are serialized. The &lt;code&gt;Age&lt;/code&gt; field is excluded from both JSON and YAML serialization, and the &lt;code&gt;Email&lt;/code&gt; field is omitted if it is empty (&lt;code&gt;omitempty&lt;/code&gt; tag).&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;3.4 Error Handling&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Proper error handling is crucial in serialization and deserialization. Let’s add error checks to ensure that any issues during encoding or decoding are handled gracefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&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;safeMarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;interface&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="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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&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;err&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="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error serializing data: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&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;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Example with error handling&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;// Invalid data (Age cannot be negative)&lt;/span&gt;

    &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;safeMarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&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;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JSON:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In this example, the &lt;code&gt;safeMarshal&lt;/code&gt; function wraps the &lt;code&gt;json.Marshal&lt;/code&gt; call and provides error handling, ensuring that if there is an issue during serialization, it will be caught and logged.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;3.5 Generating Dynamic Code&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Go’s reflection capabilities allow us to generate functions that can handle serialization and deserialization dynamically based on the data types at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&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;import&lt;/span&gt; &lt;span class="s"&gt;"reflect"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;generateSerializationFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;interface&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="n"&gt;typ&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reflect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elem&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;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"func Serialize%s(data %s) string { ... }"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;typ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;typ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;generateSerializationFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated Code:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In this example, we use reflection to dynamically generate a function that could serialize any given struct type. This can be useful when dealing with various data structures in large applications.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Full Scenario: Real-World Use Case&lt;/strong&gt; {#full-scenario}
&lt;/h2&gt;

&lt;p&gt;Let’s demonstrate a real-world use case where these techniques are applied. Imagine a web API that accepts both JSON and YAML as input formats, stores data in a database, and generates dynamic SQL queries for data insertion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&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="c"&gt;// Example of serializing data for a web API&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;apiRequestHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;user&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;err&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="c"&gt;// Handle error&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c"&gt;// Generate SQL query for database insertion&lt;/span&gt;
    &lt;span class="n"&gt;sqlQuery&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GenerateSQLInsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated SQL:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sqlQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In this real-world example, we deserialize incoming data (in JSON format) into Go structs, then use it to generate an SQL query for data insertion into a database. This demonstrates how serialization, deserialization, and dynamic code generation can be integrated in practical scenarios.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;5. Best Practices: Writing Efficient and Maintainable Serialization Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; Always handle errors properly. Ensure that both serialization and deserialization processes account for malformed or unexpected data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Struct Tags:&lt;/strong&gt; Make good use of struct tags to control serialization behavior (e.g., field names, omissions, custom rules).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Overusing Reflection:&lt;/strong&gt; Reflection is powerful but can lead to less readable and harder-to-maintain code. Use it only when necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimize Performance:&lt;/strong&gt; When dealing with large datasets, consider using streaming methods like &lt;code&gt;json.NewEncoder&lt;/code&gt; and &lt;code&gt;json.NewDecoder&lt;/code&gt; for better performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test with Different Formats:&lt;/strong&gt; Always test your serialization and deserialization functions with various input scenarios to ensure robustness.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;6. Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this article, we explored the fundamentals of serialization and deserialization in Go using JSON and YAML. We covered basic and complex structures, customization using struct tags, error handling, and dynamic code generation. Additionally, we provided a real-world scenario to demonstrate the practical application of these techniques. &lt;/p&gt;

&lt;p&gt;As you continue working with Go, consider exploring more advanced topics like performance optimizations, custom encoding/decoding methods, and integrations with third-party libraries for even more powerful data manipulation.&lt;/p&gt;




</description>
      <category>go</category>
      <category>development</category>
      <category>compliance</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>Creating Safe Custom Types with Validation in Go</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Sun, 05 Jan 2025 12:52:04 +0000</pubDate>
      <link>https://forem.com/rafa_mori/creating-safe-custom-types-with-validation-in-go-p22</link>
      <guid>https://forem.com/rafa_mori/creating-safe-custom-types-with-validation-in-go-p22</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Go programming, creating custom types with validation is paramount for ensuring data integrity and security. This article explores a code structure that exemplifies the creation of a custom type, incorporating robust validation and adhering to best practices for safety and compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's break down the essential components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Necessary Imports:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"fmt"&lt;/span&gt;
        &lt;span class="s"&gt;"strings"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Custom Type Definition:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;Example&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define a custom type &lt;code&gt;Example&lt;/code&gt; as a string, providing a clear and concise representation of the data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Constants and Allowed Options:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ArgumentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"value_a"&lt;/span&gt;
        &lt;span class="n"&gt;ArgumentB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"value_b"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;AllowedOptions&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArgumentA&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="n"&gt;ArgumentB&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define constants for allowed values and store them in a slice for easy reference and management.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Methods for the Example Type:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;String()&lt;/code&gt;:&lt;/strong&gt; Returns the string representation of the &lt;code&gt;Example&lt;/code&gt; value.
&lt;/li&gt;
&lt;/ul&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;String&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="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;Type()&lt;/code&gt;:&lt;/strong&gt; Returns the name of the type.
&lt;/li&gt;
&lt;/ul&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Type&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="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Example"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;Set()&lt;/code&gt;:&lt;/strong&gt; Validates the input value and sets the &lt;code&gt;Example&lt;/code&gt; value if valid.
&lt;/li&gt;
&lt;/ul&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="kt"&gt;string&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exampleOption&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;AllowedOptions&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;exampleOption&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Example&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="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
                &lt;span class="p"&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;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"allowed values: %s"&lt;/span&gt;&lt;span class="p"&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;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AllowedOptions&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Advantages of Using Custom Types with Validation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Enhanced Data Security:&lt;/strong&gt; By rigorously validating input, we prevent invalid or malicious data from entering the system, bolstering overall security.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Improved Compliance:&lt;/strong&gt; Adhering to validation rules helps ensure compliance with relevant standards like GDPR or HIPAA.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Increased Code Maintainability:&lt;/strong&gt; Custom types promote modularity and make code easier to maintain and extend.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Enhanced Type Safety:&lt;/strong&gt; Go's type system provides compile-time checks, minimizing runtime errors and improving code quality.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Improved Code Readability:&lt;/strong&gt; Custom types make code more self-documenting, enhancing understanding and collaboration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Employing custom types with validation in Go is a best practice for developing robust, secure, and maintainable applications. This approach is particularly valuable in scenarios demanding high data integrity, such as financial systems or healthcare applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional Considerations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Thorough Testing:&lt;/strong&gt; Rigorous testing of custom types, especially the &lt;code&gt;Set&lt;/code&gt; method, is crucial to ensure validation works as expected.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Meaningful Error Handling:&lt;/strong&gt; Provide informative error messages to aid in debugging and troubleshooting.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Contextual Adaptation:&lt;/strong&gt; Tailor validation logic to specific use cases, such as command-line arguments or configuration file parsing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By embracing custom types with validation, you can significantly enhance the quality, security, and reliability of your Go applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete Code Example:&lt;/strong&gt;&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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="c"&gt;// Package flags provides custom flag types&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"strings"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Example is a custom type that implements the flag.Value interface.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="c"&gt;// Example values.&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ArgumentA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"value_a"&lt;/span&gt;
    &lt;span class="n"&gt;ArgumentB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"value_b"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// AllowedOptions is a list of allowed values for the Example type.&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;AllowedOptions&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArgumentA&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="n"&gt;ArgumentB&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

&lt;span class="c"&gt;// String returns the string representation of the Example type.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;String&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="c"&gt;// Return the string representation of the Example type.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Type returns the type name of the Example type.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Type&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="c"&gt;// Return the type name.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Example"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Set validates and sets the value for the Example type.&lt;/span&gt;
&lt;span class="c"&gt;// It returns an error if the value is not allowed.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="kt"&gt;string&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="c"&gt;// Check if the value is allowed.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exampleOption&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;AllowedOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// If the value is allowed, set it and return nil.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;exampleOption&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c"&gt;// Set the value.&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Example&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="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// If the value is not allowed, return an error.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"allowed values: %s"&lt;/span&gt;&lt;span class="p"&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;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AllowedOptions&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Example usage:&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;myExample&lt;/span&gt; &lt;span class="n"&gt;Example&lt;/span&gt;
        &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;myExample&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"value_a"&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;err&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="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Set value:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;myExample&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://golang.org/doc/" rel="noopener noreferrer"&gt;Official Go Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golang.org/doc/effective_go.html" rel="noopener noreferrer"&gt;Effective Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golang.org/doc/articles/slices_usage_and_internals.html" rel="noopener noreferrer"&gt;Go Data Structures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/flag" rel="noopener noreferrer"&gt;Package &lt;code&gt;flag&lt;/code&gt; in Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>development</category>
      <category>compliance</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>Changing an established SSH connection without disconnecting</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Tue, 31 Dec 2024 14:46:28 +0000</pubDate>
      <link>https://forem.com/rafa_mori/changing-an-established-ssh-connection-without-disconnecting-p3c</link>
      <guid>https://forem.com/rafa_mori/changing-an-established-ssh-connection-without-disconnecting-p3c</guid>
      <description>&lt;h1&gt;
  
  
  Understanding SSH Escape Characters
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;SSH (Secure Shell) is a widely used protocol for securing remote terminal sessions. When working with SSH, you may sometimes need to use escape characters to perform specific functions within an SSH session. Understanding how to use these escape characters effectively can significantly improve your SSH experience and troubleshooting capabilities. In this article, we'll explore what escape characters are, how to use them, and provide some practical examples to illustrate their utility.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Escape Character?
&lt;/h2&gt;

&lt;p&gt;An escape character is a special character that allows users to execute certain functions within an SSH session. By default, this character is the tilde &lt;code&gt;~&lt;/code&gt;. To send a single tilde, you can either use &lt;code&gt;~~&lt;/code&gt; or follow the tilde with any character other than the specified functions. The escape character must always be preceded by a newline to be interpreted correctly. You can change this character in configuration files using the &lt;code&gt;EscapeChar&lt;/code&gt; directive or on the command line with the &lt;code&gt;-e&lt;/code&gt; option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Escape Sequences
&lt;/h2&gt;

&lt;p&gt;The following escape sequences are supported when the default tilde &lt;code&gt;~&lt;/code&gt; is used:&lt;/p&gt;

&lt;h3&gt;
  
  
  Command Line Access with &lt;code&gt;~C&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;One of the most powerful escape sequences is &lt;code&gt;~C&lt;/code&gt;, which opens a command line for adding port forwardings using the &lt;code&gt;-L&lt;/code&gt;, &lt;code&gt;-R&lt;/code&gt;, and &lt;code&gt;-D&lt;/code&gt; options. Basic help is also available with the &lt;code&gt;-h&lt;/code&gt; option. Here's how to use it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type &lt;code&gt;Enter~C&lt;/code&gt; (i.e., a capital &lt;code&gt;C&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add your port forwarding command, such as:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-L localport:server:serverport
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace &lt;code&gt;localport&lt;/code&gt;, &lt;code&gt;server&lt;/code&gt;, and &lt;code&gt;serverport&lt;/code&gt; with your desired values, and then press Enter.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Practical Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Example 1: Adding a Port Forwarding
&lt;/h4&gt;

&lt;p&gt;Imagine you need to access a web server running on a remote machine but want to forward it through a local port. You would use the &lt;code&gt;~C&lt;/code&gt; command as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter~C
-L 8080:localhost:80
Enter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will forward the remote web server (port 80) to your local machine's port 8080.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 2: Terminating an SSH Session
&lt;/h4&gt;

&lt;p&gt;If you need to quickly terminate your SSH session, you can use the escape sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter~.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sequence immediately closes the SSH connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timing:&lt;/strong&gt; Choose the right moment to press Enter, as it will be immediately sent to the remote side and may trigger some action there. Do this when you are at a shell prompt with an empty command line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;International Keyboards:&lt;/strong&gt; For internationalized keyboards where the tilde might be a dead key (e.g., pressing &lt;code&gt;~n&lt;/code&gt; to generate &lt;code&gt;ñ&lt;/code&gt;), it might be necessary to press SPACE after the tilde to generate a single tilde, i.e., &lt;code&gt;ENTER~SPACEC&lt;/code&gt;. On Spanish/Latin American keyboard layouts, since there are no combined characters using tilde and &lt;code&gt;C&lt;/code&gt;, the space can be omitted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Multiple Redirections
&lt;/h3&gt;

&lt;p&gt;The SSH escape command line only accepts one command at a time. To enter multiple commands or redirections, you need to press the keyboard sequence again for each new command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enabling &lt;code&gt;~C&lt;/code&gt; in SSH Client v9.2 and Later
&lt;/h3&gt;

&lt;p&gt;For SSH client version 9.2 and later, the &lt;code&gt;~C&lt;/code&gt; command line must be manually enabled using either the &lt;code&gt;-o EnableEscapeCommandline=yes&lt;/code&gt; option or by adding the &lt;code&gt;EnableEscapeCommandline&lt;/code&gt; option in your &lt;code&gt;~/.ssh/config&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fascination of Dynamic Port Forwarding
&lt;/h2&gt;

&lt;p&gt;One of the most intriguing uses of SSH escape characters is the ability to insert port forwardings into already established SSH connections. This functionality, enabled by the &lt;code&gt;~C&lt;/code&gt; escape sequence, allows for dynamic adjustment of port forwardings without the need to restart the SSH session.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why It's Fascinating
&lt;/h3&gt;

&lt;p&gt;This ability is especially valuable in situations where new requirements arise during an active session. Imagine you're connected to a remote server and suddenly need to forward a new port. Instead of terminating the session and starting over, you can seamlessly add the forwarding using the escape sequence.&lt;/p&gt;

&lt;p&gt;Here’s a detailed example:&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Dynamic Port Forwarding
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Establish an SSH Session:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh user@remotehost
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initiate Port Forwarding within the Session:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure you are at a shell prompt with an empty command line.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;Enter~C&lt;/code&gt; to open the escape command line.&lt;/li&gt;
&lt;li&gt;Add the port forwarding command:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nt"&gt;-L&lt;/span&gt; 3306:localhost:3306
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Press Enter.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command dynamically forwards the remote server's port 3306 (typically used by MySQL) to your local machine's port 3306, allowing you to interact with the remote database as if it were local.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Considerations
&lt;/h3&gt;

&lt;p&gt;While dynamic port forwarding is a powerful feature, it comes with security risks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unauthorized Access:&lt;/strong&gt; Be vigilant about who has access to use escape sequences, as they can potentially redirect sensitive ports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring:&lt;/strong&gt; Actively monitor SSH sessions to detect any unauthorized or unusual activity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Management:&lt;/strong&gt; Secure your &lt;code&gt;~/.ssh/config&lt;/code&gt; and related configuration files to prevent unauthorized changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By understanding and leveraging this feature with caution, you can significantly enhance the flexibility and functionality of your SSH sessions. Stay secure and make the most out of your SSH connections!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.openssh.com/manual.html" rel="noopener noreferrer"&gt;Manual Pages - OpenSSH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.man7.org/linux/man-pages/man1/ssh.1.html" rel="noopener noreferrer"&gt;ssh(1) - Linux manual page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/1/ssh" rel="noopener noreferrer"&gt;ssh(1): OpenSSH SSH client - Linux man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>ssh</category>
      <category>learning</category>
    </item>
    <item>
      <title>Kicksecure: Hardening Your Linux System’s Security (Debian Morph)</title>
      <dc:creator>Rafa Mori</dc:creator>
      <pubDate>Sun, 29 Dec 2024 05:17:08 +0000</pubDate>
      <link>https://forem.com/rafa_mori/kicksecure-hardening-your-linux-systems-security-debian-morph-2bf2</link>
      <guid>https://forem.com/rafa_mori/kicksecure-hardening-your-linux-systems-security-debian-morph-2bf2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Enhancing Digital Security with Kicksecure: How to Install and Why You Should Use It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today's digital age, data security is more important than ever. Kicksecure is a security-focused Linux distribution designed to protect your data and privacy. In this article, we will show you how to install &lt;a href="https://www.kicksecure.com/" rel="noopener noreferrer"&gt;Kicksecure&lt;/a&gt; and explain why it is an excellent choice for users who want to strengthen their system's security.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kicksecure?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.kicksecure.com" rel="noopener noreferrer"&gt;Kicksecure&lt;/a&gt;&lt;/strong&gt; is a security-focused Linux distribution based on Debian. It is designed to be secure by default, incorporating a series of security enhancements that help protect the system from various cyber threats. One of Kicksecure’s key features is &lt;strong&gt;kernel hardening&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kernel Hardening?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;kernel&lt;/strong&gt; is the core of the operating system, responsible for managing system resources and enabling communication between hardware and software. &lt;strong&gt;Kernel hardening&lt;/strong&gt; refers to applying various techniques to increase the security of the kernel, making it more resistant to attacks.&lt;/p&gt;

&lt;p&gt;Some of the techniques used in kernel hardening include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access restrictions&lt;/strong&gt;: Limiting the privileges of users and processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory protection&lt;/strong&gt;: Preventing unauthorized access to system memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure code execution&lt;/strong&gt;: Blocking the execution of unauthorized code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These measures make the system less vulnerable to attacks that exploit kernel flaws.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Install Kicksecure?
&lt;/h2&gt;

&lt;p&gt;There are many reasons to choose Kicksecure, but here are the &lt;strong&gt;top three&lt;/strong&gt; in my opinion:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security by Default&lt;/strong&gt;: Kicksecure comes pre-configured with security enhancements, making it secure from the start.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Privacy&lt;/strong&gt;: It protects your data and communications, preventing information leaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Use&lt;/strong&gt;: Despite being highly secure, Kicksecure is designed to be user-friendly, even for those with less experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Before Installing Kicksecure
&lt;/h2&gt;

&lt;p&gt;To increase the chances of a successful installation, it is best to start with a minimal &lt;strong&gt;Debian installation&lt;/strong&gt;. You can choose to install either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A)&lt;/strong&gt; Debian with a graphical user interface (GUI) (&lt;a href="https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-12.8.0-amd64-xfce.iso" rel="noopener noreferrer"&gt;Xfce&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B)&lt;/strong&gt; Debian with a command-line interface (CLI)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the base installation is complete, you can install the Kicksecure meta package as outlined below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: It's easiest to set the user account name as "user" during the installation of Debian &lt;strong&gt;Bookworm&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Considerations for the Distro-Morphing Process
&lt;/h3&gt;

&lt;p&gt;When performing &lt;strong&gt;&lt;a href="https://www.kicksecure.com/wiki/Distribution_Morphing" rel="noopener noreferrer"&gt;Distro-Morphing&lt;/a&gt;&lt;/strong&gt;, the user should be aware of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No user account creation&lt;/strong&gt;: The process does not create user or admin accounts. You can continue using your existing user accounts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No password changes&lt;/strong&gt;: No passwords for any existing user accounts will be modified. This means passwords for Full Disk Encryption (pre-boot authentication), sudo, su, login, etc., will remain the same.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No root account locking&lt;/strong&gt;: The password for the root account will not be locked. If desired, the user can manually disable the root account for better security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autologin&lt;/strong&gt;: The &lt;strong&gt;usability-misc&lt;/strong&gt; package will set up auto-login for the "user" account on LightDM, Kicksecure's default login manager at the time of writing. Auto-login can be disabled by following the &lt;a href="https://www.kicksecure.com/wiki/Desktop#Disable_Autologin" rel="noopener noreferrer"&gt;documentation for disabling autologin&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing Kicksecure (&lt;a href="https://www.kicksecure.com/wiki/Distribution_Morphing" rel="noopener noreferrer"&gt;Distro-Morphing Method&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Let’s start with the installation process. First, you'll need to become the &lt;strong&gt;root&lt;/strong&gt; user.&lt;/p&gt;

&lt;p&gt;To do this, run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;su
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If running &lt;code&gt;su&lt;/code&gt; alone doesn’t work (depending on how Debian was installed), try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo su
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, ensure the following basic tools are installed on your system before proceeding. Here is the full list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adduser&lt;/li&gt;
&lt;li&gt;console&lt;/li&gt;
&lt;li&gt;console-data&lt;/li&gt;
&lt;li&gt;console-common&lt;/li&gt;
&lt;li&gt;kbd&lt;/li&gt;
&lt;li&gt;keyboard-configuration&lt;/li&gt;
&lt;li&gt;extrepo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you have the basics covered, let's walk through the installation process step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Update the Package Lists
&lt;/h3&gt;

&lt;p&gt;To begin, update your package lists to ensure your system is aware of the latest available software:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Upgrade the System
&lt;/h3&gt;

&lt;p&gt;Next, upgrade your system to make sure all your installed packages are up to date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt full-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Install Essential Packages
&lt;/h3&gt;

&lt;p&gt;Install &lt;code&gt;sudo&lt;/code&gt; and &lt;code&gt;adduser&lt;/code&gt; packages, which are necessary for configuring user permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt install --no-install-recommends sudo adduser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Sudo Configuration (Optional)
&lt;/h3&gt;

&lt;p&gt;If you'd like to allow the user to run &lt;code&gt;sudo&lt;/code&gt; commands without entering a password, follow one of these methods:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;adduser Method&lt;/strong&gt;:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add your user to the sudo group:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/sbin/adduser user sudo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reboot your system:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/sbin/reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;file Method&lt;/strong&gt;:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Securely create the file &lt;code&gt;/etc/sudoers.d/user.conf&lt;/code&gt; using &lt;code&gt;visudo&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "user ALL=(ALL:ALL) NOPASSWD:ALL" | EDITOR=tee visudo -f /etc/sudoers.d/nopassword &amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Create the Console Group
&lt;/h3&gt;

&lt;p&gt;Create a system group named &lt;code&gt;console&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;/usr/sbin/addgroup --system console
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Add User to Console Group
&lt;/h3&gt;

&lt;p&gt;Add your user to the &lt;code&gt;console&lt;/code&gt; group (replace "user" with your actual username):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/sbin/adduser user console
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Install Console-Related Packages
&lt;/h3&gt;

&lt;p&gt;Install the necessary console-related packages. This step may also remove the unsupported &lt;strong&gt;plymouth&lt;/strong&gt;, which is a positive outcome for security purposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install console-data console-common kbd keyboard-configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Install the &lt;code&gt;extrepo&lt;/code&gt; Package
&lt;/h3&gt;

&lt;p&gt;Install the &lt;code&gt;extrepo&lt;/code&gt; package to enable external repositories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install extrepo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9. Enable the Kicksecure APT Repository
&lt;/h3&gt;

&lt;p&gt;Enable the stable Kicksecure APT repository using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo extrepo enable kicksecure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10. Install Kicksecure Packages
&lt;/h3&gt;

&lt;p&gt;Finally, install the &lt;strong&gt;Kicksecure&lt;/strong&gt; package for your desktop environment. For this guide, we will use the Xfce environment, which is known for its lightweight nature and low resource consumption. To install the &lt;strong&gt;Kicksecure Xfce Host&lt;/strong&gt; package, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install --no-install-recommends kicksecure-xfce-host
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11. Update and Upgrade Again
&lt;/h3&gt;

&lt;p&gt;It’s always a good practice to run an update and full-upgrade after adding new repositories and packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt full-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Kicksecure is an Excellent Choice
&lt;/h2&gt;

&lt;p&gt;Kicksecure is a fantastic option for anyone looking to bolster their system's security with &lt;strong&gt;hardening&lt;/strong&gt; techniques and enjoy a &lt;strong&gt;secure workspace&lt;/strong&gt;. Here are some key reasons why it stands out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hardening Made Easy&lt;/strong&gt;: Kicksecure offers a pre-configured, secure-by-default environment that is specifically designed for those who value security. It’s one of the most robust distributions for those looking to minimize vulnerabilities and ensure their system is hardened against cyber threats.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Xfce4: Lightweight and Efficient&lt;/strong&gt;: One of the most notable aspects of Kicksecure is that it uses &lt;strong&gt;Xfce4&lt;/strong&gt;, a highly lightweight desktop environment. Xfce4 is known for its low resource usage, making it a great choice for users who want a fast and responsive system without sacrificing performance. It’s an ideal environment for both experienced users and newcomers alike, ensuring smooth operation even on older hardware.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security Without Compromise&lt;/strong&gt;: Kicksecure focuses on providing a secure operating environment without sacrificing usability. Its hardened kernel, combined with a simple yet powerful desktop experience, makes it an excellent choice for those who need enhanced security but also want a comfortable&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>debian</category>
    </item>
  </channel>
</rss>
