<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shahar Shalev</title>
    <description>The latest articles on DEV Community by Shahar Shalev (@shaharking).</description>
    <link>https://dev.to/shaharking</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%2F1136501%2F6de3485c-488f-4379-99a0-221a04f7f41f.jpeg</url>
      <title>DEV Community: Shahar Shalev</title>
      <link>https://dev.to/shaharking</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shaharking"/>
    <language>en</language>
    <item>
      <title>From Chaos to Clarity: Tracing Your Flows Like a Pro with Powerful Log Techniques</title>
      <dc:creator>Shahar Shalev</dc:creator>
      <pubDate>Tue, 15 Aug 2023 15:48:51 +0000</pubDate>
      <link>https://dev.to/shaharking/from-chaos-to-clarity-tracing-your-flows-like-a-pro-with-powerful-log-techniques-1d9e</link>
      <guid>https://dev.to/shaharking/from-chaos-to-clarity-tracing-your-flows-like-a-pro-with-powerful-log-techniques-1d9e</guid>
      <description>&lt;p&gt;I recently received a bug report from a client, and I struggled to locate the logs that described what occurred; sometimes, even when you have logs, you don’t make it simple enough to trace the issues.&lt;br&gt;&lt;br&gt;
In this blog post, I’ll give you some simple tips for how to trace your flows and handle fan-in and fan-out processes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Simple case — 1:1 — Request-Id
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwne9ne1g5oym5i2kebf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwne9ne1g5oym5i2kebf9.png" alt="Example of simple flow passing the request-id from one process to another"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The simplest scenario is when an API creates sub-tasks or sub-processes.&lt;br&gt;
To keep track of the entire flow, we can create a &lt;strong&gt;Request-Id (random uuid)&lt;/strong&gt; and pass it along the way.&lt;br&gt;
Don’t forget to include the request-Id in the response.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fan-Out — 1:N — Multiple Request-Ids
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gnweh2itbwykr38pvwl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gnweh2itbwykr38pvwl.png" alt="The main process creates multiple new request-ids for each subprocess"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a Fan-Out process, you have a main process that generates a number of sub-processes, and you need to track each one of them.&lt;br&gt;
For each sub-process, create a new request-id, and then log both the old and the new request-id.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbm7ixs2hn7r5ubd69bj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbm7ixs2hn7r5ubd69bj.png" alt="Show that you also log the previous and the new request-id"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Fan-In — N:1
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tisto5mct5hejglybla.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tisto5mct5hejglybla.png" alt="Fan-in flow you create new request-id for all the subprocess"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a Fan-In process, you have several sub-processes that are combined together into a single new process.&lt;br&gt;
For the new process create a new Request-Id and log both the old and the new request-id.&lt;/p&gt;
&lt;h3&gt;
  
  
  Log Aggregation
&lt;/h3&gt;

&lt;p&gt;We know how to track our processes, but what do we actually try to monitor?&lt;br&gt;
In a fan-out flow, we might be interested in tracking the status of each subprocess (success or failure).&lt;/p&gt;

&lt;p&gt;For monitoring the flow in each of our logs we will use a combination of &lt;code&gt;logId&lt;/code&gt; and &lt;code&gt;requestId&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pm65ygxm9fdo5p5x583.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pm65ygxm9fdo5p5x583.png" alt="Example of logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we can aggregate the data and turn it into a table that shows the status of our request-ids.&lt;br&gt;
Some columns will be aggregated with the latest value, and some columns might be contacted together, summed, or averaged.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr80lbd9utvwngsx0pikr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr80lbd9utvwngsx0pikr.png" alt="Take the logs and aggregate them into a table with summary"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, statistics for each flow can be generated, giving insight into error distributions.&lt;br&gt;
These statistics can be used as benchmarks to detect errors automatically when they notice higher-than-normal occurrences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e734pli3e4iiz64wqz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e734pli3e4iiz64wqz2.png" alt="Create error distributions table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip:&lt;br&gt;&lt;br&gt;
Make a class out of all the shared logs to make it easier to expand and use them consistently, as well as to offer type safety and other benefits.&lt;/p&gt;

&lt;p&gt;It might look something like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./logger-service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;FlowAStatusInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;requestId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FAILED_REASON_A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FAILED_REASON_B&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="c1"&gt;// Other attributes&lt;/span&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logFlowAStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FLOW_A_STATUS_INPUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="na"&gt;logId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FLOW_A_STATUS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;input&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;



</description>
    </item>
  </channel>
</rss>
