<?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: AppMap</title>
    <description>The latest articles on DEV Community by AppMap (@appmap).</description>
    <link>https://dev.to/appmap</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%2Forganization%2Fprofile_image%2F3566%2Fdb90af67-aa32-4983-99fb-b98db0777b17.png</url>
      <title>DEV Community: AppMap</title>
      <link>https://dev.to/appmap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/appmap"/>
    <language>en</language>
    <item>
      <title>How AppMap Navie solved the SWE bench AI coding challenge</title>
      <dc:creator>Kevin Gilpin</dc:creator>
      <pubDate>Tue, 25 Jun 2024 16:11:31 +0000</pubDate>
      <link>https://dev.to/appmap/how-appmap-navie-solved-the-swe-bench-ai-coding-challenge-20an</link>
      <guid>https://dev.to/appmap/how-appmap-navie-solved-the-swe-bench-ai-coding-challenge-20an</guid>
      <description>&lt;p&gt;&lt;a href="https://appmap.io/product/appmap-navie.html" rel="noopener noreferrer"&gt;AppMap Navie&lt;/a&gt; is an AI coding assistant that you can use directly in your VSCode or JetBrains code editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.swebench.com/" rel="noopener noreferrer"&gt;SWE Bench&lt;/a&gt; is a benchmark from Princeton University that assesses AI language models and agents on their ability to solve real-world software engineering issues. It's made up of 2,294 issues from 12 popular Python repositories, along with their human-coded solutions and test cases. It is considered to be the most difficult of the well-known coding benchmarks.&lt;/p&gt;

&lt;p&gt;AppMap Navie recently posted 14.6% on SWE Bench, ahead of Amazon Q and 8 other tools. We were able to process the entire benchmark in under 4 hours, and at the lowest recorded cost of operation - up to 95% less expensive than other solvers.&lt;/p&gt;

&lt;p&gt;How did we do it? Read on for useful techniques that you can apply to your own AI programming.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why basic solvers fail
&lt;/h1&gt;

&lt;p&gt;The easiest way to use an LLM to solve a code issue is simply to send the issue description to the LLM along with all the code files and prompt the LLM to generate a patch file. This is basically what the first generation of SWE bench solvers attempted to do. However, the solution rate of this approach is very low (single digit percents).  Why?&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;Wrong context&lt;/strong&gt; Most LLMs have a context limit which is too small to load the entire codebase. So, some guesses have to be made about which files to give the LLM. And when those guesses are wrong, the LLM fails to generate the right solution.&lt;/p&gt;

&lt;p&gt;2) &lt;strong&gt;Failed patching&lt;/strong&gt; LLMs are not good at creating patch files. Most LLM-generated patch files will fail to apply.&lt;/p&gt;

&lt;p&gt;3) &lt;strong&gt;Broken code&lt;/strong&gt; LLMs will generate code that is malformed. It won't even run cleanly, never mind pass the test cases.&lt;/p&gt;

&lt;p&gt;4) &lt;strong&gt;Wrong code design&lt;/strong&gt; The LLM does not understand the project design and architecture. So, it tries to solve the problem in the wrong place; or it fixes one problem while creating another.&lt;/p&gt;

&lt;p&gt;You can see some of these early solvers on the SWE bench leaderboard:&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%2Fplpj8td6mxgzyl0w8l5o.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%2Fplpj8td6mxgzyl0w8l5o.png" alt="Early SWE Bench solvers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Generation 2 - Agentic architecture
&lt;/h1&gt;

&lt;p&gt;The next generation of solvers adopted a more complex architecture, in an effort to solve the problems above.&lt;/p&gt;

&lt;p&gt;Basically, the idea of an "agent" is to give the LLM a wider variety of tools, and then run a loop in which the LLM chooses a tool and examines the results of using it.&lt;/p&gt;

&lt;p&gt;Tools do things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Search&lt;/code&gt; the code for a keyword&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Inspect&lt;/code&gt; a file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Run&lt;/code&gt; a program and examine the console output&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Edit&lt;/code&gt; a file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents do substantially better on the benchmark:&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%2Fr1kny5n6n2ouxutuiqdj.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%2Fr1kny5n6n2ouxutuiqdj.png" alt="Agents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, most of the "agentic" solutions only appear on the SWE Bench "Lite" leaderboard. Why is that? &lt;/p&gt;

&lt;p&gt;1) 💸 &lt;strong&gt;Cost&lt;/strong&gt; Every tool an agent uses consumes tokens. Tokens cost money. Agentic loops use tokens over and over.&lt;br&gt;
2) 🐢 &lt;strong&gt;Speed&lt;/strong&gt; By design, agentic solvers can take a lot of time to explore the problem space. They can backtrack and repeat things they've already done. They can get stuck. &lt;/p&gt;

&lt;h1&gt;
  
  
  AppMap Navie architecture - Semi-agentic
&lt;/h1&gt;

&lt;p&gt;Agents have a higher pass rate than Basic solvers, but they are slow and expensive. AppMap Navie takes an intermediate architecture, in which the solver is provided with powerful capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rich, but selective, code context to enable &lt;a href="https://research.ibm.com/blog/retrieval-augmented-generation-RAG" rel="noopener noreferrer"&gt;retrieval-augmented generation&lt;/a&gt; (RAG) architecture.&lt;/li&gt;
&lt;li&gt;A powerful and reliable tool for making file edits.&lt;/li&gt;
&lt;li&gt;Self-healing feedback for fixing code.&lt;/li&gt;
&lt;/ul&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%2Fr95e33a7gzxdorbm936r.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%2Fr95e33a7gzxdorbm936r.png" alt="Navie architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code context
&lt;/h2&gt;

&lt;p&gt;It's inefficient and expensive to send huge amounts of code context to the LLM. Embeddings are slow and expensive to generate. But without the right code context, the LLM-generated solution will fail. &lt;/p&gt;

&lt;p&gt;Navie uses a technique called "client-side RAG", in which the code is organized and searched locally. Client-side compute is fast, cheap, and much more efficient than sending huge token payloads to the LLM or building expensive embeddings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning
&lt;/h2&gt;

&lt;p&gt;With the right context selected, it's time to get right to code generation - right?&lt;/p&gt;

&lt;p&gt;Wrong. Before code generation comes Planning. Human developers don't dive into coding without some kind of plan. Building an understanding of the system architecture is an essential step, it can't be skipped over by humans, and it shouldn't be skipped by AI coders either.&lt;/p&gt;

&lt;p&gt;So, Navie performs an explicit planning step, in which the the issue description is combined with the context to produce a detailed plan. The plan includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A restatement of the problem.&lt;/li&gt;
&lt;li&gt;A high level solution description.&lt;/li&gt;
&lt;li&gt;A list of files to be modified.&lt;/li&gt;
&lt;li&gt;For each file, a description (no code, yet), of how that file will be changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an &lt;a href="https://gist.github.com/kgilpin/32857849619aed2e4d4df88152333909" rel="noopener noreferrer"&gt;example of a Navie-generated plan&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  File editing
&lt;/h2&gt;

&lt;p&gt;Now, with the plan in hand, the LLM is ready to change code files.&lt;/p&gt;

&lt;p&gt;Navie doesn't ask the LLM to generate patch files; it doesn't work. Instead, the LLM generates a "search / replace" pair of code snippets. This works most of the time, and a simple retry loop fixes up most of the occasions when it doesn't.&lt;/p&gt;

&lt;p&gt;Here are the &lt;a href="https://gist.github.com/kgilpin/c15fda05ee41e1f6ba16df33c8e9d869" rel="noopener noreferrer"&gt;Navie-generated code changes&lt;/a&gt; that implement the Plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lint repair
&lt;/h2&gt;

