<?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: Jeff Dwyer</title>
    <description>The latest articles on DEV Community by Jeff Dwyer (@jdwyah).</description>
    <link>https://dev.to/jdwyah</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%2F1068646%2Fff9e4009-9eff-40f8-8bbf-6631d150c318.jpg</url>
      <title>DEV Community: Jeff Dwyer</title>
      <link>https://dev.to/jdwyah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jdwyah"/>
    <language>en</language>
    <item>
      <title>VSCode Plugin For Feature Flags</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Fri, 17 Nov 2023 20:45:59 +0000</pubDate>
      <link>https://dev.to/jdwyah/vscode-plugin-for-feature-flags-2mh5</link>
      <guid>https://dev.to/jdwyah/vscode-plugin-for-feature-flags-2mh5</guid>
      <description>&lt;p&gt;There's nothing like a cool editor extension. I'm so excited that I can edit feature flags right in VSCode. We thought about what would be cool and here are 3 things we came up with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autocomplete for Feature Flags:&lt;/strong&gt; No more typos leading to bugs! Get suggestions for flag names as you type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hover to Know:&lt;/strong&gt; Curious about a feature flag's status? Just hover over it in your code to see its current settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personal Overrides:&lt;/strong&gt; Test flags in your local setup without messing with the team's settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kL4zT7rv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp1w63h92bqt6i6vtmcl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kL4zT7rv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp1w63h92bqt6i6vtmcl.gif" alt="Autocomplete feature flag names" width="640" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're interested to learn how we did this, check out &lt;a href="https://www.prefab.cloud/blog/lsp-language-server-from-zero-to-completion/"&gt;Hands-On LSP Tutorial: Building a Custom Auto-Complete&lt;/a&gt; which takes you step by step through adding an autocomplete of your own to VSCode.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>ruby</category>
      <category>react</category>
    </item>
    <item>
      <title>Feature Flag &amp; Dynamic Log features we shipped this summer</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Fri, 15 Sep 2023 16:17:44 +0000</pubDate>
      <link>https://dev.to/jdwyah/feature-flag-dynamic-log-features-we-shipped-this-summer-55p1</link>
      <guid>https://dev.to/jdwyah/feature-flag-dynamic-log-features-we-shipped-this-summer-55p1</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/m0_-VMiKIak"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Tagged Logging vs Structured Logging</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Wed, 13 Sep 2023 17:07:58 +0000</pubDate>
      <link>https://dev.to/jdwyah/tagged-logging-vs-structured-logging-3mbc</link>
      <guid>https://dev.to/jdwyah/tagged-logging-vs-structured-logging-3mbc</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Tagged vs. Structured Logging
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What's Tagged Logging?
&lt;/h3&gt;

&lt;p&gt;Tagged logging allows you to prepend tags to your log messages. For instance, using &lt;a href="https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html"&gt;ActiveSupport::TaggedLogging&lt;/a&gt;, you can tag logs with "Auth API" or user IDs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Permissions&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tagged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Auth API"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://auth.example.com/permissions/?user=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"Fetching &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;permissions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"Got permissions &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Log Output&lt;/span&gt;
&lt;span class="c1"&gt;#[Auth API] Fetching https://auth.example.com/permissions/?user=bob&lt;/span&gt;
&lt;span class="c1"&gt;#[Auth API] Got permissions admin, writer, reader&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enhances log readability.&lt;/li&gt;
&lt;li&gt;Avoids repetition by tagging once for multiple log lines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not machine-friendly. While the text version looks good, the JSON format can be confusing, especially when searching for specific tags.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Structured Logging: A Better Alternative?
&lt;/h3&gt;

&lt;p&gt;Structured logging provides a more organized way to log messages. Instead of tagging, you structure your logs with key-value pairs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;team: &lt;/span&gt;&lt;span class="s2"&gt;"The best team"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;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;Text Log:
INFO hello user=1, team=The Best Team

