<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>&#x2F;dev&#x2F;notes&#x2F;www</title>
      <link>https://norbi0801.github.io</link>
      <description>Full-time developer</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://norbi0801.github.io/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Mon, 06 Apr 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Conventional commits - why and how to write meaningful commit messages</title>
          <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://norbi0801.github.io/blog/conventional-commits-why-and-how-to-write-meaningful-commi/</link>
          <guid>https://norbi0801.github.io/blog/conventional-commits-why-and-how-to-write-meaningful-commi/</guid>
          <description xml:base="https://norbi0801.github.io/blog/conventional-commits-why-and-how-to-write-meaningful-commi/">&lt;p&gt;Open any long-lived project you haven&#x27;t touched in six months. Run &lt;code&gt;git log --oneline&lt;&#x2F;code&gt;. What do you see?&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;a1b2c3d fixed stuff
&lt;&#x2F;span&gt;&lt;span&gt;e4f5g6h updates
&lt;&#x2F;span&gt;&lt;span&gt;h7i8j9k wip
&lt;&#x2F;span&gt;&lt;span&gt;l0m1n2o more fixes
&lt;&#x2F;span&gt;&lt;span&gt;p3q4r5s asdf
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Congratulations, your git history is a write-only data structure. Nobody - including future you - will ever extract useful information from it.&lt;&#x2F;p&gt;
&lt;p&gt;Now compare that with a project that uses &lt;a href=&quot;https:&#x2F;&#x2F;www.conventionalcommits.org&#x2F;en&#x2F;v1.0.0&#x2F;&quot;&gt;Conventional Commits&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;a1b2c3d feat(auth): add OAuth2 PKCE flow for mobile clients
&lt;&#x2F;span&gt;&lt;span&gt;e4f5g6h fix(parser): handle escaped quotes in string literals
&lt;&#x2F;span&gt;&lt;span&gt;h7i8j9k docs: update API reference for v3 endpoints
&lt;&#x2F;span&gt;&lt;span&gt;l0m1n2o refactor(db): extract connection pooling into shared module
&lt;&#x2F;span&gt;&lt;span&gt;p3q4r5s feat!: replace session tokens with JWT
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every line tells you &lt;em&gt;what changed&lt;&#x2F;em&gt;, &lt;em&gt;where it changed&lt;&#x2F;em&gt;, and &lt;em&gt;why it matters&lt;&#x2F;em&gt;. The exclamation mark on the last one screams &quot;breaking change&quot; before you even read the description. That&#x27;s the point of Conventional Commits - turning your commit history from noise into signal.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Load testing your Rust API - tools and methodology</title>
          <pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://norbi0801.github.io/blog/load-testing-your-rust-api-tools-and-methodology/</link>
          <guid>https://norbi0801.github.io/blog/load-testing-your-rust-api-tools-and-methodology/</guid>
          <description xml:base="https://norbi0801.github.io/blog/load-testing-your-rust-api-tools-and-methodology/">&lt;p&gt;Your Rust API compiles, the tests pass, and a quick curl returns the right JSON. Ship it? Not yet. You have no idea how it behaves when 500 users hit it at the same time. Or 5,000. Or when a steady stream of requests runs for 12 hours straight and that connection pool you configured starts leaking.&lt;&#x2F;p&gt;
&lt;p&gt;Load testing is how you find out before your users do. Rust gives you a strong starting position here - no garbage collector pauses, predictable memory usage, real threads via tokio - but &quot;fast language&quot; does not mean &quot;fast system.&quot; A badly tuned database pool, a blocking call on the async runtime, or an O(n^2) serialization path will still bring your API to its knees.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers the practical side: which tools to use, what patterns of load to apply, what numbers to watch, and how to figure out whether your bottleneck is CPU, I&#x2F;O, or something else entirely.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Logging vs tracing vs metrics - the three pillars of observability</title>
          <pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://norbi0801.github.io/blog/logging-vs-tracing-vs-metrics-the-three-pillars-of-observa/</link>
          <guid>https://norbi0801.github.io/blog/logging-vs-tracing-vs-metrics-the-three-pillars-of-observa/</guid>
          <description xml:base="https://norbi0801.github.io/blog/logging-vs-tracing-vs-metrics-the-three-pillars-of-observa/">&lt;p&gt;Your service is running. Users are making requests. Then someone reports that checkout is slow. Or worse, Slack lights up with &quot;is the API down?&quot; and you&#x27;re staring at a terminal with no idea what&#x27;s happening inside your own system.&lt;&#x2F;p&gt;