&lt;p&gt;The LLM still might get something wrong. Common cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mistakes with indenting (particularly with Python).&lt;/li&gt;
&lt;li&gt;Missing imports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Navie solver runs a linter, then feeds the linter errors back into the AI code editor. Most lint errors can be fixed this way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/kgilpin/9d7e77cbd87b2fc2f8c7a69817bea6d8" rel="noopener noreferrer"&gt;An example of lint errors fixed by Navie&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test repair
&lt;/h2&gt;

&lt;p&gt;Still not done! If the solution generated by Navie breaks existing tests, it's probably not going to fix the issue properly. So the Navie solver runs the application test cases to try and catch and fix any incompatibilities that may have been introduced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now, it's ready
&lt;/h2&gt;

&lt;p&gt;Now a patch file is created by simply diff-ing the AI-edited code with the Git base revision. This patch file is submitted to the SWE Bench harness for evaluation.&lt;/p&gt;

&lt;h1&gt;
  
  
  How is this so efficient?
&lt;/h1&gt;

&lt;p&gt;The Navie solver runs for about 1/3 the cost of most other solvers; and it's 95% cheaper than some of the most intensive agentic solvers on the benchmark (of those that post their costs; many don't 🙁). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Efficient client-side RAG context saves $$ on embeddings and LLM tokens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lint repair and test repair fixes solutions that might be almost, but not quite, correct. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A smaller "tool" suite and a linear approach to solving the problem prevents the LLM from wandering down dead ends or getting lost in pointless loops.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Ffypvf5w7rr9tc20suzwx.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%2Ffypvf5w7rr9tc20suzwx.png" alt="Dollar cost SWE bench"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Try Navie yourself!
&lt;/h1&gt;

&lt;p&gt;Navie is available today, with no wait list. Here's how to get Navie, or learn more about AppMap:&lt;/p&gt;

&lt;p&gt;⬇️ Download AppMap Navie for VSCode and JetBrains: &lt;a href="https://appmap.io/get-appmap" rel="noopener noreferrer"&gt;https://appmap.io/get-appmap&lt;/a&gt;&lt;br&gt;
⭐ Star AppMap on GitHub: &lt;a href="https://github.com/getappmap" rel="noopener noreferrer"&gt;https://github.com/getappmap&lt;/a&gt;&lt;br&gt;
📰 Follow on LinkedIn: &lt;a href="https://www.linkedin.com/company/appmap" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/appmap&lt;/a&gt;&lt;br&gt;
💬 Join AppMap Slack: &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;https://appmap.io/slack&lt;/a&gt;&lt;br&gt;
ℹ️ Read the AppMap docs: &lt;a href="https://appmap.io/docs" rel="noopener noreferrer"&gt;https://appmap.io/docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vscode</category>
      <category>llm</category>
      <category>python</category>
    </item>
    <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>Announcing AppMap for GitHub - Runtime Code Reviews for Every Pull Request</title>
      <dc:creator>Kevin Gilpin</dc:creator>
      <pubDate>Thu, 09 Nov 2023 01:17:20 +0000</pubDate>
      <link>https://dev.to/appmap/announcing-appmap-for-github-runtime-code-reviews-for-every-pull-request-47km</link>
      <guid>https://dev.to/appmap/announcing-appmap-for-github-runtime-code-reviews-for-every-pull-request-47km</guid>
      <description>&lt;p&gt;Most of us have a love-hate relationship with code reviews. We rely on code reviews to ensure that the code we send to production is clean, performs well, and is free of security flaws. But code reviews can also add a lot of overhead and delays to shipping code.&lt;/p&gt;

&lt;p&gt;Some people suggest that code reviews should be eliminated altogether. Well, I'm not in that camp, and here's why: Unexpected code behavior and deep runtime defects are responsible for a staggering 40% of performance problems¹ and 50% of security concerns² in software development. But, I do think that it's important to make code reviews easier for developers, and at AppMap we've created AppMap for CI to help do that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Security and performance reviews are part of the process on any engineering team, and ours is no different. It can take months to find issues and weeks to fix problems using static analysis and code reads. With AppMap, that time is reduced to minutes.”&lt;br&gt;&lt;br&gt;
 -Padraig Coffey, CEO at Zartis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you know AppMap already, you know us for our &lt;a href="https://marketplace.visualstudio.com/items?itemName=appland.appmap"&gt;VS Code&lt;/a&gt; and &lt;a href="https://plugins.jetbrains.com/plugin/16701-appmap"&gt;JetBrains&lt;/a&gt; extensions that automatically generate complete, accurate, interactive diagrams of your code. So now, with AppMap for CI, we've built on the solid foundation of AppMap to make code reviews easier, better, and faster. &lt;/p&gt;

&lt;p&gt;The first CI platform we support is GitHub Actions. Our solution combines an &lt;a href="https://github.com/marketplace/get-appmap"&gt;AppMap GitHub App&lt;/a&gt; with GitHub Actions. When you build your project, the &lt;a href="https://github.com/marketplace/actions/appmap-analysis"&gt;AppMap Analysis Action&lt;/a&gt; analyzes AppMaps from before and after each code change. It's able to identify critical performance, security, and stability issues and annotate specific lines of code in the pull request. It also performs deep analysis of test case failures and web service API changes, giving you a big head start on code review. And by the way, the performance and security flaws that AppMap finds are not discoverable by static analysis tools - because modern code is too dynamic for static analysis tools to understand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“When we initially adopted AppMap, we were only using it for visualizing N+1 queries locally. We later integrated it into our CI run, and we are finding the GitHub comments posted by AppMap to be very useful. The OpenAPI integration, in particular, was a surprise: it’s nice to see an automatically generated summary of what endpoints have changed in a PR."&lt;br&gt;&lt;br&gt;
-Paul Kuruvilla, CTO at CodeCrafters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Your data stays with you
&lt;/h2&gt;

&lt;p&gt;We know that your code is sensitive, and you don't want it to be transmitted to 3rd parties. All AppMaps are stored as artifacts in your GitHub build system and are sent directly to your browser when you view them. The data only resides in two places - the GitHub Actions environment, and your machine. &lt;a href="https://appmap.io/security"&gt;Learn more at appmap.io/security&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tour of AppMap's "runtime code review"
&lt;/h2&gt;

&lt;p&gt;✅ AppMap issues a summary report of its runtime analysis as a comment on every PR. The PR comment includes four key categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Failed tests&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Identifies the root cause of test failures with detailed insights and direct links to the line of code which caused the error. AppMap also includes source diffs and behavioral sequence diffs for efficient debugging.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Changes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Detects API route differences, including new, deleted, or modified routes, as well as alterations in response attributes like body, content, and descriptions.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security flaws&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uncovers issues such as broken or missing access control, deprecated cryptography, improper session management, and missing authentication. AppMap focuses on the runtime security flaws that dominate the &lt;a href="https://owasp.org/www-project-top-ten/"&gt;OWASP Top 10&lt;/a&gt;, and can't be reliably detected by static analysis.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance problems&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Identifies performance problems like N+1 SQL queries, very complex queries, RPC anti-patterns, and plain old slow code. &lt;/p&gt;

&lt;h3&gt;
  
  
  Example - Performance problems
&lt;/h3&gt;

&lt;p&gt;Here's an example of a code change that introduces four new performance problems.&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%2F0dz2ozc0mfx7vkm21yr7.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%2F0dz2ozc0mfx7vkm21yr7.png" alt="Performance flaw summary" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AppMap runtime code review includes details about the flaws detected, a stack trace, and links to the offending source code.&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%2Fczksqcrzdzo1lkvbwrg1.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%2Fczksqcrzdzo1lkvbwrg1.png" alt="Performance flaw details" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AppMap highlights specific code changes that are contributing to the flaw. It's able to focus on the specific code changes that are relevant to the newly introduced problem.&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%2F2ol3cuyvbgm2t0ganr2t.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%2F2ol3cuyvbgm2t0ganr2t.png" alt="Performance flaw source diff" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AppMap also links to an interactive "diff" diagram showing how the code change has introduced the flaw. &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%2F0zyypkgqcyuayedl3q9j.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%2F0zyypkgqcyuayedl3q9j.png" alt="Performance flaw source diff" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example - Security flaw
&lt;/h3&gt;