JSON Log:
{severity: INFO, message: "hello", user: 1, team: "The Best Team"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is more machine-readable and fits better with modern log aggregators.&lt;/p&gt;

&lt;h3&gt;
  
  
  Libraries Supporting Structured Logging:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zormandi/logcraft"&gt;logcraft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tilfin/ougai"&gt;ougai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reidmorrison/semantic_logger"&gt;semantic_logger&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: &lt;a href="https://github.com/roidrage/lograge"&gt;Lograge&lt;/a&gt; offers structured logs for Rails requests but lacks custom structuring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why I Wrote This
&lt;/h3&gt;

&lt;p&gt;I'm building a &lt;a href="https://prefab.cloud/features/log-levels/"&gt;dynamic log library&lt;/a&gt; and wanted to understand the best approaches to structured and tagged logging. &lt;/p&gt;

&lt;h3&gt;
  
  
  In Summary:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tagged logging is user-friendly but not machine-friendly.&lt;/li&gt;
&lt;li&gt;Structured logging offers a more organized and machine-readable approach.&lt;/li&gt;
&lt;li&gt;Tagged logging does have nice nesting behavior, though you can achieve that with the semantic logger gem as well.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Thoughts on: Time-traveling Ruby Logger</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Fri, 11 Aug 2023 19:37:45 +0000</pubDate>
      <link>https://dev.to/jdwyah/thoughts-on-time-traveling-ruby-logger-110a</link>
      <guid>https://dev.to/jdwyah/thoughts-on-time-traveling-ruby-logger-110a</guid>
      <description>&lt;p&gt;I've been thinking a lot about application context, the core things that our application knows: the current user, the instance it's running on, details about the request. &lt;/p&gt;

&lt;p&gt;Pretty often we know all of the context right up front and the beginning of a request, but sometimes we don't figure out this context until later in the request. Sometimes this is annoying. It might be nice to log things details of the request along with the userID at the beginning of a request, but we don't actually know the userID right at the beginning. Or we might want to log more details of the processing, but only if the request errors later on. &lt;/p&gt;

&lt;p&gt;I like the ideas in: &lt;a href="https://prefab.cloud/blog/ruby-logging-time-travel/"&gt;Time-traveling Ruby Logger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wonder if there are other ways to extends this thinking. The buffer is a bit like a promise queue that will get called later with more information. I'm curious if this gets other peoples' thoughts flowing too.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>7 Ruby Feature Flag Tools Compared</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Wed, 07 Jun 2023 14:05:56 +0000</pubDate>
      <link>https://dev.to/jdwyah/7-ruby-feature-flag-tools-compared-ljm</link>
      <guid>https://dev.to/jdwyah/7-ruby-feature-flag-tools-compared-ljm</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/krMGitoo94A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>featureflags</category>
    </item>
    <item>
      <title>How many log levels are there?</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Tue, 25 Apr 2023 16:02:10 +0000</pubDate>
      <link>https://dev.to/jdwyah/how-many-log-levels-are-there-5gp0</link>
      <guid>https://dev.to/jdwyah/how-many-log-levels-are-there-5gp0</guid>
      <description>&lt;p&gt;I'm building a tool to allow you to &lt;a href="https://www.prefab.cloud/features/log-levels/"&gt;change the log levels&lt;/a&gt; of your application at runtime. In order to do that, I need to show you a dropdown of the various log levels. Something like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ET5Kz0kw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j66x3ppvxcxj2z7xs3dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ET5Kz0kw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j66x3ppvxcxj2z7xs3dm.png" alt="Change your log level without restarting" width="400" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I started with Ruby so I put in &lt;code&gt;DEBUG&lt;/code&gt; &lt;code&gt;INFO&lt;/code&gt;WARN &lt;code&gt;ERROR&lt;/code&gt; &lt;code&gt;FATAL&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Of course, then I wanted to do it for Java, so I had to add &lt;code&gt;TRACE&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Then Python wanted &lt;code&gt;CRITICAL&lt;/code&gt; so...  spreadsheet time. &lt;/p&gt;

&lt;p&gt;Here's the sheet I ended up with. It was a fun tour. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hDzC-HKZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0q4scbqja3r4dlpsd26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hDzC-HKZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0q4scbqja3r4dlpsd26.png" alt="Grid of all log levels available in top languages" width="800" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wrote up some details and ideas / humor about why I think each language chose what it chose &lt;a href="https://www.prefab.cloud/blog/so-many-levels/"&gt;here&lt;/a&gt;, but just take a look at the grid, I was surprised by how many there are. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>ruby</category>
      <category>java</category>
      <category>python</category>
    </item>
    <item>
      <title>A Gotcha With Gauges</title>
      <dc:creator>Jeff Dwyer</dc:creator>
      <pubDate>Mon, 24 Apr 2023 00:10:57 +0000</pubDate>
      <link>https://dev.to/jdwyah/a-gotcha-with-gauges-3aad</link>
      <guid>https://dev.to/jdwyah/a-gotcha-with-gauges-3aad</guid>
      <description>&lt;p&gt;I had a gotcha recently trying to use a Gauge metric that I wanted to share. &lt;/p&gt;

&lt;p&gt;I love metrics and I use &lt;a href="https://micrometer.io/"&gt;Micrometer&lt;/a&gt; as a Facade for them. &lt;/p&gt;

&lt;p&gt;Typical usage looks like the following, although you can also annotate a method with &lt;code&gt;@Timed&lt;/code&gt; which is delightful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;SimpleMeterRegistry&lt;/span&gt; &lt;span class="n"&gt;oneSimpleMeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SimpleMeterRegistry&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"page.visitors"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"20s"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I typically use counters and timers and they have always been pretty straightforward. &lt;/p&gt;

&lt;p&gt;We're building a system for &lt;a href="https://www.prefab.cloud/features/config/"&gt;dynamic config&lt;/a&gt; now and as part of that I wanted to track the current number of connections. Counters and Timers aren't right for this sort of thing however, what I needed was a Gauge, which should work right out of the box.  &lt;/p&gt;

&lt;p&gt;I did something like the following and thought that would be it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConnectionHolder&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;AtomicInteger&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Inject&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ConnectionHolder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MeterRegistry&lt;/span&gt; &lt;span class="n"&gt;meterRegistry&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;connections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;meterRegistry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;gauge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"config.project-connections"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;Tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AtomicInteger&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Scheduled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fixedDelay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1m"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;recordConnections&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;projectConnections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calculateConnections&lt;/span&gt;&lt;span class="o"&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;I made 2 connections to test it out and looked at the metrics. I was very surprised to see my numbers all over the place! Sometimes zero, sometimes one, sometimes 2. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Trying to use Gauges exposed a setup problem in my DataDog metrics. The core issue is that Gauges are not additive in the same way as Counters. Here's what I mean: &lt;br&gt;
If server A writes a metric &lt;code&gt;counter:apples=2&lt;/code&gt; &lt;br&gt;
And server B writes a metric &lt;code&gt;counter:apples=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Both of those metrics will be saved in the time period and we can add those together and get 3. &lt;/p&gt;

&lt;p&gt;Gauges however, are stored differently.&lt;br&gt;&lt;br&gt;
If server A writes a metric &lt;code&gt;gauge:apples=2&lt;/code&gt; &lt;br&gt;
And server B writes a metric &lt;code&gt;gauge:apples=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The metrics backend will only store the most recent value: &lt;code&gt;gauge:apples=1&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In my case, this meant we had a minute by minute race conditions between the two running pods.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;The solution is proper metric tagging. We need each server to be tagging the result as having come from it. This prevents the backend from clobbering our values here.&lt;br&gt;&lt;br&gt;
&lt;code&gt;gauge:apples=2,pod:abc123&lt;/code&gt;&lt;br&gt;
&lt;code&gt;gauge:apples=1,pod:xyz789&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The problem in my case was that DataDog was not sending stats through my Datadog sidecar and was sending them straight to the Datadog API, which bypassed the functioning tagging process that was working for APM.  &lt;/p&gt;

&lt;p&gt;For more info, there are &lt;a href="https://www.prefab.cloud/blog/gauge-metrics-datadog-and-kubernetes/"&gt;full details&lt;/a&gt; in this post, which gets into the details of passing the pod ID into the containers and setting the tagging explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;You can forget about the underlying way that stats are collected with counters, but gauges are less forgiving. Keep that in mind and happy counting. &lt;/p&gt;

</description>
      <category>java</category>
      <category>development</category>
    </item>
  </channel>
</rss>