&lt;p&gt;You check the logs. There are thousands of lines, most useless. You look at your monitoring dashboard - oh wait, you don&#x27;t have one. You try to figure out which service is causing the slowdown, but you have no way to follow a request across service boundaries.&lt;&#x2F;p&gt;
&lt;p&gt;This is the gap observability fills. Not just &quot;can I see logs&quot; but &quot;can I understand what my system is doing right now, and why it&#x27;s doing it badly.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;There are three fundamental signal types that give you this understanding: logs, metrics, and traces. Each answers a different question. None replaces the others. Getting all three right - and knowing when to use which - is the difference between debugging in minutes and debugging in hours.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Rust Macros 101 - Declarative Macros with macro_rules!</title>
          <pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://norbi0801.github.io/blog/rust-macros-101-declarative-macros-with-macrorules/</link>
          <guid>https://norbi0801.github.io/blog/rust-macros-101-declarative-macros-with-macrorules/</guid>
          <description xml:base="https://norbi0801.github.io/blog/rust-macros-101-declarative-macros-with-macrorules/">&lt;p&gt;Before you reach for proc macros, &lt;code&gt;syn&lt;&#x2F;code&gt;, and &lt;code&gt;quote&lt;&#x2F;code&gt; - there&#x27;s an entire code generation system built into the language that requires zero dependencies and compiles in milliseconds. Declarative macros with &lt;code&gt;macro_rules!&lt;&#x2F;code&gt; are Rust&#x27;s pattern-matching code generator. They&#x27;re not as flexible as proc macros, but they cover a surprising amount of ground, and understanding them is a prerequisite for understanding the rest of the macro ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers how &lt;code&gt;macro_rules!&lt;&#x2F;code&gt; actually works - the matching rules, repetitions, hygiene model, and the sharp edges you&#x27;ll hit. We&#x27;ll build three practical macros along the way.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Debugging Rust Beyond println!</title>
          <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://norbi0801.github.io/blog/debugging-rust-beyond-println/</link>
          <guid>https://norbi0801.github.io/blog/debugging-rust-beyond-println/</guid>
          <description xml:base="https://norbi0801.github.io/blog/debugging-rust-beyond-println/">&lt;p&gt;Every Rust developer&#x27;s first debugger is &lt;code&gt;println!&lt;&#x2F;code&gt;. It works. You sprinkle it around, recompile, squint at the output, add more prints, recompile again. Eventually you find the bug, delete the print statements, and move on. But this gets painful fast - especially with async code, macro-heavy codebases, or bugs that only show up under specific conditions.&lt;&#x2F;p&gt;
&lt;p&gt;Rust ships with a surprisingly good debugging story that most developers never fully explore. This post walks through the tools and techniques that replaced most of my &lt;code&gt;println!&lt;&#x2F;code&gt; usage, organized by the type of problem they solve best.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>MCP Audit - building and publishing a security scanner in Rust</title>
          <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://norbi0801.github.io/blog/mcp-audit/</link>
          <guid>https://norbi0801.github.io/blog/mcp-audit/</guid>
          <description xml:base="https://norbi0801.github.io/blog/mcp-audit/">&lt;p&gt;I&#x27;ve been working with MCP (Model Context Protocol) servers a lot recently - building tools, integrating them with Claude, configuring them for different projects. At some point I realized how easy it is to misconfigure these things. One wrong path and an AI agent has access to your entire filesystem. One hardcoded API key in your config and it&#x27;s exposed to anyone who sees your dotfiles.&lt;&#x2F;p&gt;
&lt;p&gt;So I built &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Norbi0801&#x2F;mcp-audit&quot;&gt;mcp-audit&lt;&#x2F;a&gt; - a CLI tool that scans MCP configurations for security issues.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