&lt;p&gt;Here is an example of AppMap describing a security flaw and the code change that produced it.&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%2F9u4re8g0orrz58xpwgx7.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%2F9u4re8g0orrz58xpwgx7.png" alt="Security flaw details" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Included in the comment is a stack trace showing what led to the security flaw, including links to the source code.&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%2F7hg757k5xitiwrjrj9hr.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%2F7hg757k5xitiwrjrj9hr.png" alt="Security flaw stack trace" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AppMap also provides a full set of interactive visualizations that describe the code behavior that resulted in the security flaw.&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%2Fq7ayep580rg2f3fvo3q0.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%2Fq7ayep580rg2f3fvo3q0.png" alt="Security flaw AppMap" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;To get started, &lt;a href="https://github.com/marketplace/get-appmap"&gt;install the AppMap GitHub App from the GitHub Marketplace.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Not ready to try it for yourself? We have &lt;a href="https://appmap.io/docs/setup-appmap-in-ci/example-projects.html"&gt;example projects on our GitHub&lt;/a&gt; so you can check out AppMap for GitHub Actions at work. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 AppMap for GitHub Actions: &lt;a href="https://getappmap.com"&gt;https://getappmap.com&lt;/a&gt;&lt;br&gt;
⬇️ Download AppMap for VSCode and JetBrains: &lt;a href="https://appmap.io/download"&gt;https://appmap.io/download&lt;/a&gt;&lt;br&gt;
⭐ Star AppMap on GitHub: &lt;a href="https://github.com/getappmap"&gt;https://github.com/getappmap&lt;/a&gt;&lt;br&gt;
📹 Follow on: &lt;a href="https://youtube.com/@appmap"&gt;https://youtube.com/@appmap&lt;/a&gt;&lt;br&gt;
💬 Join AppMap Slack: &lt;a href="https://appmap.io/slack"&gt;https://appmap.io/slack&lt;/a&gt;&lt;br&gt;
ℹ️ Read the AppMap docs: &lt;a href="https://appmap.io/docs"&gt;https://appmap.io/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://research.facebook.com/publications/fausta-scaling-dynamic-analysis-with-traffic-generation-at-whatsapp/"&gt;(1) FAUSTA: Scaling Dynamic Analysis with Traffic Generation at WhatsApp
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cwe.mitre.org/top25/"&gt;(2) CWE Top 25 Most Dangerous Software Weaknesses&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>java</category>
      <category>python</category>
      <category>node</category>
    </item>
    <item>
      <title>Unlock developer creativity with GitHub Actions</title>
      <dc:creator>Kevin Gilpin</dc:creator>
      <pubDate>Tue, 24 Oct 2023 16:27:48 +0000</pubDate>
      <link>https://dev.to/appmap/unlock-developer-creativity-with-github-actions-211j</link>
      <guid>https://dev.to/appmap/unlock-developer-creativity-with-github-actions-211j</guid>
      <description>&lt;p&gt;Since its release in November 2019, GitHub Actions has continued to gain in popularity. Fully 72% of &lt;a href="https://appmap.io" rel="noopener noreferrer"&gt;AppMap&lt;/a&gt; users tell us that their team is using GitHub Actions! I've been personally using GitHub Actions intensively for about six months, and it feels to me like a substantial leap forward in automation technology. Why? As CI/CD has gained importance, it has increasingly become disconnected from the productivity needs of developers, primarily due to security concerns. I find that GitHub Actions allows me to automate code in innovative ways that are not possible within the confines of traditional CI/CD pipelines. &lt;/p&gt;

&lt;h2&gt;
  
  
  How GitHub Actions works
&lt;/h2&gt;

&lt;p&gt;In case you're new to GitHub Actions, here's a quick overview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub Action is a &lt;strong&gt;code snippet&lt;/strong&gt; that runs on &lt;strong&gt;GitHub-hosted infrastructure&lt;/strong&gt; (or you can provide your own compute).&lt;/li&gt;
&lt;li&gt;GitHub Actions can be &lt;strong&gt;combined&lt;/strong&gt; together into sequences called &lt;strong&gt;Workflows&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A GitHub action can be defined in a GitHub repository, and imported by other projects. So they are highly &lt;strong&gt;sharable&lt;/strong&gt; and reusable.&lt;/li&gt;
&lt;li&gt;A Workflow is a &lt;strong&gt;YAML&lt;/strong&gt; file that lives in the &lt;code&gt;.github&lt;/code&gt; folder of the code itself. &lt;/li&gt;
&lt;li&gt;Because a workflow is a git-managed file, each &lt;strong&gt;version&lt;/strong&gt; of the code &lt;strong&gt;can have its own workflows&lt;/strong&gt;. That makes it easy to try out new workflows on a branch, and then merge them to &lt;code&gt;main&lt;/code&gt; when they are debugged.&lt;/li&gt;
&lt;li&gt;There are lots of different ways to &lt;strong&gt;trigger workflows&lt;/strong&gt;. Common triggers include "run on pull request", "run on push", and "run on schedule".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this combination of features, GitHub Actions gives developers the power to easily create just about any kind of code automation. &lt;/p&gt;

&lt;h2&gt;
  
  
  How we got here
&lt;/h2&gt;

&lt;p&gt;I'm, um, old enough that when I started my career, manual builds were the norm. Build automation tools like Jenkins came along pretty soon afterwards, and brought repeatability to the build + test + package cycle. &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%2Flyn1p38d4o9yoiqv801g.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%2Flyn1p38d4o9yoiqv801g.png" alt="Good 'ol Jenkins"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deployment was still almost always a manual step. The next big step was CI/CD, which moved build automation to cloud-hosted infrastructure and also automated the deploy steps - this, of course, was made possible by cloud computing infrastructure: Amazon EC2 and all the services that derived from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trouble in paradise
&lt;/h2&gt;

&lt;p&gt;CI/CD became the core of DevOps, which expanded automation into many new areas. Most of this growth and expansion has been very positive, but the rigor of the automation has actually had some drawbacks for developers. Why? Because CI/CD has such &lt;em&gt;so&lt;/em&gt; much power to package and deploy code, it's also become an area of high security risk.&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%2Fcjrgbn6vzs3hy6xmol0l.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%2Fcjrgbn6vzs3hy6xmol0l.png" alt="Cyber attack on the CI/CD pipeline"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hackers quickly identified and exploited multiple avenues of attack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inject malicious code directly into the target software as it's being built.&lt;/li&gt;
&lt;li&gt;Use a compromised CI job is a stepping-stone for access to production systems.&lt;/li&gt;
&lt;li&gt;Use inside knowledge of the code to build the perfect exploit or backdoor. &lt;/li&gt;
&lt;li&gt;Attack the CI/CD vendor directly to obtain credentials in bulk. (Four well-known vendors in the CI/CD space have all been breached in the last decade).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security is a real concern with CI/CD systems. As a result, they are now highly protected. This is necessary - but it's also meant that CI/CD is not a developer-friendly environment anymore. CI/CD is too tightly controlled to be a good place for developers to try out new experiments in code automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions to the rescue
&lt;/h2&gt;

