<?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: Pete Cheslock</title>
    <description>The latest articles on DEV Community by Pete Cheslock (@petecheslock).</description>
    <link>https://dev.to/petecheslock</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%2F909799%2F91472855-774c-4564-8a9f-9e556e277848.jpeg</url>
      <title>DEV Community: Pete Cheslock</title>
      <link>https://dev.to/petecheslock</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/petecheslock"/>
    <language>en</language>
    <item>
      <title>Beyond Code Completion: Better Prompt Context to Supercharge Your AI Coding Workflow</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Tue, 12 Mar 2024 13:59:26 +0000</pubDate>
      <link>https://dev.to/appmap/beyond-code-completion-better-prompt-context-to-supercharge-your-ai-coding-workflow-16ob</link>
      <guid>https://dev.to/appmap/beyond-code-completion-better-prompt-context-to-supercharge-your-ai-coding-workflow-16ob</guid>
      <description>&lt;p&gt;AI code completion tools like GitHub Copilot have revolutionized the way we write code. These tools not only speed up coding tasks but also help in adding features and fixing bugs more efficiently.&lt;/p&gt;

&lt;p&gt;This post will show you how I use tracing, sequence diagrams, and other personal observability data with Generative AI, via a RAG (Retrieval-Augmented Generation) model to get better AI guidance for application development. Imagine feeding AI observability data like traces, performance timing, sequence diagrams, API calls, and other information that maps out your application’s interactions. The result? A hyper-personalized instructional guide on how your application operates and code suggestions empowering you to make informed decisions like a senior staff engineer or software architect.&lt;/p&gt;

&lt;p&gt;With the strategic use of AI and runtime data, the path from code suggestion to architecture suggestion becomes not just accessible, but intuitive. This is more than AI coding assistance; it's creating a development process where information is synthesized and presented to you to elevate your code decision making and expertise within your group.&lt;br&gt;
How could you quickly become an expert on your codebase? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s show you how this works.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Shifting your AI from Code Suggestions to Thinking Partner
&lt;/h2&gt;

&lt;p&gt;There are many tools that will statically index your code base and send them as context to the AI to provide code suggestions about your codebase. But there is still a big missing piece of context for generative AI coding assistants that can sometimes lead to bad code suggestions.  Tools like Copilot and other AI coding assistants don’t know anything about your application when it runs.  This results in between 50-70% of code suggestions being rejected by developers.&lt;/p&gt;

&lt;p&gt;Adding tracing data to AI generated prompts can improve the quality of code suggestions.  It can also help you get answers to different kinds of questions from generative AI coding tools which are trained on static open source code.&lt;/p&gt;

&lt;p&gt;You can follow this process with any large token AI system like Claude by identifying tracing data relevant to the code you are working on, using it as context to prompt OpenAI or other LLMs. Generally, you’d generate tracing data by implementing &lt;a href="https://opentelemetry.io/"&gt;OpenTelemetry&lt;/a&gt; (aka OTEL) libraries into your application, adding spans to your functions with Jaeger, or using commercial SaaS tools like Honeycomb and Datadog. &lt;/p&gt;

&lt;p&gt;In this example, I’ll use &lt;a href="//appmap.io"&gt;AppMap&lt;/a&gt; to generate tracing data and other runtime data about my code in my code editor. This will provide a structured way of describing how my code executes when it runs.&lt;/p&gt;

&lt;p&gt;I will also use &lt;a href="https://appmap.io/docs/navie"&gt;Navie&lt;/a&gt;, the AI integration for LLMs from AppMap. By default, Navie uses OpenAI GPT-4 integration with pre-programmed prompts to consider runtime data. I will feed the AI a combination of code snippets, traces, and sequence diagrams as context of this particular code interaction I am working on.  &lt;/p&gt;

&lt;p&gt;In this case I’ve installed AppMap installed into a python powered web store which uses Django.&lt;/p&gt;

&lt;p&gt;To get tracing data I use &lt;a href="https://appmap.io/docs/setup-appmap-in-your-code-editor/generate-appmaps-with-request-recording.html"&gt;Request Recording&lt;/a&gt; to generate an individual sequence diagram for every API request I make. With the libraries installed, and by simply interacting with my application I get a complete view of the entire code sequence automatically without having to spend any additional work adding telemetry, traces, or spans to my code. &lt;/p&gt;

&lt;p&gt;You could also use OTEL to instrument your app and capture similar data. But generally there is a larger development effort in identifying where in the code you need to add spans and traces too. The advantage of AppMap’s traces is that they are created without having to modify the codebase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrrvh6w238640rh9vqda.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrrvh6w238640rh9vqda.gif" alt="request-recording" width="640" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we’ve got some detailed traces and sequence diagrams and other runtime data. I could spend time looking through them to get a better understanding of how my new user registration process works, but instead let’s ask a question to our AI assistant, Navie.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Runtime data gives AI new powers to answer questions about how apps work
&lt;/h2&gt;

&lt;p&gt;So using runtime data, let’s ask new kinds of questions beyond “how does this code work”.  Let’s ask “how  does this feature” or “how does this service works”, starting with the registration service. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mj8obe9cuueydef3j8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mj8obe9cuueydef3j8d.png" alt="ask a question to navie" width="800" height="897"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI has detailed information about the code and how the app works, so when you include code in the prompt to GenAI you can understand the code in the context of the app. This is in contrast to a generic explanation of what the code does using an internet search and static analysis as the only source of information.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnu11rvbgli0b7t4hauv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnu11rvbgli0b7t4hauv.png" alt="navie response" width="800" height="1089"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I’ve learned how this API endpoint works, from API down to the database with runtime data. &lt;/p&gt;

&lt;p&gt;So now my AI has context, and I can go further and do things like ask it to implement a new captcha service.  I will get a very detailed solution that is relevant to my codebase. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdsi3igei647vs7iltf4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbdsi3igei647vs7iltf4.png" alt="Navie response" width="800" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because the GenAI now has the sequence diagram and the specific functions and code snippets for the API interaction, it’s able to tell me exactly what files to go to and what functions to change. &lt;/p&gt;

&lt;p&gt;And now when searching for that function in my code editor:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66y0riohswioevqizhnp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66y0riohswioevqizhnp.png" alt="search for class" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know exactly where to go to add this line to which file. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ra4hxem223oc7e2ek5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ra4hxem223oc7e2ek5b.png" alt="relevant function" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why can’t I just use Copilot or GPT-4 directly?
&lt;/h2&gt;

&lt;p&gt;Now what would happen if I just asked Copilot or GPT-4 directly for information about how to add this simple captcha feature to my app? Even though tools like Copilot have ways of using your “workspace” as context in the question, it has no idea how the code runs and thus you would only get generic answers based on existing public knowledge.&lt;/p&gt;