&lt;p&gt;This is where GitHub Actions comes in. A GitHub Action does  &lt;em&gt;not&lt;/em&gt; need to be part of the "blessed" CI/CD process. It can perform any kind of ad-hoc job that a developer might want it to. For example, there are GitHub Actions to report test status, inject comments into commits and PRs, synchronize with other systems, generate code, send notifications, look for bugs, etc. And it can do these things "off to the side", out of the way of the official pipeline job. It's no longer necessary to modify the master build file (think: &lt;code&gt;travis.yml&lt;/code&gt;, &lt;code&gt;Jenkinsfile&lt;/code&gt;, &lt;code&gt;.circleci&lt;/code&gt;) in order to try out some new code automation. &lt;/p&gt;

&lt;p&gt;Since Actions are controlled by YAML files that any developer can create and modify - and they run in the cloud with direct and easy access to project source code - GitHub Actions combine power and safety in a way that's not found either in local developer environments or in traditional CI/CD tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Powerful, tune-able performance
&lt;/h2&gt;

&lt;p&gt;As a developer, you have a good understanding of performance considerations such as CPU capabilities, memory use, and parallelization. So, you'll be glad to know that GitHub Actions is powerful enough to let you control and optimize exactly how your workflow uses and consumes compute and storage. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Each Workflow runs on a pre-defined runner instance, which is basically a container running with a pre-defined allocation of CPU cores and amount of memory. So you can run small, lightweight jobs with little cost.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is your Workflow slow and sluggish? You've got options; several options in fact. First, you can bump the workflow up to a larger runner instance. How does 64 cores and 256GB of RAM sound? You can get that. What if the code you are running doesn't scale that well with cores? Well, you can apply matrix build strategies as well. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can store and retrieve data within and across workflows. Both a cache store and artifact store are available. The cache is really fast, and it can only be accessed from within Workflows. Artifacts are slower, but they can be accessed from anywhere using the GitHub REST API. Cache expiration times and artifact retention times are both customizable, so you can tune the amount of money you are spending on these storage resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Proceed! (With caution)
&lt;/h2&gt;

&lt;p&gt;While it is separate from the official CI/CD pipeline, the privileged operation of GitHub Actions does still pose a security risk. GitHub Actions have access to the code; can commit and push code; can be given access to secrets that may be mishandled. Recognizing this, GitHub provides repository and organization settings that can be used to control which GitHub Actions are allowed to run, and even whether the feature is enabled at all. &lt;/p&gt;

&lt;p&gt;Furthermore, each GitHub Action Workflow runs with its own explicit permissions. So, the security capabilities of each Workflow are clearly stated, and less-trusted Actions can be run with lower privilege settings than more-trusted Actions. This type of "least-privilege" access management is a highly effective security strategy, and it's not possible in monolithic and/or legacy CI/CD jobs. &lt;/p&gt;

&lt;p&gt;As always, freedom comes with responsibility and we've heard of at least one organization that has locked its developers out of GitHub Actions after incidents of careless, insecure coding. So, be aware and mindful of the security controls that are available, and use them!&lt;/p&gt;

&lt;h2&gt;
  
  
  How we're using GitHub Actions and AppMap together to improve code quality
&lt;/h2&gt;

&lt;p&gt;AppMap is a tool that records code traces into JSON data files, which can be visualized and analyzed to improve code understanding and quality. GitHub Actions offers a way to create a comprehensive AppMap data set for every pull request, providing a complete profile of the runtime architecture, performance, and security characteristics of your application.  It also offers a way to compare the AppMap data sets of two different code versions. &lt;/p&gt;

&lt;p&gt;Comparing AppMaps of two code versions (a baseline and a proposed change set) is an amazingly powerful technique for analyzing code for architecture changes, security flaws and performance problems. With &lt;a href="https://appmap.io/product/appmap-in-ci" rel="noopener noreferrer"&gt;AppMap for GitHub Actions&lt;/a&gt;, we are offering exactly this capability. Our Early Access program is wrapping up now, and we are transitioning to general availability. Come check it out!&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%2Fj29aweqvac13h8zpaggg.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%2Fj29aweqvac13h8zpaggg.png" alt="AppMap for GitHub Actions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because AppMap runs in &lt;em&gt;your&lt;/em&gt; GitHub account, the data is processed within your account and it stays within the boundaries of it. You don't have to share source code or sensitive data with any third party. This is the type of win/win/win capability that GitHub Actions offers. A high level of developer control, good performance, and good security characteristics.&lt;/p&gt;

&lt;h2&gt;
  
  
  How are you using GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;Has your organization adopted GitHub Actions? How enabled are developers to add and change GitHub Actions? Did you encounter any problems or mishaps along the way that others could benefit from hearing about? We would love to hear about it in the comments below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 Get Early Access to AppMap for GitHub Actions: &lt;a href="https://getappmap.com" rel="noopener noreferrer"&gt;https://getappmap.com&lt;/a&gt;&lt;br&gt;
⬇️ Download AppMap for VSCode and JetBrains: &lt;a href="https://appmap.io/download" rel="noopener noreferrer"&gt;https://appmap.io/download&lt;/a&gt;&lt;br&gt;
⭐ Star AppMap on GitHub: &lt;a href="https://github.com/getappmap" rel="noopener noreferrer"&gt;https://github.com/getappmap&lt;/a&gt;&lt;br&gt;
📹 Follow on: &lt;a href="https://youtube.com/@appmap" rel="noopener noreferrer"&gt;https://youtube.com/@appmap&lt;/a&gt;&lt;br&gt;
💬 Join AppMap Slack: &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;https://appmap.io/slack&lt;/a&gt;&lt;br&gt;
ℹ️ Read the AppMap docs: &lt;a href="https://appmap.io/docs" rel="noopener noreferrer"&gt;https://appmap.io/docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>githubactions</category>
      <category>productivity</category>
      <category>cicd</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>6 super nerdy podcasts &amp; channels</title>
      <dc:creator>Jen Wike Huger</dc:creator>
      <pubDate>Wed, 09 Aug 2023 02:29:34 +0000</pubDate>
      <link>https://dev.to/appmap/6-super-nerdy-podcasts-1bo2</link>
      <guid>https://dev.to/appmap/6-super-nerdy-podcasts-1bo2</guid>
      <description>&lt;p&gt;Last week, the AppMap team shared their &lt;a href="https://dev.to/appmap/8-great-software-tech-podcasts-2023-4642"&gt;8 favorite tech and software podcasts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We're developers, so the media we consume covers the complexity of the software industry... and a ton of NERDY stuff, too! Like Linux, web dev, and the 2000s. &lt;/p&gt;

&lt;p&gt;Let's get into it.&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;h2&gt;
  
  
  &lt;a href="https://shoptalkshow.com" rel="noopener noreferrer"&gt;Shop Talk Show&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Dave Rupert and Chris Coyier produce a weekly podcast about building websites - front end web design, development, and UX. They have guests and answer listener submitted questions. &lt;a href="https://shoptalkshow.com/573/" rel="noopener noreferrer"&gt;This one&lt;/a&gt; features a banjo! and thoughts on long-dead Google Reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.giantrobots.fm/" rel="noopener noreferrer"&gt;GIANT ROBOTS&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;... SMASHING INTO OTHER GIANT ROBOTS. Rotating between three hosts, this podcast is "about the design, development, and business of great software." Recently &lt;a href="https://www.giantrobots.fm/484" rel="noopener noreferrer"&gt;they interviewed Brittany Martin&lt;/a&gt;, a co-host of The Ruby on Rails Podcast, a podcast featured in &lt;a href="https://dev.to/appmap/8-great-software-tech-podcasts-2023-4642"&gt;our last post&lt;/a&gt;. Oh, &lt;a href="https://www.giantrobots.fm/475" rel="noopener noreferrer"&gt;and here's my friend Lauren Maffeo&lt;/a&gt;, the author of Designing Data Governance from the Ground Up.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://youtube.com/@CathodeRayDude" rel="noopener noreferrer"&gt;Cathode Ray Dude&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The host of this YouTube channel &lt;a href="https://www.youtube.com/watch?v=6Z524I1cy2k" rel="noopener noreferrer"&gt;quit his day job a month ago&lt;/a&gt; and is now much happier spending his energy on his video channel (not really a podcast) about "cameras, computer mice, and the 2000s."&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://podcasts.proof.xyz/" rel="noopener noreferrer"&gt;PROOF&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This podcast is all about in-depth NFT coverage. Venture capitalist Kevin Rose and team "interview NFT artists, both up-and-coming and industry icons. [They] also cover the generative art scene, the NFT gaming/metaverse, and founders building new tools for creators and collectors." I like cool domains so will be checking out &lt;a href="https://podcasts.proof.xyz/100-proof-live-the-future-of-3d-art-david-greenstein-of-soundxyz/" rel="noopener noreferrer"&gt;this one with David Greenstein&lt;/a&gt;, co-founder of sound.xyz.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://youtube.com/@TheLinuxEXP" rel="noopener noreferrer"&gt;The Linux Experiment&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The host, Nick, treats this as a safe space with "no techno babble, no super technical content" that focuses on "Linux desktop news, simple tutorials, application spotlights, and opinion pieces trying to stay positive, without gatekeeping." It's no surprise that his step-by-step walkthrough of &lt;a href="https://www.youtube.com/watch?v=ro6IWsT3uRk" rel="noopener noreferrer"&gt;how to switch to Linux&lt;/a&gt; has a gazillion views.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://a16z.com/podcast-episodes/" rel="noopener noreferrer"&gt;The a16z Podcast&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The team at Andreessen Horowitz, a silicon valley venture capital firm, interviews "industry experts, business leaders, and other interesting thinkers and voices from around the world." Interestingly, &lt;a href="https://future.com/announcing-search-new-host-the-a16z-podcast/" rel="noopener noreferrer"&gt;they are looking for the next host of the podcast&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Got any super nerdy podcasts or video channels to share with us? We need more, clearly.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>8 great software &amp; tech podcasts 2023</title>
      <dc:creator>Jen Wike Huger</dc:creator>
      <pubDate>Thu, 03 Aug 2023 20:40:40 +0000</pubDate>
      <link>https://dev.to/appmap/8-great-software-tech-podcasts-2023-4642</link>
      <guid>https://dev.to/appmap/8-great-software-tech-podcasts-2023-4642</guid>
      <description>&lt;p&gt;Podcasts come and go. Time and energy to listen to them also. And what a wonderful innovation they are, especially when you are learning or working in a field like software and tech.&lt;/p&gt;

&lt;p&gt;Millions of developers means the complexity of the industry, business, culture, news, and let's not forget... the technology itself, is seemingly endless.&lt;/p&gt;

&lt;p&gt;All you must ask is "What do I need to learn today?" and the answer will reveal itself quickly with a few keystrokes. Yet, with countless options and podcasters talking about their perspective on everything from AI to apple pie, how will you narrow it down?&lt;/p&gt;

&lt;p&gt;To help with that, today we're sharing the &lt;a href="https://appmap.io/" rel="noopener noreferrer"&gt;AppMap&lt;/a&gt; team's favorite podcasts. Enjoy, and let us know what you're listening to!&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;h2&gt;
  
  
  Software &amp;amp; tech podcasts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.se-radio.net/" rel="noopener noreferrer"&gt;Software Engineering Radio&lt;/a&gt;&lt;br&gt;
The self-proclaimed "authority on translating software theory into practice." &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.arresteddevops.com/" rel="noopener noreferrer"&gt;Arrested DevOps&lt;/a&gt;&lt;br&gt;
Want to maximize your DevOps-ing? Check it out. One of our team has been a guest here, too!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.dataengineeringpodcast.com/" rel="noopener noreferrer"&gt;Data Engineering Podcast&lt;/a&gt;&lt;br&gt;
Get the goods on data management with guest engineers and entrepreneurs who are shaping the industry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language-specific podcasts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://airhacks.fm/" rel="noopener noreferrer"&gt;airhacks.fm podcast with Adam Bien&lt;/a&gt;&lt;br&gt;
Stellar discussions on Java, serverless, cloud, architecture, and web!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.therubyonrailspodcast.com/" rel="noopener noreferrer"&gt;The Ruby on Rails Podcast&lt;/a&gt;&lt;br&gt;
Still going strong, this podcast is a weekly conversation about Ruby on Rails, open source software, and the programming profession.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pythonpodcast.com/" rel="noopener noreferrer"&gt;The Python Podcast.&lt;strong&gt;init&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
Another one where we've been a guest, this is a podcast about Python and the people who make it great.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deeper stuff
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://darknetdiaries.com/" rel="noopener noreferrer"&gt;Darknet Diaries&lt;/a&gt;&lt;br&gt;
The description says it all: "Explore true stories of the dark side of the Internet with host Jack Rhysider as he takes you on a journey through the chilling world of hacking, data breaches, and cyber crime." &lt;/p&gt;

&lt;p&gt;&lt;a href="https://lexfridman.com/podcast/" rel="noopener noreferrer"&gt;The Lex Fridman Podcast&lt;/a&gt;&lt;br&gt;
One for that higher level, about the nature of intelligence, consciousness, love, and power. Oooo!&lt;/p&gt;

&lt;p&gt;What would you add to this list? Any favorites to share with us? We'd love to hear about them and give them a listen!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>Improve application performance: How to find and fix slow function calls, HTTP requests, and SQL queries</title>
      <dc:creator>Garrett Hamelin</dc:creator>
      <pubDate>Fri, 21 Jul 2023 16:53:43 +0000</pubDate>
      <link>https://dev.to/appmap/improve-application-performance-how-to-find-and-fix-slow-function-calls-http-requests-and-sql-queries-1pf9</link>
      <guid>https://dev.to/appmap/improve-application-performance-how-to-find-and-fix-slow-function-calls-http-requests-and-sql-queries-1pf9</guid>
      <description>&lt;p&gt;Runtime analysis is the latest and greatest way for developers to find, flag, and fix software flaws before production. Our series on rules and their impact is focused in this article on Slow Function Calls, HTTP Requests, and SQL Queries.&lt;/p&gt;

&lt;p&gt;I will review what these rules mean and how to enhance your application performance using AppMap. &lt;/p&gt;

&lt;p&gt;If you learn better through video you can check out a walkthrough of these rules here: &lt;/p&gt;

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

&lt;h2&gt;
  
  
  Slow function calls
&lt;/h2&gt;

&lt;p&gt;In this first example, let’s use AppMap to locate a performance finding related to slow function calls and use the new flame graph view to see the duration of each function call. It's crucial to optimize those long-running functions, as they can significantly impact performance. Often slow function calls are caused by poor code practices, inadequate algorithms, or excessive resource consumption, leading to scalability issues, bottlenecks in system responsiveness, and even user frustration&lt;/p&gt;

&lt;p&gt;To illustrate this, let's examine code snippets related to slow renders and highlight the usage of partials. Repeated rendering of partials within loops can significantly impact performance.&lt;/p&gt;