&lt;p&gt;For example this response from Copliot. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatzypaf4npxcoj4mvzqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatzypaf4npxcoj4mvzqf.png" alt="Image description" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only problem here is that there is no &lt;code&gt;RegistrationForm&lt;/code&gt; class in my project.  As Navie told us in the previous section, the class where I would actually need to add this is called &lt;code&gt;EmailUserCreationForm&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now you can see how adding tracing data and other runtime context improves the AI coding experience across your application.  Now you have a software architect or a senior staff engineer pair programming with you. Without knowledge of your code’s runtime, these generic responses will leave you continuing to hunt and search through a complex code base.  Adding runtime behavior providea context-aware insights to power hyper-personalized responses to your toughest software questions.  &lt;/p&gt;

&lt;p&gt;Check out this video demo watching me add this feature, with the help of AppMap Navie.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/52LnEGIZEoY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;To learn more about getting started with AppMap Navie, head over to &lt;a href="//getappmap.com"&gt;getappmap.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>openai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>How do you say... [insert tech lingo here]: A video series.</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Tue, 26 Sep 2023 19:24:44 +0000</pubDate>
      <link>https://dev.to/appmap/how-do-you-say-insert-tech-lingo-here-a-video-series-9df</link>
      <guid>https://dev.to/appmap/how-do-you-say-insert-tech-lingo-here-a-video-series-9df</guid>
      <description>&lt;p&gt;I've been fascinated by how the industry has come to pronounce different tech words, lingo, products, and acronyms.  Months ago, I asked my twitter followers for an idea of some good words to have people pronounce in a "game show" style lightning round. &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1635342410053201921-731" src="https://platform.twitter.com/embed/Tweet.html?id=1635342410053201921"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1635342410053201921-731');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1635342410053201921&amp;amp;theme=dark"
  }



 &lt;/p&gt;

&lt;p&gt;After 31(!!) individual recordings this summer, we shipped the series with friends from all over the tech industry in all kinds of roles.&lt;/p&gt;

&lt;p&gt;We threw a slew of tech names and acronyms at them to see how they pronounced them because, hey, most of these words have been made up in the last decade or less to describe a new technology or name for something related to ye'ole computer.&lt;/p&gt;

&lt;p&gt;The list:&lt;br&gt;
/etc&lt;br&gt;
AMI&lt;br&gt;
k8s&lt;br&gt;
chmod&lt;br&gt;
curl&lt;br&gt;
fsck&lt;br&gt;
HAProxy&lt;br&gt;
/proc/&lt;br&gt;
NGINX&lt;br&gt;
SQL&lt;br&gt;
systemctl&lt;br&gt;
SCSI&lt;br&gt;
www&lt;br&gt;
sudo&lt;br&gt;
URL&lt;br&gt;
/lib/&lt;br&gt;
CIDR&lt;br&gt;
epoch&lt;br&gt;
jwt&lt;br&gt;
strace&lt;/p&gt;

&lt;p&gt;Wanna check out the supercuts? You can find them on &lt;a href="https://www.youtube.com/@appmap/shorts"&gt;YouTube Shorts&lt;/a&gt; or &lt;a href="https://tiktok.com/@petecheslock"&gt;TikTok&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Head over to this &lt;a href="https://www.youtube.com/playlist?list=PLPDuImwwJ_oxDV3lF4uXJ5p3FX5awNLCT"&gt;AppMap Youtube Playlist&lt;/a&gt; to check out all the full length "game show" style lightning rounds.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4_EBBfzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8quu1g5kh807qjbfoti2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4_EBBfzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8quu1g5kh807qjbfoti2.png" alt="Image description" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The best part is the conversations between humans - the relationships with folks from all walks of tech life - and the joy you get from watching the laughter or disgust ensue.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>discuss</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>How do you say... "/etc"?</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Tue, 11 Jul 2023 17:38:22 +0000</pubDate>
      <link>https://dev.to/appmap/how-do-you-say-etc-246h</link>
      <guid>https://dev.to/appmap/how-do-you-say-etc-246h</guid>
      <description>&lt;p&gt;How would you pronounce this file system directory name commonly found on linux and unix-like systems? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Contains system-wide configuration files and system databases; the name stands for et cetera[14] but now a better expansion is editable-text-configurations. Originally also contained "dangerous maintenance utilities" such as init,[6] but these have typically been moved to /sbin or elsewhere. Needs to be on the root filesystem itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;/etc&lt;/code&gt; stands for Et Cetera which is a Latin expression used in English to mean &lt;code&gt;and other (similar) things&lt;/code&gt;, or &lt;code&gt;and so forth&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Translated literally from Latin, et means 'and', while cētera means 'the rest'; thus the expression translates to 'and the rest (of such things)'.&lt;/p&gt;

&lt;p&gt;But if you had to tell another person to put a file in the &lt;code&gt;/etc&lt;/code&gt; directory, how would you say it? &lt;/p&gt;

&lt;p&gt;Listen to a few examples from technology professionals on the latest episode of "How Do You Say?"&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8w1L6uU0bLs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Want to see more tech word pronunciations by tech professionals?  Find them on &lt;a href="https://www.youtube.com/@appmap/shorts"&gt;Youtube&lt;/a&gt;.  New videos ship every Friday.  &lt;/p&gt;

</description>
      <category>linux</category>
      <category>discuss</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How do you say... "k8s"?</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Fri, 16 Jun 2023 13:47:49 +0000</pubDate>
      <link>https://dev.to/appmap/how-do-you-say-k8s-3mhb</link>
      <guid>https://dev.to/appmap/how-do-you-say-k8s-3mhb</guid>
      <description>&lt;p&gt;You may have seen the abbreviation for "Kubernetes" as &lt;code&gt;k8s&lt;/code&gt; online.  This is called a &lt;a href="https://en.wikipedia.org/wiki/Numeronym"&gt;Numeronym&lt;/a&gt;.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A numeronym is a number-based word. Most commonly, a numeronym is a word where a number is used to form an abbreviation (albeit not an acronym or an initialism). Pronouncing the letters and numbers may sound similar to the full word, as in "K9" (pronounced "kay-nine") for "canine, relating to dogs". Alternatively, letters between the first and last letters of a word may be replaced by a number representing the number of letters omitted, such as in "i18n" for "internationalization".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But how would you SAY &lt;code&gt;k8s&lt;/code&gt; if you had to tell it to another person? It's a word we often read or write but rarely say.  &lt;/p&gt;

&lt;p&gt;I asked over 30 technologists for their pronunciation of this numeronym.  The results may surprise you!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/4RQwLtgXfkY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Want to see more tech word pronunciations by tech professionals?  Find them on &lt;a href="https://www.youtube.com/@appmap/shorts"&gt;Youtube&lt;/a&gt;.  New videos ship every Friday.  &lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>discuss</category>
      <category>watercooler</category>
      <category>jokes</category>
    </item>
    <item>
      <title>How do you say... "fsck"?</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Tue, 30 May 2023 15:03:34 +0000</pubDate>
      <link>https://dev.to/appmap/how-do-you-say-fsck-12l1</link>
      <guid>https://dev.to/appmap/how-do-you-say-fsck-12l1</guid>
      <description>&lt;p&gt;Have you ever had to boot into single user mode and run &lt;code&gt;fsck&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;It's a word we often read and write but rarely say.  How would you pronounce it to a co-worker or say it out loud?&lt;/p&gt;

&lt;h3&gt;
  
  
  So how do you pronounce it?