&lt;p&gt;For some context, the example we are dissecting today is an e-commerce merch store. To make sure we are all on the same page, the AppMap we are looking at outlines the user interaction of a user selecting featured products to view. The function in question &lt;code&gt;ActionController::Renderers#render_to_body&lt;/code&gt; can be plainly seen in the flame graph.&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%2F3s0jrb2quwbsub1n3j3h.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%2F3s0jrb2quwbsub1n3j3h.png" alt="Flame Graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we dig a little deeper and see what is actually happening.&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%2Fiuzzm9lz7clcj4o4742m.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%2Fiuzzm9lz7clcj4o4742m.png" alt="Render function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that &lt;code&gt;Render_to_body&lt;/code&gt; calls &lt;code&gt;render_to_body_with_renderer&lt;/code&gt; which gets passed a series of options. Looking into the function itself we see the &lt;code&gt;_renderers.each do ...&lt;/code&gt;which, when passed a file with a lot of partials that need to be rendered, some containing caching operations themselves, we start to understand exactly why this function runs for such a long time. &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%2Fcsojgpjr19temkgno02a.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%2Fcsojgpjr19temkgno02a.png" alt="Partials being rendered"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at the trace view, we can see just how many children are spawned and will complete before we can return from the original calling function. &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%2Flqgz0093055v2o4f55nl.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%2Flqgz0093055v2o4f55nl.png" alt="stack trace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To mitigate this we may want to reduce the number of partials that we are individually working with. Good coding practices encourage abstraction and code reuse but doing so may have introduced a performance concern. We need to be careful that we don’t abstract which can impact the performance of our application at runtime. &lt;/p&gt;

&lt;h2&gt;
  
  
  Slow HTTP requests and SQL queries
&lt;/h2&gt;

&lt;p&gt;Slow HTTP requests and SQL queries often stem from a range of situations, ranging from suboptimal coding practices, inefficient schemas and configuration, or lack of indexing to lack of resources available, and high network congestion. We need to be aware of potential causes, such as the lack of caching HTTP requests or leveraging a content delivery network (CDN) for faster content delivery. &lt;/p&gt;

&lt;h2&gt;
  
  
  Find and fix performance issues
&lt;/h2&gt;

&lt;p&gt;To address slow function calls, HTTP requests, and SQL queries, we can implement effective mitigation strategies by updating our coding practices and improving resource management. For slow renders, alternative home or index views can be used to minimize the number of function calls. Additionally, you can leverage caching techniques and pre-render pages that don't require dynamic data, as well as load-balancing techniques to reduce the pressure on our network. &lt;/p&gt;

&lt;h2&gt;
  
  
  In summary
&lt;/h2&gt;

&lt;p&gt;To improve application performance, it’s important to identify and optimize slow function calls, HTTP requests, and SQL queries.&lt;/p&gt;

&lt;p&gt;AppMap’s flame graphs and other tools like the &lt;a href="https://dev.to/appmap/quickly-learn-how-new-to-you-code-works-using-sequence-diagrams-h9g"&gt;interactive sequence diagram&lt;/a&gt; make it easy to pinpoint performance bottlenecks and implement appropriate mitigation strategies. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⬇️ Download AppMap for VSCode and JetBrains: &lt;a href="https://appmap.io/download" rel="noopener noreferrer"&gt;https://appmap.io/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⭐ Star AppMap on GitHub: &lt;a href="https://github.com/getappmap" rel="noopener noreferrer"&gt;https://github.com/getappmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🐦 Follow on Twitter: &lt;a href="https://twitter.com/getappmap" rel="noopener noreferrer"&gt;https://twitter.com/getappmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 Join AppMap Slack: &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;https://appmap.io/slack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ℹ️ Read the AppMap docs: &lt;a href="https://appmap.io/docs" rel="noopener noreferrer"&gt;https://appmap.io/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📺 Watch AppMap Tutorials: &lt;a href="https://www.youtube.com/@appmap" rel="noopener noreferrer"&gt;https://www.youtube.com/@appmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📸 Cover Photo by &lt;a href="https://unsplash.com/@rwlinder?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Robert Linder&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/road-work?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__1045236"&gt;
    &lt;a href="/ghamelin" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F1045236%2Fed6cdfef-5c3f-4fdc-aff4-e5b40aadaf05.jpeg" alt="ghamelin image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/ghamelin"&gt;Garrett Hamelin&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/ghamelin"&gt;I love technology and everything about it. I'm a software engineer who enjoys helping others succeed and building communities of like minded people. &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>performance</category>
      <category>vscode</category>
      <category>java</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Introducing Flame graphs: It’s getting hot in here</title>
      <dc:creator>Garrett Hamelin</dc:creator>
      <pubDate>Fri, 14 Jul 2023 18:47:50 +0000</pubDate>
      <link>https://dev.to/appmap/introducing-flame-graphs-its-getting-hot-in-here-1j9l</link>
      <guid>https://dev.to/appmap/introducing-flame-graphs-its-getting-hot-in-here-1j9l</guid>
      <description>&lt;p&gt;Flame graphs help developers identify code bottlenecks and understand code execution patterns, so we’re excited to announce they are now available within the AppMap extension for VS Code and JetBrains editors like IntelliJ. &lt;/p&gt;

&lt;p&gt;“&lt;a href="https://www.brendangregg.com/flamegraphs.html" rel="noopener noreferrer"&gt;Flame graphs&lt;/a&gt; are a visualization of hierarchical data, created to visualize stack traces of profiled software so that the most frequent code-paths to be identified quickly and accurately.”&lt;/p&gt;

&lt;p&gt;In this article, I explore how they work, and how to generate and use them with AppMap.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to read a flame graph
&lt;/h3&gt;

&lt;p&gt;Flame graphs are read from bottom to top, left to right, providing a holistic view of function execution. In this video, you can see how I identify time-consuming functions and visualize the sequence of operations.&lt;/p&gt;

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

&lt;p&gt;To make sense of the flame graphs, we must first understand the color scheme. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Purple represents &lt;code&gt;SQL queries&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Blue indicates &lt;code&gt;classes&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, or &lt;code&gt;functions&lt;/code&gt; that follow in the execution flow&lt;/li&gt;
&lt;li&gt;Yellow denotes &lt;code&gt;external service calls&lt;/code&gt; (absent in this video)&lt;/li&gt;
&lt;li&gt;Teal is the name of the AppMap&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What you get with flame graphs
&lt;/h3&gt;

&lt;p&gt;Flame Graphs reveal crucial insights about application performance. Each function in the graph is labeled with its corresponding execution time in milliseconds or microseconds. This detailed breakdown allows developers to pinpoint long-running queries and functions, optimizing code efficiency.&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%2Frmm36w2989yk8slhw7fj.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%2Frmm36w2989yk8slhw7fj.png" alt="Flame Graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Zooming in on the graph or selecting a specific function provides a deeper understanding of the call stack and execution sequence. For example, the demonstration showcased the occurrence of a selector before an active support call, shedding light on the execution flow. This level of granularity empowers developers to tackle complex performance issues head-on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revealing performance issues&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By examining the graph, developers can detect common issues like N+1 queries, a notorious problem in application development. The ability to visualize the duration of each query or function provides actionable insights, highlighting areas for improvement.&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%2Fz80o865m9k1tm6ozr0o3.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%2Fz80o865m9k1tm6ozr0o3.png" alt="Flame Graph Analysis Highlight"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flame graphs also expose the impact of long-running functions on overall performance. While some functions, like renders to body, are intended to run longer, others such as support services and callbacks, should be optimized for efficiency. The graph's tally of execution times offers a comprehensive overview, ensuring developers can focus their efforts where they matter most.&lt;/p&gt;

&lt;p&gt;AppMap improves on flame graphs by highlighting the flaws in your application and shows you the direct impact of a specific flaw on your application. No more searching to figure out where an N+1 query happened or how many times it ran!&lt;/p&gt;

&lt;h3&gt;
  
  
  Flame graphs, sequence diagrams, and more
&lt;/h3&gt;

&lt;p&gt;Try AppMap today to help you identify issues with your code or refactor an existing code base. Use our new flame graph and sequence diagram views. We also have traditional dependency and trace views. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⬇️ Download AppMap for VSCode and JetBrains: &lt;a href="https://appmap.io/download" rel="noopener noreferrer"&gt;https://appmap.io/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⭐ Star AppMap on GitHub: &lt;a href="https://github.com/getappmap" rel="noopener noreferrer"&gt;https://github.com/getappmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🐦 Follow on Twitter: &lt;a href="https://twitter.com/getappmap" rel="noopener noreferrer"&gt;https://twitter.com/getappmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 Join AppMap Slack: &lt;a href="https://appmap.io/slack" rel="noopener noreferrer"&gt;https://appmap.io/slack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ℹ️ Read the AppMap docs: &lt;a href="https://appmap.io/docs" rel="noopener noreferrer"&gt;https://appmap.io/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📺 Watch AppMap Tutorials: &lt;a href="https://www.youtube.com/@appmap" rel="noopener noreferrer"&gt;https://www.youtube.com/@appmap&lt;/a&gt;&lt;br&gt;
 &lt;br&gt;
 &lt;br&gt;
 &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__1045236"&gt;
    &lt;a href="/ghamelin" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F1045236%2Fed6cdfef-5c3f-4fdc-aff4-e5b40aadaf05.jpeg" alt="ghamelin image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/ghamelin"&gt;Garrett Hamelin&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/ghamelin"&gt;I love technology and everything about it. I'm a software engineer who enjoys helping others succeed and building communities of like minded people. &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>ruby</category>
      <category>vscode</category>
      <category>python</category>
      <category>java</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>Exploring" Too Many Updates": How to find and fix a code issue for a large number of outward calls</title>
      <dc:creator>Garrett Hamelin</dc:creator>
      <pubDate>Fri, 07 Jul 2023 18:59:37 +0000</pubDate>
      <link>https://dev.to/appmap/how-to-identify-and-fix-sql-and-rpc-updates-with-runtime-analysis-51aj</link>
      <guid>https://dev.to/appmap/how-to-identify-and-fix-sql-and-rpc-updates-with-runtime-analysis-51aj</guid>
      <description>&lt;p&gt;Whether you're a software engineer looking to optimize your code or just eager to understand &lt;a href="https://dev.to/appmap/how-appmaps-runtime-analysis-finds-performance-and-security-flaws-4p0k"&gt;runtime analysis&lt;/a&gt;, this article will help you think about rules as they relate to code analysis.&lt;/p&gt;

&lt;p&gt;In this article, I explore a maintenance rule called "Too Many Updates" and discuss its implications, causes, and mitigation strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the rule
&lt;/h2&gt;

&lt;p&gt;At AppMap, we define the "Too Many Updates" rule as a verification process that examines the number of SQL and RPC updates executed by a command function or method within your application. This rule sets a default threshold of five updates in our &lt;code&gt;default.yml&lt;/code&gt; file. Any function or method that exceeds this threshold triggers the "Too Many Updates" finding to appear in the runtime analysis results. &lt;/p&gt;

&lt;p&gt;In technical terms, this finding corresponds to &lt;a href="https://cwe.mitre.org/data/definitions/1048.html"&gt;CWE-1048&lt;/a&gt;, which refers to an “invokable control element with a large number of outward calls” [sic]. For simplicity, we'll refer to it as "Too Many Updates" throughout this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying the rule
&lt;/h2&gt;

&lt;p&gt;To illustrate the concept, let's consider a real-world example using a Spring Pet Clinic application implemented with Java and the Spring framework. This application allows us to manage owners, pets, and visits for a veterinary clinic. Imagine we have created an owner, and a pet, a bird we have given the name of Jimmy, and added a recent visit to the veterinarian. Now, let's take a closer look at the code and explore the consequences of the "Too Many Updates" finding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting custom overrides
&lt;/h3&gt;

&lt;p&gt;Before diving into the code, let's first understand how to customize the default threshold for the "Too Many Updates" rule. By creating an &lt;code&gt;appmap-scanner.yml&lt;/code&gt; file, and running the command, you can override the default settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx @appland/scanner &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--appmap-dir&lt;/span&gt; tmp/appmap &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--config&lt;/span&gt; appmap-scanner.yml &lt;span class="se"&gt;\&lt;/span&gt;
    ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the example provided, the warning limit is set to one for demonstration purposes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;authzBeforeAuthn&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http500&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;illegalPackageDependency&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;callerPackages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;equal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actionpack&lt;/span&gt;
      &lt;span class="na"&gt;calleePackage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;equal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app/controllers&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;insecureCompare&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;missingAuthentication&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;missingContentType&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nPlusOneQuery&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secretInLog&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;slowFunctionCall&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;timeAllowed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;
      &lt;span class="na"&gt;functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Controller#create$&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;slowHttpServerRequest&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;timeAllowed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;slowQuery&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;timeAllowed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tooManyJoins&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tooManyUpdates&lt;/span&gt;
        &lt;span class="s"&gt;properties&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;warningLimit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unbatchedMaterializedQuery&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;updateInGetRequest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;However, in practical scenarios, it's recommended to set a more appropriate threshold based on your application's requirements. Now that we can control our threshold let's jump over and view our findings.&lt;/p&gt;
&lt;h3&gt;
  
  
  Analyzing findings
&lt;/h3&gt;

&lt;p&gt;To analyze the findings, we'll use AppMap to navigate to the runtime analysis section. The findings table provides a comprehensive overview of all the identified issues. &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%2Fdm4f0i5f280cll0j5wo3.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%2Fdm4f0i5f280cll0j5wo3.png" alt="Analyzing Findings 1" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also group the findings by project, date, or category to gain better visibility into your application's maintainability.&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%2Fnb3t9ow7oy8w675w1zip.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%2Fnb3t9ow7oy8w675w1zip.png" alt="Analyzing Findings 2" width="477" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examining Example 1&lt;/p&gt;

&lt;p&gt;Open the findings report for the "Too Many Updates" finding to understand its causes and implications. In this example, the command performs 47 SQL or RPC updates, as indicated in the event summary.&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%2Fn8g910n9tr9kn91i0lqc.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%2Fn8g910n9tr9kn91i0lqc.png" alt="Findings Report Example 1" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we examine the map, we can observe a sequence diagram representing the execution flow. The presence of this finding suggests potential poor coding practices or architectural flaws in the application.&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%2F5hmxhuqaaayotqd0tqqg.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%2F5hmxhuqaaayotqd0tqqg.png" alt="Example 1 Sequence Diagram" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It highlights the need to consolidate multiple calls into a more efficient and maintainable structure. In this particular application, this is the result of database migrations being performed during the setup phase for development.&lt;/p&gt;

&lt;p&gt;Examining Example 2&lt;/p&gt;