&lt;/h3&gt;

&lt;p&gt;I asked over 30 software engineers and technical operators exactly that question.  Here are a handful of their responses.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/2dcoBqcujkE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;There are no agreed upon pronunciations, but here are a handful from &lt;a href="https://en.wikipedia.org/wiki/Fsck"&gt;wikipedia&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"F-S-C-K", "F-S-check", "fizz-check", "F-sack", "fisk", "fizz-k", "fishcake", "fizik", "F-sick", "F-sock", "F-suck", "F-sek", "feshk", the sibilant "fsk", "fix", "farsk", "fosk" or "fusk".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Want to see more tech word pronunciations by tech professionals?  Find them on &lt;a href="https://www.youtube.com/@appmap/shorts"&gt;Youtube&lt;/a&gt;.  New videos ship every Friday.  &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>devops</category>
      <category>sre</category>
      <category>linux</category>
    </item>
    <item>
      <title>How do you say... "jwt"</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Tue, 23 May 2023 20:21:44 +0000</pubDate>
      <link>https://dev.to/appmap/how-do-you-say-jwt-9kb</link>
      <guid>https://dev.to/appmap/how-do-you-say-jwt-9kb</guid>
      <description>&lt;p&gt;Have you heard of a "jwt" before (&lt;a href="https://auth0.com/docs/secure/tokens/json-web-tokens" rel="noopener noreferrer"&gt;JSON web token&lt;/a&gt;)?&lt;/p&gt;

&lt;p&gt;It's a word we often read and write but rarely say.  &lt;/p&gt;

&lt;h3&gt;
  
  
  So how do you pronounce it?
&lt;/h3&gt;

&lt;p&gt;I asked over 30 software engineers and technical operators exactly that question.  Here are a handful of their responses.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/D2D9umQMKhA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Turns out - there is an official pronunciation for "jwt" on the &lt;a href="https://auth0.com/docs/secure/tokens/json-web-tokens#:~:text=JSON%20web%20token%20(JWT)%2C,parties%20as%20a%20JSON%20object." rel="noopener noreferrer"&gt;creators's (Auth0) website.&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;web&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;token&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(JWT),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pronounced&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jot"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;standard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(RFC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7519&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;defines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compact&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;self-contained&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;way&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;securely&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;transmitting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;information&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;between&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;parties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;object.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But it's NOT the same way to pronounce "JWt (&lt;a href="https://en.wikipedia.org/wiki/JWt_(Java_web_toolkit)" rel="noopener noreferrer"&gt;Java web toolkit&lt;/a&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%2Fl3sq65b2yzw5ugn6fa0s.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%2Fl3sq65b2yzw5ugn6fa0s.png" alt="JWt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 (pronounced "jay-witty") is an open-source widget-centric web application framework for the Java programming language developed by Emweb.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Want to see more tech word pronunciations by tech professionals?  Find them on &lt;a href="https://www.youtube.com/@appmap/shorts" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;.  New videos ship every Friday.  &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>coding</category>
    </item>
    <item>
      <title>The DevOps Hangover</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Fri, 19 May 2023 16:12:25 +0000</pubDate>
      <link>https://dev.to/appmap/the-devops-hangover-4el3</link>
      <guid>https://dev.to/appmap/the-devops-hangover-4el3</guid>
      <description>&lt;p&gt;&lt;strong&gt;The greatest irony is that DevOps aimed to help developers talk with operations, and vice versa, yet developers are even further away from understanding how their code operates at runtime.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Engineering and development teams, from startups to large corporations, have faced hard economic events over the last 12 months. Large-scale layoffs and company restructuring have forced teams to “do more with less” while building, scaling, and operating large-scale systems. Yet progress still needs to be made, and value still needs to be shown higher up the chain.&lt;/p&gt;

&lt;p&gt;After years of consuming countless tools and services to maintain high levels of performance and security, with little oversight for design or costs, the DevOps hangover is real. The average company continues to use well over 100+ SaaS tools, and many companies are still investing in new tools and technologies to help them weather the current economic storm (&lt;a href="https://www.battery.com/wp-content/uploads/2023/03/Battery-Ventures-State-of-Cloud-Software-Spending-Report-March-2023.pdf"&gt;Battery Report 2023&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The teams who can take this time to assess and streamline their arsenal will be the ones who emerge on the other side, cutting costs and improving efficiency, while gaining a competitive advantage. &lt;/p&gt;

&lt;p&gt;So, what’s the best medicine for our DevOps hangover? First, let’s understand how we got here.&lt;/p&gt;

&lt;h2&gt;
  
  
  DevOps then: Party time, excellent!
&lt;/h2&gt;

&lt;p&gt;DevOps emerged during a time of unbridled economic expansion with financial resources and the easy-to-use, pay-as-you-go SaaS products to support it. The problem has been two-fold: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developers continue to use solutions that aren't perfect, as long as they are useful enough for their needs. However, when budgets become tight (like today), these tools or services may cause unnecessary financial stress.&lt;/li&gt;
&lt;li&gt;And, developer toil was largely ignored as we yelled over our shoulders that it’s ok to “move fast and break things!” But today, developers are spending more than 17 hours per week dealing with maintenance issues, such as debugging and refactoring, according to the &lt;a href="https://stripe.com/files/reports/the-developer-coefficient.pdf"&gt;Developer Coefficient report by Stripe&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  DevOps now: Waking up to the hangover
&lt;/h2&gt;

&lt;p&gt;Imagine you are now waking up to a request to &lt;em&gt;do more with less&lt;/em&gt;, whether that is a reduced team size or a request to lower cloud and tools bills. With the loss of team members, you may be losing institutional knowledge that enables key applications to run. This loss can result in hundreds of thousands of dollars in outages, lost revenue, and regulatory fines. Despite these challenges, you may still be expected to maintain a five nines SLA to achieve aggressive growth targets.&lt;/p&gt;

&lt;p&gt;It's not just engineers and operators who are waking up to the DevOps hangover. Executives, including CEOs, COOs, CFOs, and engineering leaders, are also taking a closer look at operational spending in relation to sales and growth. Many are now hiring consultants to help them map their cloud spending with the rest of their operational spending (like Observability and Data Platforms) in order to find ways to make necessary cost reductions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the hangover cost us?
&lt;/h2&gt;

&lt;p&gt;It depends on the conditions under which your development team is operating. Here are a few common environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex legacy codebases&lt;/li&gt;
&lt;li&gt;A microservices platform that is growing exponentially&lt;/li&gt;
&lt;li&gt;A hybrid, stalled-out digital transformation project that is a Frankenstein’s monster of monolith and microservices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s break down each one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost of a legacy codebase
&lt;/h3&gt;

&lt;p&gt;When a company's codebase becomes a monolith that nobody can easily understand, new features take substantially longer to release because it’s much harder to add features and make changes when there are too many unknown upstream and downstream effects. This delay can be frustrating for both the development team and the end-users who are eagerly waiting for new features to be implemented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost of a microservices platform
&lt;/h3&gt;

&lt;p&gt;On the other end of the spectrum, Kubernetes and Lambda-native applications proliferated during the growth-at-all-costs era when cash was being burned at an astonishing rate. When running multiple products across shared underlying infrastructure, it becomes significantly more difficult to attribute per-product COGS (Cost of Goods Sold). This shift to a microservices architecture was made to improve the speed at which developers could deliver new applications. However, with shrinking budgets, already constrained Ops/DevOps/Platform teams are now pushing the ongoing management of these platforms onto the overburdened dev teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost of a hybrid monolith + microservices platform
&lt;/h3&gt;

&lt;p&gt;And finally, in the middle of these two extremes are the teams stuck with both a legacy monolith, a constellation of microservices, and maintaining their five nines SLA with every code change. Teams are now faced with the challenges of breaking code changes, scaling issues, and the growing number and complexity of dependent services. And they are throwing all the observability tools at the problem to better understand how the code operates at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autoscaling up is easy, Autoscaling down isn’t
&lt;/h3&gt;

&lt;p&gt;While understanding how to scale up infrastructure as your usage grows is important, it can be challenging to determine how to scale down when usage decreases. And many teams never spent the time to plan for a scenario where they would need to reduce the infrastructure as usage decreased. &lt;/p&gt;

&lt;p&gt;If the cost of delivering your application becomes detached from your sales and revenue, your company may end up spending more money than necessary. This can happen if your cloud and observability bills remain constant, even as your business slows down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Curing the DevOps Hangover
&lt;/h2&gt;

&lt;p&gt;Every software company is asking its development team to cut infrastructure costs. Yet, the same problems remain: bad code creates blockages, outages, and inefficiencies that cost hundreds of thousands, sometimes millions, to the business, annually.&lt;/p&gt;

&lt;h3&gt;
  
  
  First, let’s tackle operational costs.
&lt;/h3&gt;

&lt;p&gt;Look beyond cloud spending as our only barometer for operational costs. The costs of delivering a product feature can exist over many services and across teams. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a spreadsheet or list and account for all of the other applications you use to deliver the entire application.&lt;/li&gt;
&lt;li&gt;Identify each feature or product's actual value to the user and business, not just what sales and marketing claim they do.&lt;/li&gt;
&lt;li&gt;Find areas of overlap between applications and teams. This is a great opportunity to identify and break down technical and organizational barriers built up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some costs for delivering your application are hidden in third-party SaaS services that follow pay-per-use or subscription models but do not register as your typical cloud expense. In particular, observability tooling and data infrastructure lead the pack for non-cloud infrastructure spend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Services like DataDog and NewRelic have extremely high costs related to custom metrics, and once a metric is added, it is unlikely to be removed later. Identify and attribute these underlying costs back toward the product or team supporting it.&lt;/li&gt;
&lt;li&gt;Review and understand which team owns which data sources. Take note of where data is moving within your applications and services. Many cost overruns stem from developers not understanding the cost impacts of data transfer between services.&lt;/li&gt;
&lt;li&gt;Identify where these tools are currently operating.  In expensive production environments where it is costly to maintain these tools and more expensive to cure the issues?  Consider migrating these tools earlier in the development process where mistakes are cheap to fix, and the cost of running developer tools is lower.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debugging in production may seem like the best way to solve the problem, but this will be after your users are already impacted, or after a critical code change balloons your AWS costs. It’s simply too late to be effective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next, let’s address the importance of code analysis and application design.
&lt;/h3&gt;

&lt;p&gt;Code quality and design influence costs. Your senior developers know it, but it may be much less obvious to your CFO. Consider this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A developer adds new code to your application, like a new feature or a bug fix.&lt;/li&gt;
&lt;li&gt;That code change makes a repeated call to a database, increasing database queries.&lt;/li&gt;
&lt;li&gt;Those increased queries cause application and database performance loss. &lt;/li&gt;
&lt;li&gt;An SRE, siloed by a developer, is alerted to poor performance and increases the underlying infrastructure to support the workload.
&lt;/li&gt;
&lt;li&gt;The cost to deliver this application has now doubled as the SRE team threw the cloud at the problem and increased the database to a larger instance. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is quick and easy to make a database larger, but in reality, we simply masked a code quality issue AND increased our overall spending with no additional value being provided to the user. Over time, the code becomes riddled with performance issues that, in reality, never get fixed. Code quality suffers, as well as your bottom line.&lt;/p&gt;

&lt;p&gt;For example, this type of N+1 SQL query problem isn’t ONLY a problem for databases and slow-performing applications. Today's services are pay-as-you-go, where each API request has a defined cost, and inadvertently calling that same API repeatedly will rack up the bills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finally, let’s acknowledge this will take continual improvement.
&lt;/h3&gt;

&lt;p&gt;Remember, all hangovers will eventually pass. The ideal scenario is that you and your team can begin taking stock and evaluating your tools and services, and then you start seeing an improvement in the performance and costs of delivering your application. What can you then do to ensure things stay this way? &lt;/p&gt;

&lt;p&gt;Remember that this isn’t a static process. That’s what got us into this mess. Make taking stock and evaluating your tools and services a quarterly step. Even better, include this work in your ongoing product development workflows. A little bit of low-friction software governance can go a long way toward reigning in wasteful and costly code changes, and incorporating it into your CI/CD means catching problems earlier in the process. &lt;/p&gt;

&lt;p&gt;Even if you are unable to make a large investment into optimization today, understanding how your software is changing when it changes will be critical to stem the tide of growing operational expenses. Use tools to help you analyze your software during the development and testing phase in order to identify performance issues early and put those tools into the hands of the developers so they can better understand the operational impact of the code changes they are making.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>monitoring</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How Do You Say... "Epoch"</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Mon, 08 May 2023 17:24:09 +0000</pubDate>
      <link>https://dev.to/appmap/how-do-you-say-epoch-5c10</link>
      <guid>https://dev.to/appmap/how-do-you-say-epoch-5c10</guid>
      <description>&lt;p&gt;As a technologist, there are a lot of words and acronyms we often only read or type out but don't say out loud (commands/services/etc). So, I asked a bunch of folks how they pronounce some of them and recorded the result. For example...&lt;/p&gt;

&lt;p&gt;For example: "&lt;a href="https://en.wikipedia.org/wiki/Epoch_(computing)" rel="noopener noreferrer"&gt;Epoch&lt;/a&gt;"&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In computing, an epoch is a date and time from which a computer measures system time. Most computer systems determine time as a number representing the seconds removed from particular arbitrary date and time. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do you pronounce it?  &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Top 5 VS Code extensions</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Thu, 04 May 2023 18:58:33 +0000</pubDate>
      <link>https://dev.to/appmap/top-5-vs-code-extensions-4ncd</link>
      <guid>https://dev.to/appmap/top-5-vs-code-extensions-4ncd</guid>
      <description>&lt;p&gt;As a co-builder of AppMap — a runtime code analysis platform for developers to better visualize, interact with, and understand their code — I spend a lot of time helping people in their code editor. &lt;/p&gt;

&lt;p&gt;When our users are &lt;a href="https://appmap.io/download" rel="noopener noreferrer"&gt;working in VS Code&lt;/a&gt;, they like to use a few key extensions to make life easier and more fun. We’re all about developer happiness around here, so I thought I’d share the top 5 VS Code extensions that the AppMap team loves. &lt;/p&gt;

&lt;p&gt;[Out now! &lt;a href="https://info.appmap.io/early-access-to-appmap-for-ci" rel="noopener noreferrer"&gt;Early access to AppMap for GitHub Actions&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;What are yours?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=vscodevim.vim" rel="noopener noreferrer"&gt;Vim&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our team likes to use the vim keybindings so they don’t have to take their fingers off the keyboard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is very popular, so it won’t come as a surprise to anyone that it’s on the list. Our dev team appreciates not having to worry about formatting their code, and with Prettier, their code stays linted and formatted. They say it works best with JS and JSON.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=GitHub.copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This new extension really is as great as the hype. It drastically reduces the need for the team to look up language and API docs. Plus, we’re kind of into planes over here, so we love the name. &lt;br&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%2Fu3zava1yi5600bzd6op2.jpg" 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%2Fu3zava1yi5600bzd6op2.jpg" alt="Planes!"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;That's &lt;a href="https://dev.to/kgilpin"&gt;Kevin&lt;/a&gt;, AppMap CTO 🛫&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server" rel="noopener noreferrer"&gt;Live Preview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This VS Code extension serves a workspace as HTTP, which is useful when the team wants to use, preview, test, or debug an HTML page (including JS code such as Vue) that’s part of the project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview" rel="noopener noreferrer"&gt;GitHub Markdown Preview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s really helpful to have a preview of how the GitHub markdown features will display before the team commits a change, so this extension is one they use often.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  BONUS: &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;AppMap&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Of course! &lt;/p&gt;

&lt;p&gt;We just updated our &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;marketplace page&lt;/a&gt; today as we’ve been building and improving AppMap for a few years now.&lt;/p&gt;

&lt;p&gt;We built AppMap to &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;run in the VS Code editor&lt;/a&gt; so it can analyze runtime code behavior before you commit changes and go to production. It works by recording detailed traces of how your application runs and analyzing it based on frameworks and techniques. Interactive, visual sequence diagrams and views present your bugs, loops, calls, dependencies, security issues, and other things that might keep your code from being ready to ship. &lt;/p&gt;

&lt;p&gt;AppMap can also be used to help you understand a legacy codebase, which someone in our community recently likened to trying to understand “a crime scene.” It can also instantly generate OpenAPI documentation based on the API calls it observes at runtime.&lt;/p&gt;

&lt;p&gt;AppMap supports the following programming languages: Java, Python, Ruby, Typescript, and JavaScript. And, these web applications and API frameworks: Ruby on Rails, Django, Flask, Express, and Spring.&lt;/p&gt;

&lt;p&gt;In terms of data usage, AppMap runtime recordings and diagrams are created and stored locally on your machine. AppMap does not require any permissions to your web-hosted code repo in order to run.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to get started with AppMap
&lt;/h3&gt;

&lt;p&gt;Install from the &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;VS Code marketplace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://appmap.io/docs/appmap-overview" rel="noopener noreferrer"&gt;Visit the documentation&lt;/a&gt; for guides and videos.&lt;/p&gt;

&lt;p&gt;Use AppMap to &lt;a href="https://appmap.io/docs/diagrams/sequence-diagrams.html" rel="noopener noreferrer"&gt;generate sequence diagrams of your code.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check us out and leave a ⭐ &lt;a href="https://github.com/getappmap" rel="noopener noreferrer"&gt;in GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://appmap.io/blog/" rel="noopener noreferrer"&gt;Read the blog&lt;/a&gt; for user stories and product announcements.&lt;/p&gt;

&lt;p&gt;Join us &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;in Slack&lt;/a&gt; or email us for support: &lt;a href="//mailto:support@appmap.io"&gt;support@appmap.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>opensource</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Code-First Auto-Generated OpenAPI Docs for Django Applications</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Tue, 28 Feb 2023 19:23:23 +0000</pubDate>
      <link>https://dev.to/appmap/code-first-auto-generated-openapi-docs-for-django-applications-3a9j</link>
      <guid>https://dev.to/appmap/code-first-auto-generated-openapi-docs-for-django-applications-3a9j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Using the open source e-commerce framework &lt;a href="https://github.com/django-oscar/django-oscar" rel="noopener noreferrer"&gt;Django-Oscar&lt;/a&gt; as an example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;API documents are usually a developer’s first introduction to a project; however, they can be out of date or incorrect because developers on the project have to go in and update the documents manually each time the code changes. This is not only a waste of developers’ time, but it is easy to forget to do it altogether. The industry says "API first" - starting with an API Document - is the way to build applications, but this approach can be overlooked when there are tight deadlines.&lt;/p&gt;

&lt;p&gt;AppMap is a free, dynamic runtime analysis tool that makes it easy to automatically generate API documents. Automatic OpenAPI generation can also be incorporated into your CI/CD system to prevent the documents from ever being out of date or incorrect. The days of manual API documentation writing are over. Write your code, run your code, and the document will appear in your repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add AppMap to Django-Oscar
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/appmap/host-your-own-online-shop-with-django-oscar-pycharm-3m37"&gt;In Part One of this series&lt;/a&gt;, you learned how to generate AppMaps for the open-source project Django-Oscar. AppMaps are visual representations of code that allow developers to dig into the trace of their HTTP requests, function calls, and database writes. To install AppMap libraries into the Django-Oscar codebase, &lt;a href="https://plugins.jetbrains.com/plugin/16701-appmap" rel="noopener noreferrer"&gt;add the AppMap PyCharm extension.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are not using VS Code or Jetbrains, or if you want to incorporate OpenAPI generation into your CI/CD system, you can &lt;a href="https://appmap.io/docs/reference/appmap-client-cli.html" rel="noopener noreferrer"&gt;install the AppMap CLI&lt;/a&gt; and generate OpenAPI docs on the command line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the Django-Oscar Test Suite
&lt;/h2&gt;

&lt;p&gt;Set your environment variable as shown below, and run the PyTest command to execute the Django-Oscar test suite. The test coverage is extensive and will take a while to run, so feel free to run a subset of the tests first just to see how the API generation works. You can learn more about generating AppMaps from tests in Python in the AppMap Documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPMAP_LOG_LEVEL=info pytest -svv 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the full test suite, you’ll have a collection of code-accurate AppMaps with all the up to date API request information within. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkiie5ril4hyc9nhmbkbx.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkiie5ril4hyc9nhmbkbx.png" alt="AppMap in Pycharm" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on one of the AppMaps in the sidebar to expand it and explore the dependencies within the project.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhujwsd566r0mc73pthhi.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhujwsd566r0mc73pthhi.png" alt="AppMap Dependency View" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate the OpenAPI Spec
&lt;/h2&gt;

&lt;p&gt;Now that our API requests have been recorded within our AppMaps, you can generate the OpenAPI v3 supported specification file via either PyCharm or using the AppMap CLI. From there you can import the file into &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;, other API management tools, or share with your team. &lt;/p&gt;

&lt;p&gt;After the Django-Oscar test cases complete, click the “Generate OpenAPI” button.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrv7zjg8ojdfctctvk3f.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrv7zjg8ojdfctctvk3f.png" alt="Generate OpenAPI" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open the OpenAPI generator. Then click the “Generate OpenAPI Documents” button and your OpenAPI specification will be displayed in the editor. Save this data anywhere you need it for later usage or distribution.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3brufpnv14f0xzgl48o.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3brufpnv14f0xzgl48o.png" alt="OpenAPI Docs are neat" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example: I loaded this API Specification into &lt;a href="https://blog.postman.com/new-postman-integration-with-appmap-create-and-manage-always-accurate-collections/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; as a new collection.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1a6pkbe98axfcifgxpxh.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1a6pkbe98axfcifgxpxh.png" alt="AppMap and Postman" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate OpenAPI Document with AppMap CLI
&lt;/h2&gt;

&lt;p&gt;If you are not a PyCharm user, or if you want to incorporate OpenAPI generation as part of your CI process, you can run the AppMap CLI command after the tests have completed to similarly output the API documents to a user-defined output file.&lt;/p&gt;

&lt;p&gt;The AppMap CLI is written in JavaScript, which makes it easy to run across a variety of platforms. To install the AppMap CLI, you need &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed, or you can grab &lt;a href="https://github.com/getappmap/appmap-js/releases" rel="noopener noreferrer"&gt;pre-built binaries for @appland/appmap on Github&lt;/a&gt;. To install AppMap CLI after Node.js is installed, run 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;npx @appland/appmap@latest openapi --output-file openapi.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the OpenAPI documents into other tools to more easily interact with your APIs, test new or updated features, and finally export the OpenAPI documents to your users so that they will know how to interact with your application as well.&lt;/p&gt;

&lt;p&gt;Now that you've generated the API document locally, add this command to your CI system to update your OpenAPI docs as your code changes.&lt;br&gt;
You can learn more about other features of AppMap by reviewing our &lt;a href="https://appmap.io/docs/appmap-overview.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; or you can join the developers in &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;our community Slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>welcome</category>
      <category>opensource</category>
      <category>mobile</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Optimizing Mastodon Performance: Finding and Fixing its N+1 Queries</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Thu, 12 Jan 2023 18:34:06 +0000</pubDate>
      <link>https://dev.to/appmap/optimizing-mastodon-performance-finding-and-fixing-its-n1-queries-57ni</link>
      <guid>https://dev.to/appmap/optimizing-mastodon-performance-finding-and-fixing-its-n1-queries-57ni</guid>
      <description>&lt;p&gt;&lt;a href="https://appmap.io/blog/2021/02/04/eager-loading-and-the-n-plus-one-query-problem/" rel="noopener noreferrer"&gt;N+1 queries&lt;/a&gt; happen in a variety of ways, out of sight to many developers who are using an &lt;a href="https://en.wikipedia.org/wiki/List_of_object%E2%80%93relational_mapping_software" rel="noopener noreferrer"&gt;ORM&lt;/a&gt;. With the level of abstraction that ORMs provide, it can be easy for developers to accidentally incorporate a query that is executed on each result of the previous query. ORMs can make development faster and more secure, but the automatic generation of SQL queries can make it hard to predict the code's performance when it gets deployed.&lt;/p&gt;

&lt;p&gt;Developers can be unaware their functions even query the database and a simple feature like checking user permissions could lead to querying for the same exact data multiple times. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://guides.rubyonrails.org/active_record_basics.html" rel="noopener noreferrer"&gt;Active Record&lt;/a&gt; is a Ruby on Rails framework used to easily save and retrieve objects from a database in programming frameworks. It automatically generates SQL statements to do this. ORMs like Active Record can make it easier for developers to write database-backed applications, but they can also make it harder to understand exactly how their code makes database queries.&lt;/p&gt;

&lt;p&gt;In this final part of our Mastodon Series, you’ll learn how to &lt;a href="https://appmap.io/docs/analysis" rel="noopener noreferrer"&gt;analyze your AppMaps&lt;/a&gt; to uncover and fix an N+1 SQL query in an active code base. &lt;/p&gt;

&lt;p&gt;In the previous posts you have learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/appmap/installing-appmap-in-mastodon-with-vs-code-167d"&gt;How you can install AppMap into Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appmap/visualizing-mastodon-internals-1198"&gt;How to visualize Mastodon code internals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/appmap/the-fastest-way-to-run-mastodon-tests-5g03"&gt;How to run the Mastodon rspec tests&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appmap/automatically-generating-openapi-docs-for-mastodon-42ig"&gt;How to automatically generate OpenAPI docs for Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our previous post, you learned how AppMap uses the runtime code data to automatically generate accurate OpenAPI documentation. AppMap contains all the relevant HTTP request information including status codes, headers, and the session operations and AppMap builds complete and accurate OpenAPI documentation by analyzing how the code executes.&lt;/p&gt;

&lt;p&gt;This same AppMap data can be used in other ways, for example in this post you’ll learn how to use AppMap Analysis to locate and fix a performance issue. Since the AppMaps shows function calls, SQL queries, exceptions, and more, they can be analyzed to find design flaws that contributes to performance and security issues. &lt;/p&gt;

&lt;p&gt;Design related security flaws are rising in the &lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt; in recent years. Runtime data helps us to uncover design flaws that are contributing to slow performance such as an N+1 query. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpho87ucrn6897ts6xk0w.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpho87ucrn6897ts6xk0w.png" alt="1" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate Code Analysis Findings
&lt;/h2&gt;

&lt;p&gt;With our &lt;code&gt;rspec&lt;/code&gt; tests passing and our AppMaps created back in &lt;a href="https://dev.to/appmap/the-fastest-way-to-run-mastodon-tests-5g03"&gt;Part 3&lt;/a&gt;, findings are now shown in the section of our VSCode extension titled “Runtime Analysis”. Since AppMap records the runtime application behavior, it analyzes the output of those recordings and scans for code behavior issues that you can’t find with a static analyzer. &lt;/p&gt;

&lt;p&gt;AppMap can scan for a variety of &lt;a href="https://appmap.io/docs/analysis/rules-reference" rel="noopener noreferrer"&gt;Performance, Security, Scalability, and Maintainability issues&lt;/a&gt;. These &lt;a href="https://github.com/getappmap/appmap-js/tree/main/packages/scanner/src/rules" rel="noopener noreferrer"&gt;rules are extensible&lt;/a&gt; for developers to create and contribute to the open source community. &lt;/p&gt;

&lt;p&gt;On the left side of the VS Code extension, you can see a section called “Runtime Analysis”. This is where AppMap will display the results of the analysis scan. This scan should happen within seconds of AppMaps being created or updated. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ycz4aanscaix01crbor.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ycz4aanscaix01crbor.png" alt="2" width="800" height="809"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When clicking on any one of the lines of code referenced in the findings, a new tab will open with additional details about the event, including links to the relevant &lt;a href="https://cwe.mitre.org/" rel="noopener noreferrer"&gt;CWE&lt;/a&gt;. The findings page will also show the stack trace leading up to the event, and a list of the AppMaps this flaw is present in.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5atrszgu8cr6gm67uv9.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5atrszgu8cr6gm67uv9.png" alt="3" width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By navigating to the base controller in Mastodon, AppMap identifies this line of code (Line 92) as making a database call (via User.find) when the &lt;code&gt;doorkeeper_token&lt;/code&gt; variable is false. But by looking closer at the stack trace, AppMap shows line 109 is the caller function which checks to see if the current user is known and properly validated. This is correctly reported by AppMap as an N+1 query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mastodon/mastodon/blob/623d3d2e32ac8ec2819f2cd99e6565d06c9b0023/app/controllers/api/base_controller.rb#L111-L141" rel="noopener noreferrer"&gt;https://github.com/mastodon/mastodon/blob/623d3d2e32ac8ec2819f2cd99e6565d06c9b0023/app/controllers/api/base_controller.rb#L111-L141&lt;/a&gt;&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevc5usl7o27ppsc0lil4.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevc5usl7o27ppsc0lil4.png" alt="4" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple fix would be to just fetch current_user once in require_user!, or to memoize it in the current_user function. &lt;/p&gt;

&lt;p&gt;AppMap &lt;a href="https://app.land/scenarios/a8878519-7709-45e7-883b-38d56d90ce77?process=true&amp;amp;state=eyJjdXJyZW50VmlldyI6InZpZXdGbG93Iiwic2VsZWN0ZWRPYmplY3QiOiJldmVudDoxMTUxIiwidHJhY2VGaWx0ZXIiOiJpZDoxMTY1IGlkOjEyMDUgaWQ6MTI0NyBpZDoxMjg3IGlkOjEzMzMgaWQ6MTM3MyBpZDoxNDEzIGlkOjExNTEgIn0" rel="noopener noreferrer"&gt;visualizes this function and the repeated SQL queries&lt;/a&gt;.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tltclbmguf777zrfeus.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tltclbmguf777zrfeus.gif" alt="5" width="760" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Before and After
&lt;/h2&gt;

&lt;p&gt;Before implementing the code change, save the original AppMap in a “Baseline” collection so that AppMap can visually compare the before and after impact of the change. &lt;/p&gt;

&lt;p&gt;This code is found in 6 AppMaps and they are listed on the specific findings page. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dqrm7xxnvw0dnhubkjv.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dqrm7xxnvw0dnhubkjv.png" alt="6" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now select one of these AppMaps, right click them, and choose the option to “Save To Collection”. Collections can be used to create copies of AppMaps which is useful for saving the current code behavior as a baseline before you implement code changes. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faacqbdqqotcfb3r0orh4.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faacqbdqqotcfb3r0orh4.png" alt="7" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there we can click &lt;code&gt;&amp;lt;create&amp;gt;&lt;/code&gt; to create a new collection of AppMaps or select a previously created collection to add to. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0hwsbjk8l1k5731e408.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0hwsbjk8l1k5731e408.png" alt="8" width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After copying that AppMap to a new collection, you’ll see it included within the list of existing AppMaps. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faz6wz6cyr00emm5douom.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faz6wz6cyr00emm5douom.png" alt="9" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s important to note that this makes a copy of the AppMap in the state it was in when it was added to the Collection. After updating the code and the AppMap, the collection will still contain the previous version of the code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the Performance Fix
&lt;/h2&gt;

&lt;p&gt;This poorly performing code is improved by &lt;a href="https://github.com/mastodon/mastodon/pull/23057/commits/b677187280abb6d66c165098f9d8faac067fe6bc" rel="noopener noreferrer"&gt;breaking out the user validation into its own function&lt;/a&gt; so it will not repeatedly query the database for the same information. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mastodon/mastodon/pull/23057" rel="noopener noreferrer"&gt;https://github.com/mastodon/mastodon/pull/23057&lt;/a&gt;&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv1skcyeu8ndo5zlypdbv.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv1skcyeu8ndo5zlypdbv.png" alt="10" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Identify Out of Date AppMaps
&lt;/h2&gt;

&lt;p&gt;After making this code change (either committed to your project or not) AppMap will display both the baseline and other maps that are listed as out of date because we’ve changed the functions these maps had previously recorded. AppMap knows when the underlying code has been changed and can notify when the AppMaps no longer match the code. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuouojccdnn35psv7le2g.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuouojccdnn35psv7le2g.png" alt="11" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the Command Palette in VS Code (View -&amp;gt; Command Palette OR Shift+⌘+P on Mac OR Ctrl+Shift+P on Windows), and search for the option to “Copy Out-of-Date Tests”.&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9exoa6rceto9p30mvfl0.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9exoa6rceto9p30mvfl0.png" alt="12" width="800" height="133"&gt;&lt;/a&gt;&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupgbnz9rmoet2pkuhk99.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupgbnz9rmoet2pkuhk99.png" alt="13" width="800" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can choose to copy the file names into the clipboard and paste them into the &lt;code&gt;rspec&lt;/code&gt; command. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwx3iydrraop1r5fhkoo.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwx3iydrraop1r5fhkoo.png" alt="14" width="800" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After successfully running only the tests needed to update our AppMaps the baseline AppMap will continue to be out of date and the other AppMaps will be updated. It’s important to note that when you make a code change to a function recorded in the “Baseline” AppMap, that AppMap will always display as “out of date” since it will always represent the original test case run. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9dpn9veqsm3adpybgft.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9dpn9veqsm3adpybgft.png" alt="15" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Sequence Diagram Diffs
&lt;/h2&gt;

&lt;p&gt;Another feature of AppMap is the ability to &lt;a href="https://dev.to/appmap/auto-magically-generate-sequence-diagrams-of-your-codes-runtime-behavior-597a"&gt;automatically create sequence diagrams&lt;/a&gt; of your code’s runtime behavior. This can be extremely useful information to include in a pull request or a code review to help other members of your team understand how the code behavior has changed.  &lt;/p&gt;

&lt;p&gt;Since a baseline AppMap exists prior to our code change, AppMap can create a sequence diagram diff of the before and after. Assuming the local VS Code environment is &lt;a href="https://appmap.io/docs/diagrams/sequence-diagrams.html" rel="noopener noreferrer"&gt;configured to support sequence diagram creation&lt;/a&gt;, AppMap will be able to both generate a sequence diagram, or compare two sequence diagrams. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0pubawb1jywd2c17cod.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0pubawb1jywd2c17cod.png" alt="16" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To generate the sequence diagram diff, right click on the latest version of the AppMap and select “Compare Sequence Diagrams”&lt;/p&gt;

&lt;p&gt;Hit enter twice then select the original baseline AppMap saved in our Baseline collection. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tgo2kvqpi7h404766dj.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tgo2kvqpi7h404766dj.png" alt="17" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here a new browser window will open showing a sequence diagram diff visualizing the change in behavior of the code from before and after our changes. The red items in sequence diagram will indicate code behavior that has been removed, and green items will show new code paths created. &lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm12htyetc1njet0ej069.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm12htyetc1njet0ej069.png" alt="18" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the changes in the sequence diagram show the code is not longer making similar repeated SQL queries. By reducing these unnecessary queries the speed of this code function has increased. &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this post, you’ve learned how to find and fix a performance issue in the Mastodon code base using AppMap. The automated code analysis will work for other projects written in languages other than Ruby like Java, Python, and JavaScript/TypeScript. &lt;/p&gt;

&lt;p&gt;To get started finding potential issues in your code base, download and install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;AppMap VS Code Extension&lt;/a&gt;, or the &lt;a href="https://plugins.jetbrains.com/plugin/16701-appmap/reviews" rel="noopener noreferrer"&gt;JetBrains Marketplace&lt;/a&gt; in your code editor and follow the similar instructions taken in this project. For more language specific information, check out the &lt;a href="https://appmap.io/docs/install-appmap-agent.html" rel="noopener noreferrer"&gt;AppMap documentation&lt;/a&gt;, or join the &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;AppMap Community Slack&lt;/a&gt; to ask a developer for more information.&lt;/p&gt;

</description>
      <category>gratitude</category>
      <category>aws</category>
      <category>serverless</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Automatically Generating OpenAPI Docs for Mastodon</title>
      <dc:creator>Pete Cheslock</dc:creator>
      <pubDate>Wed, 14 Dec 2022 20:26:15 +0000</pubDate>
      <link>https://dev.to/appmap/automatically-generating-openapi-docs-for-mastodon-42ig</link>
      <guid>https://dev.to/appmap/automatically-generating-openapi-docs-for-mastodon-42ig</guid>
      <description>&lt;p&gt;As the Mastodon open source community grows, many developers are coming into the project for the first time and learning more by viewing the documentation.  One of the common pieces of documentation that users in both the &lt;a href="https://discourse.joinmastodon.org/t/openapi-documentation-of-the-api/3929" rel="noopener noreferrer"&gt;Mastodon Discourse&lt;/a&gt; and &lt;a href="https://github.com/mastodon/mastodon/issues/20572" rel="noopener noreferrer"&gt;GitHub issues&lt;/a&gt; are looking for is an up-to-date version of API documentation. &lt;/p&gt;

&lt;p&gt;One user proposes writing rswag specs to allow for automatically documenting the APIs and generating the OpenAPI schema. The downside to this approach is the additional engineering time it takes for adding this net new code to the project. &lt;/p&gt;

&lt;p&gt;The OpenAPI specification, which is formerly known as the Swagger Specification, is a &lt;a href="(https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md)"&gt;community-driven open standard&lt;/a&gt; for documenting APIs. OpenAPI allows both humans and computers to discover and understand the capabilities of a service without requiring access to the service’s source code. &lt;/p&gt;

&lt;p&gt;In the previous parts of this series, we showed you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/appmap/installing-appmap-in-mastodon-with-vs-code-167d"&gt;How you can install AppMap into Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/appmap/visualizing-mastodon-internals-1198"&gt;How to visualize Mastodon code internals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/appmap/the-fastest-way-to-run-mastodon-tests-5g03"&gt;How to run the Mastodon rspec test suite&lt;/a&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By now you’ll now have AppMaps recorded from the Mastodon tests. The &lt;a href="https://github.com/getappmap/appmap" rel="noopener noreferrer"&gt;AppMap data specification&lt;/a&gt; includes all of the API calls processed including the schema of each request and response. Using the AppMap CLI (or the &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; or &lt;a href="https://plugins.jetbrains.com/plugin/16701-appmap" rel="noopener noreferrer"&gt;JetBrains&lt;/a&gt; extension) developers can automatically output OpenAPI specifications for Mastodon in just 3 steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add AppMap to Mastodon&lt;/li&gt;
&lt;li&gt;Run the Mastodon Test suite&lt;/li&gt;
&lt;li&gt;Generate the OpenAPI Spec&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add AppMap to Mastodon
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/appmap/installing-appmap-in-mastodon-with-vs-code-167d"&gt;Check out part 1 of this series&lt;/a&gt; to install AppMap libraries into the Mastodon code base, and to install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; or &lt;a href="https://plugins.jetbrains.com/plugin/16701-appmap" rel="noopener noreferrer"&gt;JetBrains&lt;/a&gt; extension. &lt;/p&gt;

&lt;p&gt;If you are not using VS Code or Jetbrains, or if you want to incorporate OpenAPI generation into your CI/CD system, you can install the AppMap CLI and generate OpenAPI docs on the command line. &lt;/p&gt;

&lt;h2&gt;
  
  
  Run the Mastodon Test suite
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/appmap/the-fastest-way-to-run-mastodon-tests-5g03"&gt;In Part 3 of this series&lt;/a&gt; you learned how to run the entire Mastodon rspec test suite.  After running the full test suite you’ll have a collection of code-accurate AppMaps with all the up-to-date API request information within. &lt;/p&gt;

&lt;h2&gt;
  
  
  Generate the OpenAPI Spec
&lt;/h2&gt;

&lt;p&gt;Now that AppMaps exist with our API requests, you can generate the OpenAPI v3 supported specification file via either VS Code or using the AppMap CLI. From there you can import this into &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;, other API management tools, or share with your team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate in VS Code
&lt;/h3&gt;

&lt;p&gt;After the Mastodon test cases complete - click the “Generate OpenAPI” button on the left column. &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%2Fjdsp8ua5lcwkf57hc0mf.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%2Fjdsp8ua5lcwkf57hc0mf.png" alt="openapi-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open the OpenAPI introduction page. Then click the “Generate OpenAPI Definitions” button and your OpenAPI specification will be displayed in the editor.  Save this data anywhere you need it for later usage or distribution. &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%2F5cwac64m57cqxe0s5ajs.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%2F5cwac64m57cqxe0s5ajs.png" alt="openapi-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example: I loaded this API Specification into &lt;a href="https://blog.postman.com/new-postman-integration-with-appmap-create-and-manage-always-accurate-collections/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; as a new collection.&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%2Feepu7gasn2bu9gfn24a5.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%2Feepu7gasn2bu9gfn24a5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate with AppMap CLI
&lt;/h3&gt;

&lt;p&gt;If you are not a VS Code user, or if you want to incorporate OpenAPI generation as part of your CI/CD build process, you can run the AppMap CLI command after the &lt;code&gt;rspec&lt;/code&gt; tests have completed to similarly output the API documentation to a user-defined output file.  &lt;/p&gt;

&lt;p&gt;The AppMap CLI is written in JavaScript which makes it easy to run across a variety of platforms. You’ll need &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed or alternatively you can grab pre-built binaries for &lt;a href="https://github.com/getappmap/appmap-js/releases" rel="noopener noreferrer"&gt;@appland/appmap on Github.&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;npx @appland/appmap@latest openapi --output-file openapi.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can import this OpenAPI documentation into other tools to more easily interact with your APIs, test new or updated features, and finally export these OpenAPI specifications to your users so that they will know how to interact with your application as well.  &lt;/p&gt;

&lt;p&gt;You can learn more about other features of AppMap by reviewing our &lt;a href="https://appmap.io/docs/appmap-overview.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; or you can join the developers in &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;our community Slack.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mastodon</category>
      <category>api</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
  </channel>
</rss>