&lt;p&gt;Now, let's explore another example to compare and contrast the findings. In this case, the threshold is set to two, and we examine the sequence diagram for the corresponding map finding an action that performs to “updates” in the same function call.&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%2Fhpdxpit47ca7ab1rp6xp.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%2Fhpdxpit47ca7ab1rp6xp.png" alt="Example 2 Sequence Diagram" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This specific scenario involves adding a pet to an owner. We can observe that two updates are performed: one to &lt;code&gt;INSERT&lt;/code&gt; the pet's information…&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;pets&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;birth_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;`
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;…and another to associate the pet with its owner.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;pets&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;owner&lt;/span&gt; &lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="o"&gt;=?&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Unlike the previous example, this finding emphasizes a design choice rather than inherent flaws in the application's architecture. It prompts us to evaluate if these two calls can be consolidated into a single call for improved efficiency and simplicity.&lt;/p&gt;
&lt;h3&gt;
  
  
  Selecting a strategy
&lt;/h3&gt;

&lt;p&gt;To address the "Too Many Updates" finding, we have several mitigation strategies at our disposal. &lt;/p&gt;

&lt;p&gt;The first and simplest approach is refactoring the code to consolidate multiple updates into a single call. Often we find that “Too Many Updates” isn’t the result of some large flaw in the design of our application, but rather the result of poor implementation of coding standards and common best practices. &lt;/p&gt;

&lt;p&gt;By reviewing the code and analyzing the sequence diagrams, we can identify opportunities to optimize the number of updates performed. Additionally, if we do find a larger issue at play we can consider architectural changes. Such as reevaluating the structure of services and abstractions, to ensure a more streamlined approach. &lt;/p&gt;

&lt;p&gt;Alternatively, if these issues uncover a security risk in our application, we can employ the use of rate limiting to ensure our application remains performant and secure. These mitigation strategies enhance maintainability, improve code readability, and reduce potential security risks.&lt;/p&gt;

&lt;p&gt;Watch the video:&lt;/p&gt;

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

&lt;p&gt;In this article, we explored the "Too Many Updates" maintenance rule and its impact on software engineering practices. &lt;/p&gt;

&lt;p&gt;By understanding the causes, implications, and mitigation strategies, you can effectively optimize your code and ensure a more efficient and maintainable application. &lt;/p&gt;

&lt;p&gt;Remember to review your findings, analyze sequence diagrams, and implement the appropriate refactoring techniques and architectural changes. By doing so, you'll enhance the overall quality and performance of your software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;br&gt;
📸 Cover Photo by &lt;a href="https://unsplash.com/@karlp?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Karl Pawlowicz&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/QUHuwyNgSA0?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⬇️ Download AppMap for VSCode and JetBrains: &lt;a href="https://appmap.io/download"&gt;https://appmap.io/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⭐ Star AppMap on GitHub: &lt;a href="https://github.com/getappmap"&gt;https://github.com/getappmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🐦 Follow on Twitter: &lt;a href="https://twitter.com/getappmap"&gt;https://twitter.com/getappmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 Join AppMap Slack: &lt;a href="https://appmap.io/slack"&gt;https://appmap.io/slack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ℹ️ Read the AppMap docs: &lt;a href="https://appmap.io/docs"&gt;https://appmap.io/docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📺 Watch AppMap Tutorials: &lt;a href="https://www.youtube.com/@appmap"&gt;https://www.youtube.com/@appmap&lt;/a&gt;&lt;/p&gt;

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


&lt;div class="ltag__user ltag__user__id__1045236"&gt;
    &lt;a href="/ghamelin" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F1045236%2Fed6cdfef-5c3f-4fdc-aff4-e5b40aadaf05.jpeg" alt="ghamelin image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/ghamelin"&gt;Garrett Hamelin&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/ghamelin"&gt;I love technology and everything about it. I'm a software engineer who enjoys helping others succeed and building communities of like minded people. &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>programming</category>
      <category>java</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to streamline and focus your sequence diagrams</title>
      <dc:creator>Garrett Hamelin</dc:creator>
      <pubDate>Wed, 28 Jun 2023 19:38:01 +0000</pubDate>
      <link>https://dev.to/appmap/how-to-streamline-and-focus-your-sequence-diagrams-3p7o</link>
      <guid>https://dev.to/appmap/how-to-streamline-and-focus-your-sequence-diagrams-3p7o</guid>
      <description>&lt;p&gt;&lt;strong&gt;AppMap’s new feature gives developers greater control over their sequence diagrams to enhance code reviews.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The value of sequence diagrams, especially for code reviews, &lt;a href="https://dev.to/appmap/quickly-learn-how-new-to-you-code-works-using-sequence-diagrams-h9g"&gt;is growing&lt;/a&gt;. And AppMap is at the cutting edge, creating new tools and capabilities for developers to generate and use sequence diagrams for designing and improving code quality from writing to reviewing. In this article, I’ll share a new filtering feature of our sequence diagram tool in AppMap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taming the complexity of sequence diagrams
&lt;/h3&gt;

&lt;p&gt;As software projects grow in size and complexity, so do the sequence diagrams generated from them that represent their inner workings. These diagrams often become extensive and overwhelming, making it challenging to decipher the flow of interactions and identify critical components. The AppMap user community has requested a way to declutter their &lt;a href="https://dev.to/appmap/automatically-generate-interactive-sequence-diagrams-of-your-java-codes-runtime-behavior-2jg0"&gt;automatically-generated sequence diagrams&lt;/a&gt; in order to focus on the essential elements of their application. &lt;/p&gt;

&lt;p&gt;We heard you, and we’re excited to share this new feature release. Read on for the details, and watch this walkthrough video to see it in action.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Advanced filtering for unparalleled control
&lt;/h3&gt;

&lt;p&gt;With our latest release, we added an enhanced filtering system that empowers developers to take control of their sequence diagrams by eliminating unnecessary noise and tailoring your diagrams to display only the information that matters most to you and your team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 key functionalities&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Live filtering: Instantly reduce complexity by hiding specific components, such as external code or framework-related elements. With just a few clicks, you can create a clean, focused view of your sequence diagram.&lt;/li&gt;
&lt;li&gt;Customizable views: Once you have refined your diagram to your liking, you can save that view as a filter. This means you can apply the filter to future app maps, whether you want it as a default setting for all diagrams or selectively choose where to apply it.&lt;/li&gt;
&lt;li&gt;Seamless switching: Switching between different views is effortless. Just select the desired filter, and the diagram will dynamically update to display your preferred elements. No need to rebuild or navigate complex menus.&lt;/li&gt;
&lt;/ol&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%2F46hgvhvz31qaahebya3b.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%2F46hgvhvz31qaahebya3b.png" alt="Filtering Sequence Diagrams" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits and advantages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AppMap's enhanced filtering feature goes beyond simplifying your sequence diagrams.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Persistence: Your custom filter views persist as long as the diagram remains open. This allows you to revisit and analyze your diagrams without losing your customized settings. If a diagram has been closed, getting that view back is as simple as reapplying the filter. If you find yourself applying the same filter to a majority of your sequence diagrams, set a previously saved filter as the default, providing a seamless experience across any sequence diagram you choose to open or share. Changing or setting a default view becomes as simple as clicking a button. &lt;/li&gt;
&lt;li&gt;Intuitive interface: Our user-friendly interface ensures that applying filters and customizing your view is a breeze. With our configure-as-you-go model, developers spend less time configuring and more time gaining insights from their diagrams.&lt;/li&gt;
&lt;li&gt;Increased efficiency: By decluttering your sequence diagrams and focusing on the relevant elements, you can make quick decisions on things that matter most, improving your code analysis efficiency and gaining a deeper understanding of your application's behavior on whatever scale you choose to view.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Getting Started + community
&lt;/h3&gt;

&lt;p&gt;Sequence diagrams are particularly useful for designing and testing software systems that involve multiple components, asynchronous events, or complex control flows. Learn more about the common use cases for sequence diagrams and how to interpret them &lt;a href="https://dev.to/appmap/quickly-learn-how-new-to-you-code-works-using-sequence-diagrams-h9g"&gt;in this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To try out our new filtering feature, &lt;a href="https://appmap.io/download"&gt;download AppMap&lt;/a&gt; into your favorite IDE and use our &lt;a href="https://appmap.io/docs/appmap-overview.html"&gt;handy docs&lt;/a&gt; to get started. We hope you enjoy exploring the possibilities, experimenting with different views, and revolutionizing how you analyze and understand your code!&lt;/p&gt;

&lt;p&gt;To chat with us and other users about it and get your questions answered, &lt;a href="https://appmap.io/community"&gt;join our community&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@lucabravo?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Luca Bravo&lt;/a&gt; on &lt;a href="href="&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;br&gt;
 &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__1045236"&gt;
    &lt;a href="/ghamelin" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F1045236%2Fed6cdfef-5c3f-4fdc-aff4-e5b40aadaf05.jpeg" alt="ghamelin image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/ghamelin"&gt;Garrett Hamelin&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/ghamelin"&gt;I love technology and everything about it. I'm a software engineer who enjoys helping others succeed and building communities of like minded people. &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>news</category>
      <category>vscode</category>
    </item>
  </channel>
</rss>
