<?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: Samad Yar Khan</title>
    <description>The latest articles on DEV Community by Samad Yar Khan (@samadyarkhan).</description>
    <link>https://dev.to/samadyarkhan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F655155%2Fb0290217-3772-4bcf-93f6-8c83ccd1aa42.jpeg</url>
      <title>DEV Community: Samad Yar Khan</title>
      <link>https://dev.to/samadyarkhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samadyarkhan"/>
    <language>en</language>
    <item>
      <title>Top 10 Tips to Get Started with Open Source and GSoC</title>
      <dc:creator>Samad Yar Khan</dc:creator>
      <pubDate>Thu, 22 Aug 2024 16:52:30 +0000</pubDate>
      <link>https://dev.to/middleware/top-10-tips-to-get-started-with-open-source-and-gsoc-41na</link>
      <guid>https://dev.to/middleware/top-10-tips-to-get-started-with-open-source-and-gsoc-41na</guid>
      <description>&lt;p&gt;During my sophomore year, I was applying for internships daily but had no luck. Then, I read a blog that recommended contributing to open source to gain real-world experience and mentioned opportunities like Google Summer of Code (GSoC), the MLH Fellowship, and the Linux Foundation Mentorship. Intrigued, I decided to dive in.&lt;/p&gt;

&lt;p&gt;However, I quickly felt overwhelmed by the vast number of projects with complex codebases. My initial contributions were minor UI fixes, and I didn't get selected for GSoC that year.&lt;/p&gt;

&lt;p&gt;After a break, I returned with a better approach and eventually secured a spot in GSoC the next year.&lt;/p&gt;

&lt;p&gt;Whether you’re aiming for GSoC or want to contribute, here are my top 10 tips for starting in open source and preparing for GSoC.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Choose the Right Organization&lt;/li&gt;
&lt;li&gt;Become a User First&lt;/li&gt;
&lt;li&gt;Start Small: Pick a Tiny Functionality&lt;/li&gt;
&lt;li&gt;Tackle Open Issues&lt;/li&gt;
&lt;li&gt;Communicate and Ask Questions&lt;/li&gt;
&lt;li&gt;Focus on Consistency, Not Quantity&lt;/li&gt;
&lt;li&gt;Learn to Navigate Large Codebases&lt;/li&gt;
&lt;li&gt;Don’t Overlook Documentation and Testing&lt;/li&gt;
&lt;li&gt;Sharpen Your Git Skills&lt;/li&gt;
&lt;li&gt;Read the Code&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  1. Choose the Right Organization
&lt;/h3&gt;

&lt;p&gt;Begin by browsing through various open-source organizations. Focus on projects that align with your skills and interests. For example, if you’re into web development, look for organizations that work on web-based projects similarly, if you’re proficient in languages like Java, Kotlin, or Python, target projects that make extensive use of those languages.&lt;/p&gt;

&lt;p&gt;One way to find these projects is by exploring &lt;a href="https://summerofcode.withgoogle.com/archive/2023/organizations" rel="noopener noreferrer"&gt;past GSoC organizations&lt;/a&gt; and filtering them based on your area of interest.&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%2Fmv6d9jcmbme65fr0fh6g.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%2Fmv6d9jcmbme65fr0fh6g.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also use &lt;a href="https://www.gsocorganizations.dev/" rel="noopener noreferrer"&gt;this website&lt;/a&gt; to view trends of past projects and filter them by the languages used in those projects.&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%2Fr8lhzwo5q3imeh4shv31.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%2Fr8lhzwo5q3imeh4shv31.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure you’re genuinely interested in the project and that it solves a problem you care about. Aligning your interests, skills, and the organization’s needs will make the contribution process much smoother.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Become a User First
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcng3MmR5bTNiNm5kY3kzaTByMHkxNjUyd3hjem82ajUwbmJmc2h3cyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2R06FEpVRk6IroNq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcng3MmR5bTNiNm5kY3kzaTByMHkxNjUyd3hjem82ajUwbmJmc2h3cyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2R06FEpVRk6IroNq/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open-source projects often have large and complex codebases, which can feel overwhelming at first. A great way to familiarize yourself with a project is by becoming a user. Build the project locally, explore its features, and use it like any other software. This hands-on experience will help you understand its functionality and spot areas for improvement.&lt;/p&gt;

&lt;p&gt;For instance, before contributing to organizations like Joplin, Rocket.Chat, or CircuitVerse, I spent over a week experimenting with their projects. This not only helped me understand the codebase but also gave me ideas on where I could contribute.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Start Small: Pick a Tiny Functionality
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylqcig6nvk64xv1cauux.gif" 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%2Fylqcig6nvk64xv1cauux.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before diving into big features or fixing complex issues, start small. Choose a minor feature that interests you—like tweaking logic in a login screen or updating a button’s behaviour—and search the codebase for relevant keywords. Make small changes and see how they affect the project. In short, hack it out! This process will help you get comfortable with the code while boosting your confidence.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Tackle Open Issues
&lt;/h3&gt;

&lt;p&gt;Open issues are a great starting point but can be intimidating at first. A helpful strategy is to look for issues tagged as &lt;code&gt;good-first-issue&lt;/code&gt;. &lt;a href="https://github.com/middlewarehq/middleware/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22" rel="noopener noreferrer"&gt;Example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjq4tw3e6z9n1u2nqtrfb.gif" 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%2Fjq4tw3e6z9n1u2nqtrfb.gif" alt="Good First Issue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Websites like &lt;a href="https://goodfirstissue.dev/" rel="noopener noreferrer"&gt;Good First Issue&lt;/a&gt; and &lt;a href="https://goodfirstissues.com/" rel="noopener noreferrer"&gt;Good First Issues&lt;/a&gt; make it easier to find beginner-friendly issues.&lt;/p&gt;

&lt;p&gt;A useful trick is to reverse-engineer solved issues. Start by reviewing closed issues similar to the one you’re interested in. Understand how they were resolved, then apply that knowledge to your solution. This approach not only helps you solve current issues but also provides insights into the project’s problem-solving patterns.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Communicate and Ask Questions
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExOWZodmhxYTFzc2dqc2p3ZGM2dTRvdG80cWk1ejdlaTRvdHIzZDlvcCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o7btZ1Gm7ZL25pLMs/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExOWZodmhxYTFzc2dqc2p3ZGM2dTRvdG80cWk1ejdlaTRvdHIzZDlvcCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o7btZ1Gm7ZL25pLMs/giphy.gif" alt="Ask Questions"&gt;&lt;/a&gt;&lt;br&gt;
One of my first open-source contributions to &lt;a href="https://github.com/RocketChat/Rocket.Chat" rel="noopener noreferrer"&gt;Rocket.Chat&lt;/a&gt; involved fixing the login screen. I spent a week working on it and opened a pull request (PR). Moments later, I found out that the internal team was already revamping the entire login screen, so my PR couldn’t be merged. All that effort could have been saved if I had first communicated with the maintainers.&lt;/p&gt;

&lt;p&gt;Open-source communities are generally welcoming and supportive. Don’t hesitate to ask questions if you’re stuck or need guidance. Whether it’s understanding the project’s structure, finding relevant files, or figuring out best practices, reach out to the community. Engaging in discussions will also help you build relationships with other contributors and maintainers. Communicating your approach before diving in can save you from unnecessary rework.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;


&lt;h3&gt;
  
  
  6. Focus on Consistency, Not Quantity
&lt;/h3&gt;

&lt;p&gt;Contributing to open source is a marathon, not a sprint. It’s better to be consistent with small contributions than to aim for big changes that might be hard to sustain. As you get more comfortable, you can take on bigger tasks.&lt;/p&gt;

&lt;p&gt;For example, one of my first contributions was adding a small brand logo component to Rocket.Chat: &lt;a href="https://github.com/RocketChat/RC4Community/pull/46" rel="noopener noreferrer"&gt;Link to PR&lt;/a&gt;. A few months later, I worked on adding a &lt;a href="https://github.com/RocketChat/RC4Community/pull/91" rel="noopener noreferrer"&gt;GitHub Component Kit&lt;/a&gt;, which was a much more complex task. During this period, I focused on learning Next.js and improving my code quality.&lt;/p&gt;

&lt;p&gt;Persistence is key—making your first meaningful contribution might take a few weeks, but that’s where the real growth happens.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;


&lt;h3&gt;
  
  
  7. Learn to Navigate Large Codebases
&lt;/h3&gt;

&lt;p&gt;As you progress, you’ll need to get comfortable navigating large codebases. Tools like &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;ripgrep&lt;/code&gt;, or your IDE’s search function are invaluable for locating specific functions, variables, or files.&lt;/p&gt;

&lt;p&gt;If you’re looking to fix something in the UI, search for the keywords visible on the screen.&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%2F18oxbnbivz6djfxx1ant.gif" 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%2F18oxbnbivz6djfxx1ant.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your focus is on data-related issues, examine the network calls happening during the loading process to figure out which call corresponds to which component.&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%2Fr5e88x7vv524hi39ok8d.gif" 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%2Fr5e88x7vv524hi39ok8d.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, use documentation, GitHub Wikis, and architecture diagrams (if available) to understand how different components interact.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;


&lt;h3&gt;
  
  
  8. Don’t Overlook Documentation and Testing
&lt;/h3&gt;

&lt;p&gt;Many new contributors skip over documentation and testing, but these are areas where help is often needed. Improving documentation, creating tutorials, or adding test cases are valuable contributions.&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%2Fhor3w9snghmlfc7vdzp4.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%2Fhor3w9snghmlfc7vdzp4.png" alt="GitHub App Wiki"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Writing test cases helps you understand the project’s core logic while documenting code deepens your understanding and helps others.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;


&lt;h3&gt;
  
  
  9. Sharpen Your Git Skills
&lt;/h3&gt;

&lt;p&gt;Version control is at the heart of open-source development. Get comfortable with Git commands and workflows, including branching, pull requests, rebasing, and resolving merge conflicts.&lt;/p&gt;

&lt;p&gt;Git isn’t always as straightforward as it seems, and you’ll likely encounter tricky situations like merge conflicts or rebasing issues. Learning how to navigate these problems is essential. You can start with this &lt;a href="https://github.com/git-guides" rel="noopener noreferrer"&gt;Git Guide&lt;/a&gt; or find something more beginner-friendly.&lt;/p&gt;

&lt;p&gt;Projects often have specific contribution guidelines, so, be sure to follow them and keep your commit history clean.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;


&lt;h3&gt;
  
  
  10. Read the Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY25hNnJ0ZjV0bmQ0ang0dXViaDlpdmYwN2dsNXlmaDAyYzAzc3ZybCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZVik7pBtu9dNS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY25hNnJ0ZjV0bmQ0ang0dXViaDlpdmYwN2dsNXlmaDAyYzAzc3ZybCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZVik7pBtu9dNS/giphy.gif" alt="Reading Code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the most underrated skills in open source is the ability to dive into a codebase and start contributing, even if documentation is lacking. While documentation is helpful, it’s often outdated or incomplete in many open-source projects.&lt;/p&gt;

&lt;p&gt;When I worked on adding a PR review feature during my GSoC period, I needed to integrate a code editor block into the component kit. This required changes across three different codebases, none of which were documented. The only way forward was to read a lot of code and commits, piecing together a solution.&lt;/p&gt;

&lt;p&gt;As a newcomer, focus on reading as much code as possible and try to map out how different pieces connect to features you see on the screen.&lt;/p&gt;

&lt;p&gt;Back to Table of Contents&lt;/p&gt;


&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Your first few contributions might be slow, and that’s perfectly fine. Getting comfortable with a new codebase, understanding the project’s culture, and making meaningful contributions takes time. Enjoy the process and celebrate the small wins. The satisfaction of seeing your code accepted into a project used by thousands (or even millions) of people makes it all worthwhile.&lt;/p&gt;

&lt;p&gt;By following these tips and being patient with yourself, you’ll find that contributing to open source is not just a way to level up your skills—it’s also an opportunity to collaborate with like-minded people and create something impactful. Good luck on your open-source journey and in your pursuit of GSoC!&lt;/p&gt;

&lt;p&gt;Feel free to checkout open issues in &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;Middleware OpenSource&lt;/a&gt;👇🏻&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/middlewarehq" rel="noopener noreferrer"&gt;
        middlewarehq
      &lt;/a&gt; / &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;
        middleware
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ✨ Open-source DORA metrics platform for engineering teams ✨
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a href="https://www.middlewarehq.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmiddlewarehq%2Fmiddleware%2Fraw%2Fmain%2Fmedia_files%2Flogo.png" alt="Middleware Logo" width="300px"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Open-source engineering management that unlocks developer potential&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://github.com/middlewarehq/middleware/actions/workflows/build.yml" rel="noopener noreferrer"&gt;&lt;img alt="continuous integration" src="https://camo.githubusercontent.com/d72013fe354cb76bdb62fae188d011c4d1bce7723189bacad6cbde6387cf52e6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6964646c657761726568712f6d6964646c65776172652f6275696c642e796d6c3f6272616e63683d6d61696e266c6162656c3d6275696c64267374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;a href="https://github.com/middlewarehq/middleware/graphs/commit-activity" rel="noopener noreferrer"&gt;&lt;img alt="Commit activity per month" src="https://camo.githubusercontent.com/b694441288287fd6f4c8750f3887fcc6853aef9bfc84ee8a0e1e490a7633639a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f6d2f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;a href="https://github.com/middlewarehq/middleware/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img alt="contributors" src="https://camo.githubusercontent.com/15f7e201a0b0e240425157b1a7251f24a91dcd6b6bbec76af4ad66efda00eeba/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732d616e6f6e2f6d6964646c657761726568712f6d6964646c65776172653f636f6c6f723d79656c6c6f77267374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;a href="https://opensource.org/licenses/Apache-2.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44fae73fb8fb80dc9f5673dc4e1d0e57b1ac81da1166a70c8a5ce52bb39ed67f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f617061636865253230322e302d707572706c652e7376673f7374796c653d666f722d7468652d6261646765266c6162656c3d6c6963656e7365" alt="license"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/eab8dfd78113b2679d98f9f33a66e3a157276c68cc4cf3541fa1287f4dddb379/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765"&gt;&lt;img src="https://camo.githubusercontent.com/eab8dfd78113b2679d98f9f33a66e3a157276c68cc4cf3541fa1287f4dddb379/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765" alt="Stars"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mhq.link/oss-community" rel="nofollow noopener noreferrer"&gt;Join our Open Source Community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/middlewarehq/middleware/blob/main/media_files/banner.gif"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmiddlewarehq%2Fmiddleware%2Fraw%2Fmain%2Fmedia_files%2Fbanner.gif" alt="Middleware Opensource"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Introduction&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt; is an open-source tool designed to help engineering leaders measure and analyze the effectiveness of their teams using the &lt;a href="https://dora.dev" rel="nofollow noopener noreferrer"&gt;DORA metrics&lt;/a&gt;. The DORA metrics are a set of &lt;a href="https://dora.dev/guides/dora-metrics-four-keys/" rel="nofollow noopener noreferrer"&gt;four key values&lt;/a&gt; that provide insights into software delivery performance and operational efficiency.&lt;/p&gt;

&lt;p&gt;They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Frequency&lt;/strong&gt;: The frequency of code deployments to production or an operational environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Time for Changes&lt;/strong&gt;: The time it takes for a commit to make it into production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mean Time to Restore&lt;/strong&gt;: The time it takes to restore service after an incident or failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change Failure Rate&lt;/strong&gt;: The percentage of deployments that result in failures or require remediation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/middlewarehq/middleware#introduction" rel="noopener noreferrer"&gt;Middleware - Open Source&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/middlewarehq/middleware#-quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-installing-middleware" rel="noopener noreferrer"&gt;Installing Middleware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-troubleshooting" rel="noopener noreferrer"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/middlewarehq/middleware#-developer-setup" rel="noopener noreferrer"&gt;Developer Setup&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-using-gitpod" rel="noopener noreferrer"&gt;Using Gitpod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-using-docker" rel="noopener noreferrer"&gt;Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-manual-setup" rel="noopener noreferrer"&gt;Manual Setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-how-we-calculate-dora-metrics" rel="noopener noreferrer"&gt;How we Calculate DORA&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-contributing-guidelines" rel="noopener noreferrer"&gt;Contributing guidelines&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;…&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>programming</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building a Scalable Notifications and Alerting System 🔥🚀</title>
      <dc:creator>Samad Yar Khan</dc:creator>
      <pubDate>Fri, 09 Aug 2024 13:44:09 +0000</pubDate>
      <link>https://dev.to/middleware/building-a-scalable-notifications-and-alerting-system-kon</link>
      <guid>https://dev.to/middleware/building-a-scalable-notifications-and-alerting-system-kon</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;The Idea&lt;/li&gt;
&lt;li&gt;Application Flow&lt;/li&gt;
&lt;li&gt;Assumptions&lt;/li&gt;
&lt;li&gt;Low Level Design&lt;/li&gt;
&lt;li&gt;High Level Design&lt;/li&gt;
&lt;li&gt;Points of Failure&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article explores the development of a Rule-Based alerting and notification system at &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;Middleware&lt;/a&gt;. The system, known as the Playbook, aims to notify customers when certain metrics cross predefined thresholds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea💡
&lt;/h2&gt;

&lt;p&gt;One of my first tasks after joining &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;Middleware&lt;/a&gt; as a full time software engineer was to build something known as the Playbook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExODJsYjdteXQxamVxZnJ3OGdkZjRlMHZvdjNjYmZ1cXFkcHl1cHQzaiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/eImrJKnOmuBDmqXNUj/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExODJsYjdteXQxamVxZnJ3OGdkZjRlMHZvdjNjYmZ1cXFkcHl1cHQzaiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/eImrJKnOmuBDmqXNUj/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Playbook serves as a Rule-Based alerting system, allowing Engineering managers to receive notifications when specific metrics exceed set thresholds. For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Send an email if developers spend more than 50% of their time on bug fixes in the past week.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Send a Slack message if the team’s average PR Rework Time exceeds 6 hours over the last month.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Application Flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Setting Up Rules and Cadence&lt;/strong&gt;: Users define alerting rules for their teams and select the time range for rule checks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Breach Processing&lt;/strong&gt;: The system reads rules from the database, validates metrics against these rules, and generates notifications for breaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dispatching Notifications&lt;/strong&gt;: Notifications are sent to users based on their set time zones.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Entities like Users and Teams exist.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services can provide metric values for Users or Teams within specified time ranges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A notification dispatcher can send notifications via Slack/Email.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One notification is sent per breach.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Low Level Design
&lt;/h2&gt;

&lt;p&gt;The system employs various models, including Playbook, Playbook Rules, Playbook Rule Breaches, and Notifications. These models handle rule creation, breach generation, and notification dispatching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functionalities:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Playbook Core:&lt;/strong&gt; Create a playbook as an aggregation of Rules. Each rule has some setting data and cadence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Breach Processor:&lt;/strong&gt; Identify breaches based on the rules set by the user and the rule cadence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notification Processor:&lt;/strong&gt; Create Notifications based on the breaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notification Dispatcher:&lt;/strong&gt; Sends Notifications via different channels.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Models:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Playbook and Playbook Rules&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Playbook are set by the manager for a team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each Playbook has a set of Rules for each metric with set threshold.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Playbook&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;team_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;date_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;date_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PlaybookRule&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="n"&gt;hashes&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PlaybookRule&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;rule_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PlaybookRuleType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ENUM&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;rule_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;alert_cadence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PlaybookRuleAlertCadence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ENUM&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;users_to_notify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;is_active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PlaybookRuleType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;CYCLE_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CYCLE_TIME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;INCIDENT_COUNT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INCIDENT_COUNT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


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

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Alert Cadence refer to the frequency at which a user would like to receive these notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Daily Cadence: Breaches are calculated daily and we send notification every day according to user time zone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Weekly Cadence: Breaches are calculated based on weekly data, and notifications are sent every Monday.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two Weeks Cadence: Breaches are calculated over the past two weeks’ data, and notifications are sent every second Monday.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monthly Cadence: Breaches are calculated over the monthly average, and notifications are sent on the 1st of each month.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AlertCadence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;DAILY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DAILY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;WEEKLY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WEEKLY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;TWO_WEEKS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TWO_WEEKS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;MONTHLY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MONTHLY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Playbook Breaches:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Triggering Breaches&lt;/strong&gt;: Whenever a metric exceeds or falls below the set threshold, a PlaybookBreach is generated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Linkage&lt;/strong&gt;: Each PlaybookBreach is associated with a playbook and a rule type, providing context for the breach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule Data Inclusion&lt;/strong&gt;: To accommodate potential rule changes later, each breach includes the rule data as it was at the time of generation. This ensures historical accuracy and consistency despite future rule modifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PlaybookRuleBreach&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;playbook&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rule_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rule_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;team_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;alert_cadence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PlaybookRuleAlertCadence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ENUM&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;metric_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Notifications:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Breach Notification&lt;/strong&gt;: Upon breach creation, a notification can be generated and sent to the user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preventing Duplicate&lt;/strong&gt;s: To avoid duplicate notifications, each notification is assigned an idempotency key, ensuring uniqueness in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notification Model Flexibility&lt;/strong&gt;: The notification model is designed to be versatile, accommodating other services beyond the Playbook. As such, each notification can be categorized by type to facilitate organization and handling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;receiver_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;idempotency_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;notification_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;NotificationTypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ENUM&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;due_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;queued_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sent_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date_time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  High Level Design
&lt;/h2&gt;

&lt;p&gt;In this section we will define how to makes this system robust:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ensure breaches are generated reliably at set intervals despite system failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement measures to prevent the generation of duplicate breaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Establish safeguards to avoid sending duplicate notifications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Develop a retry system for notifications in case of bugs or system failures.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Generating and Processing Breaches
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwce3kbovscc1kox8kqk1.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%2Fwce3kbovscc1kox8kqk1.png" alt="High level design for alerting generation"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  CRONS
&lt;/h4&gt;

&lt;p&gt;We must check and process our playbook rules based on the cadence set by the user.&lt;/p&gt;

&lt;p&gt;For this purpose we can simplify the system to use a CRON that runs Daily.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Process rules with a daily cadence each time the CRON job executes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check if the current date is the 1st to process rules with a monthly alert cadence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For rules with a weekly alert cadence, process them on Mondays.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle rules with a two-week alert cadence by processing them on the first or third Monday of the month.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Jobs and Workers
&lt;/h4&gt;

&lt;p&gt;Processing all this data inside a single cron process can be a challenge incase one of the rule fails due to incorrect data, unhandled case in code or deleted entities.&lt;/p&gt;

&lt;p&gt;Example: If you have processed a 10 Rules and there is an unhandled case on the 11th Rule, the last generated breaches and notifications are wasted and not stored to the DB. Similarly, once the CRON throws an error, it will need to be manually re-triggered else we will have to wait for the next time it automatically runs.&lt;/p&gt;

&lt;p&gt;To avoid this, we use the producer-consumer model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Treat each Playbook Rule as a single job and enqueue these jobs into a PlaybookRule Queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilise multiple workers to listen to the PlaybookQueue and process one job at a time to generate PlaybookRuleBreach and Notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a job fails, the Queue will receive a 500 status code, we can setup some alerts and this failed job can be re-tried by the Queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using a non-FIFO queue ensures that failed jobs do not block the queue while fixes are being deployed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regarding technology choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The system described uses Amazon SQS and Lambdas for its internal systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While AWS provides built-in functionality for this setup, similar systems can be built using other service providers or custom solutions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Queuing Notifications
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijvm94bzdtp3i93ohbl2.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%2Fijvm94bzdtp3i93ohbl2.png" alt="High Level Design for Notifications System"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the Notification are in the Database, we can run a hourly CRON that checks for any due notifications in the DB and queues them as jobs.&lt;/p&gt;

&lt;p&gt;These notification jobs are handled by the notification dispatcher which decides which channel to use to notify the user and runs any additional logic to manipulate notification message set for a notification type.&lt;/p&gt;
&lt;h2&gt;
  
  
  Points of Failure
&lt;/h2&gt;

&lt;p&gt;As data travels through distributed systems, there are chances of failure. We handled some cases in our design, but each system has its own shortcomings.&lt;/p&gt;
&lt;h3&gt;
  
  
  Handled Cases
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Processing jobs from the PlaybookRuleQueue:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Failed saving operations for breaches are retried by the Queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When saving notifications fails and a retry occurs, ensure no duplicate breaches are generated for the same packet. Breaches remain idempotent based on playbook_id, rule_type, and rule checking interval.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Processing and Saving Notification
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When re-queuing playbook rule jobs, we prevent duplicate notifications from being saved in the DB by using an idempotency key based on breach data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using idempotency key we make sure one notification can be created from one breach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incase a dispatched notifications is failed, it will be retried by the queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Incase a sent notification is re-queued, the worker will check the sent_at key for a notification making sure it is not resent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Shortcomings
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Rule Changes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Incase a user updates a rule after the notification is generated and waiting to be sent, we still send the notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This was a edge case that we did not handle internally simply because of time constraints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This can also be handled by cross-checking the rule data inside the breach used to generate the notification with the rule data in associated playbook and deleting notification and re-queueing a PlaybookRule Job.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Rule-Based Notification System developed at &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;Middleware&lt;/a&gt; has proven to be robust in the past year at our current scale.&lt;/p&gt;

&lt;p&gt;While it may not be the most scalable notifications system out there, I hope this article can get you thinking in the right direction :)&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/middlewarehq" rel="noopener noreferrer"&gt;
        middlewarehq
      &lt;/a&gt; / &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;
        middleware
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ✨ Open-source DORA metrics platform for engineering teams ✨
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a href="https://www.middlewarehq.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmiddlewarehq%2Fmiddleware%2Fraw%2Fmain%2Fmedia_files%2Flogo.png" alt="Middleware Logo" width="300px"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Open-source engineering management that unlocks developer potential&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;
&lt;a href="https://github.com/middlewarehq/middleware/actions/workflows/build.yml" rel="noopener noreferrer"&gt;&lt;img alt="continuous integration" src="https://camo.githubusercontent.com/d72013fe354cb76bdb62fae188d011c4d1bce7723189bacad6cbde6387cf52e6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6964646c657761726568712f6d6964646c65776172652f6275696c642e796d6c3f6272616e63683d6d61696e266c6162656c3d6275696c64267374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;a href="https://github.com/middlewarehq/middleware/graphs/commit-activity" rel="noopener noreferrer"&gt;&lt;img alt="Commit activity per month" src="https://camo.githubusercontent.com/b694441288287fd6f4c8750f3887fcc6853aef9bfc84ee8a0e1e490a7633639a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f6d2f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;a href="https://github.com/middlewarehq/middleware/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img alt="contributors" src="https://camo.githubusercontent.com/15f7e201a0b0e240425157b1a7251f24a91dcd6b6bbec76af4ad66efda00eeba/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732d616e6f6e2f6d6964646c657761726568712f6d6964646c65776172653f636f6c6f723d79656c6c6f77267374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;a href="https://opensource.org/licenses/Apache-2.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44fae73fb8fb80dc9f5673dc4e1d0e57b1ac81da1166a70c8a5ce52bb39ed67f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f617061636865253230322e302d707572706c652e7376673f7374796c653d666f722d7468652d6261646765266c6162656c3d6c6963656e7365" alt="license"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/eab8dfd78113b2679d98f9f33a66e3a157276c68cc4cf3541fa1287f4dddb379/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765"&gt;&lt;img src="https://camo.githubusercontent.com/eab8dfd78113b2679d98f9f33a66e3a157276c68cc4cf3541fa1287f4dddb379/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765" alt="Stars"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mhq.link/oss-community" rel="nofollow noopener noreferrer"&gt;Join our Open Source Community&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/middlewarehq/middleware/blob/main/media_files/banner.gif"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmiddlewarehq%2Fmiddleware%2Fraw%2Fmain%2Fmedia_files%2Fbanner.gif" alt="Middleware Opensource"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Introduction&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt; is an open-source tool designed to help engineering leaders measure and analyze the effectiveness of their teams using the &lt;a href="https://dora.dev" rel="nofollow noopener noreferrer"&gt;DORA metrics&lt;/a&gt;. The DORA metrics are a set of &lt;a href="https://dora.dev/guides/dora-metrics-four-keys/" rel="nofollow noopener noreferrer"&gt;four key values&lt;/a&gt; that provide insights into software delivery performance and operational efficiency.&lt;/p&gt;

&lt;p&gt;They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Frequency&lt;/strong&gt;: The frequency of code deployments to production or an operational environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Time for Changes&lt;/strong&gt;: The time it takes for a commit to make it into production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mean Time to Restore&lt;/strong&gt;: The time it takes to restore service after an incident or failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change Failure Rate&lt;/strong&gt;: The percentage of deployments that result in failures or require remediation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/middlewarehq/middleware#introduction" rel="noopener noreferrer"&gt;Middleware - Open Source&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/middlewarehq/middleware#-quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-installing-middleware" rel="noopener noreferrer"&gt;Installing Middleware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-troubleshooting" rel="noopener noreferrer"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/middlewarehq/middleware#-developer-setup" rel="noopener noreferrer"&gt;Developer Setup&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-using-gitpod" rel="noopener noreferrer"&gt;Using Gitpod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-using-docker" rel="noopener noreferrer"&gt;Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-manual-setup" rel="noopener noreferrer"&gt;Manual Setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-how-we-calculate-dora-metrics" rel="noopener noreferrer"&gt;How we Calculate DORA&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-contributing-guidelines" rel="noopener noreferrer"&gt;Contributing guidelines&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;…&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>distributedsystems</category>
      <category>programming</category>
    </item>
    <item>
      <title>LLAMA 3.1 vs GPT4: Which is smarter for analytics?</title>
      <dc:creator>Samad Yar Khan</dc:creator>
      <pubDate>Tue, 30 Jul 2024 11:29:48 +0000</pubDate>
      <link>https://dev.to/middleware/llama-31-vs-gpt4-which-is-smarter-for-analytics-11k0</link>
      <guid>https://dev.to/middleware/llama-31-vs-gpt4-which-is-smarter-for-analytics-11k0</guid>
      <description>&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Background&lt;/li&gt;
&lt;li&gt;Objectives&lt;/li&gt;
&lt;li&gt;
Implementation

&lt;ul&gt;
&lt;li&gt;Data Processing: Middleware to the Rescue&lt;/li&gt;
&lt;li&gt;Model Integration: FireworksAi and OpenAI&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Evaluation and Results: GPT4o Vs LLAMA 3.1

&lt;ul&gt;
&lt;li&gt;Mathematical Accuracy&lt;/li&gt;
&lt;li&gt;Data Analysis&lt;/li&gt;
&lt;li&gt;Actionability&lt;/li&gt;
&lt;li&gt;Summarisation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;li&gt;Future Work&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Middleware is a platform that enables engineering leaders to derive actionable insights from data and improve the processes, making dev teams more efficient. With the fast movements in the field of AI we have been continuously trying to integrate ML models across the product with the goal of deriving actionable insights from the data.&lt;br&gt;
&lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&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%2F14s0u5vc81avrnhg91ef.gif"&gt;&lt;/a&gt;&lt;br&gt;
We took some time and figured that the open source LLAMA or Mistral models we wanted to use were good but GPT4o was more reliable when it came to data centric problems. Hence we decided to move in the more sophisticated direction of building RAG pipelines and using function calling.&lt;/p&gt;

&lt;p&gt;All this changed when we heard that Meta dropped LLAMA 3.1 models. The  70B and 405B models are simply one of the best open-source models out there and compete neck to neck with GPT4o. So we decided to integrate AI powered DORA reports as a part of an experimental effort and see how GPT4 and LLAMA 3.1 perform when it comes to data analysis and reasoning.&lt;/p&gt;
&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;DORA metrics provide critical insights into the performance and reliability of software delivery processes. &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%2Fcwuu16657otq82iadbvp.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%2Fcwuu16657otq82iadbvp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Lead Time for Changes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lead time consists of First Commit to PR Open time, First Response Time, Rework Time, Merge Time, and Merge to Deploy Time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2) Deployment Frequency&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This metric gauges how frequently code changes are deployed to production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3) Mean Time to Recover (MTTR)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MTTR measures how swiftly a team can restore service after a failure occurs in production.&lt;/li&gt;
&lt;li&gt;The team's average incident resolution time is to compute its MTTR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4) Change Failure Rate (CFR)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CFR quantifies the percentage of changes that result in a service impairment or outage in production, aiding in the evaluation of deployment process stability and reliability.&lt;/li&gt;
&lt;li&gt;CFR is computed by linking incidents to deployments within an interval; each deployment may have several or no incidents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn more about dora metrics from &lt;a href="https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance" rel="noopener noreferrer"&gt;here&lt;/a&gt;. By leveraging advanced LLMs, we aim to automate the analysis of these metrics, providing teams with deeper and more actionable insights.&lt;/p&gt;
&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;To integrate LLMs into Middleware for the analysis of DORA metrics.&lt;/li&gt;
&lt;li&gt;To compare the performance of different large language models in terms of: 

&lt;ul&gt;
&lt;li&gt;Mathematical Accuracy: How well can it calculate the DORA score ?&lt;/li&gt;
&lt;li&gt;Data Analysis: Can the LLM analyse the input data and derive correct inferences ? &lt;/li&gt;
&lt;li&gt;Summarising: How well can the model summarise data ?&lt;/li&gt;
&lt;li&gt;Actionability: How well can the models suggest an action-plan based on the input data ?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Data Processing: Middleware to the Rescue
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Middleware syncs all your data from different sources and calculates the DORA Metrics for your teams.&lt;/li&gt;
&lt;li&gt;Checkout &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;middlewarehq/middleware&lt;/a&gt; and setup the dev server using docker. &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%2Fhh9fbtzwfyrw0foetw31.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%2Fhh9fbtzwfyrw0foetw31.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Model Integration: FireworksAi and OpenAI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We integrated OpenAI GPT4o and LLAMA 3.1 (70B and 405B) models.&lt;/li&gt;
&lt;li&gt;The OpenAI models use the official OpenAI API under the hood, while the &lt;a href="http://fireworks.ai/login/?ref=middleware" rel="noopener noreferrer"&gt;Fireworks AI APIs&lt;/a&gt; have been used to integrate the 70B and 405B LLAMA 3.1 Models.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;These AI analytics are powered by the AIAnalyticsService in the analytics server. This service can be extended to use more closed sources models from OpenAI or OpenSource model using &lt;a href="http://fireworks.ai/login/?ref=middleware" rel="noopener noreferrer"&gt;FireworksAi&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fur8sblzc23pof7g5qaqk.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%2Fur8sblzc23pof7g5qaqk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes on the front end introduce components and &lt;a href="https://dev.to/middleware/best-architecture-for-your-next-project-framework-doesnt-matter-29em"&gt;BFF&lt;/a&gt; logic allowing users to enter their token, choose a large language model and generate AI Reports for their DORA Metrics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whenever the user tries to generate AI analysis, the UI makes a POST request to the BFF API:  &lt;code&gt;internal/ai/dora_metrics&lt;/code&gt; with all the preprocessed DORA Metrics and trends data. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This BFF API internally calls multiple analytics APIs with the dora metrics and trends data, which in turn generate the analysis based on the processed data and the curated prompts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the analysis for each individual metric trend is fed again into the LLM for a summarising effort and all the data is sent to the front-end.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More implementation details can be found in &lt;a href="https://github.com/middlewarehq/middleware/pull/493" rel="noopener noreferrer"&gt;this pull request&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Evaluation and Results: GPT4o Vs LLAMA 3.1
&lt;/h2&gt;

&lt;p&gt;We did the DORA AI analysis for July on the following open-source repositories:  &lt;a href="https://github.com/facebook/react" rel="noopener noreferrer"&gt;facebook/react&lt;/a&gt;, &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;middlewarehq/middlware&lt;/a&gt;, &lt;a href="https://github.com/meta-llama/llama3" rel="noopener noreferrer"&gt;meta-llama/llama&lt;/a&gt; and &lt;a href="https://github.com/facebookresearch/dora" rel="noopener noreferrer"&gt;facebookresearch/dora&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mathematical Accuracy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Middleware generated a DORA Performance Score for the team based on this &lt;a href="https://dora.dev/quickcheck/" rel="noopener noreferrer"&gt;guide by dora.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;To test out the computational accuracy of the model we provide it with the four key metrics and prompt the LLM to generate a DORA Score and compare the results with Middleware.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The four keys was a JSON of the format.&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
    "lead_time": 4000,
    "mean_time_to_recovery": 200000,
    "change_failure_rate": 20,
    "weekly_deployment_frequency": 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- The Actual Dora Score for the repositories was around 5. While OpenAi’s GPT4o was able to predict the score to be 4-5 most of the times, LLAMA 3.1 405B a margin away.

_DORA Metrics score: 5/10_
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/saepp6t4su3j86fm1g3j.png)

_GPT 4o with DORA score 5/10_
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9u7nln407p0rhhqkag71.png)

_LLAMA 3.1 with DORA Score 8/10 (incorrect)_
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwpladuhj66ij2s5j1l7.png)


GPT 4o  DORA Score was closer to the actual DORA score than LLAMA 3.1 in 9/10 cases, hence GPT4o was more accurate compared to LLAMA 3.1 in this scenario.

### Data Analysis
- The trend data for the four keys dora metrics, calculated by Middleware, was fed to the LLMs as input along with different experimental prompts to ensure a concrete data analysis.
- The trend data is usually a JSON object with date strings as keys, representing weeks' start dates mapped to the metric data.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "2024-01-01": {
           ...
       },
       "2024-01-08": {
           ...
       }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- *Mapping Data*: Both the models were at par at extracting data from the JSON and inferring the data in the correct manner. Example: Both GPT and LLAMA were able to map the correct data to the input weeks without errors or hallucinations.


     _Deployment Trends Summarised: GPT4o_
     ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ey4jlh2o1nk5xkvg4tt0.png)


     _Deployment Trends Summarised: LLAMA 3.1 405B_
     ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ziiymc6tl0l360uam8hs.png)


- **Extracting Inferences**: Both the models were able to derive solid inferences from data. 
  - LLAMA 3.1 identified week with maximum lead time along with the reason for the high lead time.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/evww5o0tg6bu4m941z6h.png)


  - This inference could be verified by the Middleware Trend Charts.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmu39pip49f0brsbd0ti.png)


  - GPT4o was also able to extract the week with the maximum lead time and the reason too, which was, high first-response time.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74eepbadfzk24z0i5i80.png)


- **Data Presentation**: Data representation has been a hit or miss with LLMs. There are cases where GPT performs better at data presentation but lacks behind LLAMA 3.1 in accuracy and there have been cases like the DORA score where GPT was able to do the math better.
  - LLAMA and GPT were both given the lead time value in seconds. LLAMA was able to round off the data closer to the actual value of 16.99 days while GPT rounded off the data to 17 days 2 hours but presented the data in a  more detailed format.

     _GPT4o_![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dpwmlcscgehi47zlx0c.png)


     _LLAMA 3.1 405B_![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3owjv94wjfrtxetf91a.png)



### Actionability
&amp;lt;img width="100%" style="width:100%" src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExZXFmcmM2cno2c3liN3doeXJ6Z282NmxrZDN0ZGd3c2xta2RwOXp5eCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/jsrfOEfEHkHPFSNlir/giphy.gif"&amp;gt;

- The models were able to output similar actionables for improving teams' efficiency based on all the metrics.
- Example: Both the models identified the reason for high lead-time to be first-response time and suggested the team to use an alerting tool to avoid delayed PR Reviews. The models also suggested better planning to avoid rework where rework was high in a certain week.

_GPT4o_![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq9uaapz50z3dsom7jhd.png)

_LLAMA 3.1 405B_![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gbw7ovecvj3rc6fhykz3.png)


### Summarisation
To test out the summarisation capabilities of the models we asked the model to summarise each metric trend individually and then feed the output results for all the trends back into the LLMs to get a summary or in Internet's slang *DORA TLDR* for the team.

The summarisation capability of large data is similar in both the LLMs.

_LLAMA 3.1 405B_
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ewsg3cgyqp3mikx1pb92.png)

_GPT4o_
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iq6qgz104pacq7nhpyku.png)

## Conclusion
For a long time LLAMA was trying to catch up with GPT in terms of data processing and analytical abilities. Our earlier experimentation with older LLAMA models led us to believe that GPT is way ahead, but the recent LLAMA 3.1 405B model is at par with the GPT4o.

If you value data privacy of your customers and want to try out the open-source LLAMA 3.1 models instead of GPT4, go ahead! There will be negligible difference in performance and you will be able to ensure data privacy if you use self hosted models. Open-Source LLMs have finally started to compete with all the closed-source competitors.

Both LLAMA 3.1 and GPT4o are super capable of deriving inferences from processed data and making Middleware’s DORA metrics more actionable and digestible for engineering leaders, leading to more efficient teams.

## Future Work
This was an experiment to build an AI powered DORA solution and in the future we will be focusing on adding greater support for self hosted or locally running LLMs from Middleware. Enhanced support for AI powered action-plans throughout the product using self hosted LLMs, while ensuring data privacy, will be our goal for the coming months. 

In the mean time you can try out the AI DORA summary feature [here](https://github.com/middlewarehq/middleware/tree/ai-beta).

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/middlewarehq" rel="noopener noreferrer"&gt;
        middlewarehq
      &lt;/a&gt; / &lt;a href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;
        middleware
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ✨ Open-source DORA metrics platform for engineering teams ✨
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a href="https://www.middlewarehq.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmiddlewarehq%2Fmiddleware%2Fraw%2Fmain%2Fmedia_files%2Flogo.png" alt="Middleware Logo" width="300px"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Open-source engineering management that unlocks developer potential&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://github.com/middlewarehq/middleware/actions/workflows/build.yml" rel="noopener noreferrer"&gt;&lt;img alt="continuous integration" src="https://camo.githubusercontent.com/d72013fe354cb76bdb62fae188d011c4d1bce7723189bacad6cbde6387cf52e6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d6964646c657761726568712f6d6964646c65776172652f6275696c642e796d6c3f6272616e63683d6d61696e266c6162656c3d6275696c64267374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;a href="https://github.com/middlewarehq/middleware/graphs/commit-activity" rel="noopener noreferrer"&gt;&lt;img alt="Commit activity per month" src="https://camo.githubusercontent.com/b694441288287fd6f4c8750f3887fcc6853aef9bfc84ee8a0e1e490a7633639a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f6d2f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;a href="https://github.com/middlewarehq/middleware/graphs/contributors" rel="noopener noreferrer"&gt;&lt;img alt="contributors" src="https://camo.githubusercontent.com/15f7e201a0b0e240425157b1a7251f24a91dcd6b6bbec76af4ad66efda00eeba/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6e7472696275746f72732d616e6f6e2f6d6964646c657761726568712f6d6964646c65776172653f636f6c6f723d79656c6c6f77267374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;a href="https://opensource.org/licenses/Apache-2.0" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44fae73fb8fb80dc9f5673dc4e1d0e57b1ac81da1166a70c8a5ce52bb39ed67f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f617061636865253230322e302d707572706c652e7376673f7374796c653d666f722d7468652d6261646765266c6162656c3d6c6963656e7365" alt="license"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/eab8dfd78113b2679d98f9f33a66e3a157276c68cc4cf3541fa1287f4dddb379/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765"&gt;&lt;img src="https://camo.githubusercontent.com/eab8dfd78113b2679d98f9f33a66e3a157276c68cc4cf3541fa1287f4dddb379/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d6964646c657761726568712f6d6964646c65776172653f7374796c653d666f722d7468652d6261646765" alt="Stars"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mhq.link/oss-community" rel="nofollow noopener noreferrer"&gt;Join our Open Source Community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/middlewarehq/middleware/blob/main/media_files/banner.gif"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmiddlewarehq%2Fmiddleware%2Fraw%2Fmain%2Fmedia_files%2Fbanner.gif" alt="Middleware Opensource"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Introduction&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt; is an open-source tool designed to help engineering leaders measure and analyze the effectiveness of their teams using the &lt;a href="https://dora.dev" rel="nofollow noopener noreferrer"&gt;DORA metrics&lt;/a&gt;. The DORA metrics are a set of &lt;a href="https://dora.dev/guides/dora-metrics-four-keys/" rel="nofollow noopener noreferrer"&gt;four key values&lt;/a&gt; that provide insights into software delivery performance and operational efficiency.&lt;/p&gt;

&lt;p&gt;They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Frequency&lt;/strong&gt;: The frequency of code deployments to production or an operational environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Time for Changes&lt;/strong&gt;: The time it takes for a commit to make it into production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mean Time to Restore&lt;/strong&gt;: The time it takes to restore service after an incident or failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change Failure Rate&lt;/strong&gt;: The percentage of deployments that result in failures or require remediation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Table of Contents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/middlewarehq/middleware#introduction" rel="noopener noreferrer"&gt;Middleware - Open Source&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/middlewarehq/middleware#-quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-installing-middleware" rel="noopener noreferrer"&gt;Installing Middleware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-troubleshooting" rel="noopener noreferrer"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/middlewarehq/middleware#-developer-setup" rel="noopener noreferrer"&gt;Developer Setup&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-using-gitpod" rel="noopener noreferrer"&gt;Using Gitpod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-using-docker" rel="noopener noreferrer"&gt;Using Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-manual-setup" rel="noopener noreferrer"&gt;Manual Setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#-how-we-calculate-dora-metrics" rel="noopener noreferrer"&gt;How we Calculate DORA&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-roadmap" rel="noopener noreferrer"&gt;Roadmap&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://github.com/middlewarehq/middleware#%EF%B8%8F-contributing-guidelines" rel="noopener noreferrer"&gt;Contributing guidelines&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;…&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/middlewarehq/middleware" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;

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

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Automate the Boring Stuff: How I Built a Code Generator to Save Hours of Redundant Work🧑‍💻</title>
      <dc:creator>Samad Yar Khan</dc:creator>
      <pubDate>Sun, 16 Jun 2024 14:20:04 +0000</pubDate>
      <link>https://dev.to/samadyarkhan/how-i-automated-all-the-elegant-code-required-to-extend-a-feature-mmn</link>
      <guid>https://dev.to/samadyarkhan/how-i-automated-all-the-elegant-code-required-to-extend-a-feature-mmn</guid>
      <description>&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%2Fryfu3pv9u0z5o21sqpjl.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%2Fryfu3pv9u0z5o21sqpjl.gif" alt="Image description" width="960" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I will explain how I got frustrated with writing redundant code needed to extend a service every time a new requirement was raised, and how I automated this with code generation.&lt;/p&gt;

&lt;p&gt;You can skip to one of the sections:&lt;/p&gt;

&lt;p&gt;0) Backstory / Lore Time 🧙&lt;br&gt;
1) The Redundant Work 🥱&lt;br&gt;
2) Writing a Code Generator 🧑‍💻&lt;br&gt;
3) The Result ⚡&lt;/p&gt;
&lt;h2&gt;
  
  
  Backstory / Lore Time 🧙
&lt;/h2&gt;

&lt;p&gt;A new customer logged in at &lt;a href="https://www.middlewarehq.com/"&gt;Middleware&lt;/a&gt; and they had 100 times the data of our previous ones, causing our data pipelines to choke. We had to ship a hot fix ASAP.&lt;/p&gt;

&lt;p&gt;After mitigation, we discovered most of their data was irrelevant bot-generated content, which we could filter out during data sync. We implemented a hot fix to filter data at ingestion, which worked well.&lt;/p&gt;

&lt;p&gt;Next, I was tasked with adding a new setting to filter bot-generated data without manual coding. While this provided more control over what we sync, it was a boring 🥱, redundant task that required understanding the Setting Service context 📚.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExbnkwYjNjbThkMmlzaWR3bDZkYTAyNWNoYTZuajV3eG13eWhkMzMweSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/F3BeiZNq6VbDwyxzxF/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExbnkwYjNjbThkMmlzaWR3bDZkYTAyNWNoYTZuajV3eG13eWhkMzMweSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/F3BeiZNq6VbDwyxzxF/giphy.gif" width="480" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Redundant Work 🥱
&lt;/h2&gt;

&lt;p&gt;We have a Setting Service in our codebase that handles all the settings in our product. The code follows a great structure; it's easy to breeze through and handles any type of setting needed by the product.&lt;/p&gt;

&lt;p&gt;The whole process of adding a new setting requires any developer to see a previous PR where someone added a new setting, regain context, make code changes across multiple files (spanning from adapters to validators), which all depend on the new setting's schema, and ensure that the APIs are working.&lt;/p&gt;

&lt;p&gt;The code changes are straightforward; they just feel like a lot of manual work with little gain and are heavily dependent on the class schema of the new setting type. It's easily half a day of work for any developer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHh6aHBpdW91bnF0MXV1bnExNTBxY3k0bDg5ZGN3a3F6M3Bvb2ptaSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/9K5E2QOubA2yzoQjLT/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHh6aHBpdW91bnF0MXV1bnExNTBxY3k0bDg5ZGN3a3F6M3Bvb2ptaSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/9K5E2QOubA2yzoQjLT/giphy.gif" width="480" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I got the task to add a setting, I thought to myself: 🤔💡 If some work feels redundant and follows changes based on a set structure, I should try to automate it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing a Code Generator 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExc2doc3k4dzZtcTczaHZmb2czbWQ0azU0ODhldm9kNXpnaTkwa2xxYSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/gVlgj80ZLp9yo/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExc2doc3k4dzZtcTczaHZmb2czbWQ0azU0ODhldm9kNXpnaTkwa2xxYSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/gVlgj80ZLp9yo/giphy.gif" width="500" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had no idea how I could automate code generation based on some rules. I have often heard my friends working in bigger organizations speak about how they have whole services that build out APIs and layouts for them based on certain schemas, so I knew it was possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  Research 📖
&lt;/h3&gt;

&lt;p&gt;I googled if a solution already existed. People have built similar things, but none tied to my use case.&lt;/p&gt;

&lt;p&gt;I used ChatGPT to churn out an easy solution, but none worked. My next idea was to just send all the files to GPT using a script and get updated files, but that had two problems:&lt;/p&gt;

&lt;p&gt;1) LLMs are not reliable enough with code generation.&lt;br&gt;
2) Sharing proprietary code would get me fired 💀.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExdnMxemFjbWljdmw3M3Vqc2U0azlyempyZHp6OTM1cm83eTM0Y3dyNiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xULW8CVCfQn2QytFM4/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExdnMxemFjbWljdmw3M3Vqc2U0azlyempyZHp6OTM1cm83eTM0Y3dyNiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xULW8CVCfQn2QytFM4/giphy.gif" width="350" height="264"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Breaking Down the Problem 🛠️
&lt;/h3&gt;

&lt;p&gt;The next step was to verify if a solution was even possible for our use case, so I did the following:&lt;/p&gt;

&lt;p&gt;1) Gained all the context needed to add a new setting to the codebase.&lt;br&gt;
2) Tracked all the files and specific classes and functions where the changes would go.&lt;br&gt;
3) Mapped the nature of changes needed in each file with the new setting schema.&lt;/p&gt;

&lt;p&gt;So far, the function/variable/class naming was consistent with the setting type name, and the logic for adapters and validators could be coded out and automated based on the primitive data types used in my new setting type schema.&lt;/p&gt;

&lt;p&gt;If I added placeholder comments where new code was to be added and my script could identify which code to add in place of which comment and at the same time move the comment down so it could be used again next time, it would solve the problem.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Solution ⭐
&lt;/h3&gt;

&lt;p&gt;The first challenge was to create pure functions that could generate code based on the new setting name and schema. Generating new enums, classes, and dictionaries was straightforward, but creating handlers, adapters, and validators was more complex and time-consuming. I used GPT and Claude to help develop a generic solution for this.&lt;/p&gt;

&lt;p&gt;The next challenge was locating placeholder comments across files and inserting the generated code while handling Python's indentation issues. This was particularly painful as I had little experience with regex and had to learn it on the go.&lt;/p&gt;

&lt;p&gt;Here is how I managed the code population bit, explained with an example because it was new for me and might be for you as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;enum_pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?P&amp;lt;indent&amp;gt;\s*)# ADD NEW SETTING TYPE ENUM HERE\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enum_pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;indent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;indent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;new_enum_entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;setting_type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; = &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;setting_type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enum_pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_enum_entry&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;enum_pattern&lt;/code&gt;: The regex pattern to find the placeholder comment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;re.search&lt;/code&gt;: Searches for the pattern in the file content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;match.group('indent')&lt;/code&gt;: Captures the indentation level.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;re.sub&lt;/code&gt;: Replaces the placeholder with the new enum entry, preserving the indentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And all this effort paid off ✨&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result ⚡
&lt;/h2&gt;

&lt;p&gt;After hours of struggling to build the code generator script, it paid off 🚀&lt;/p&gt;

&lt;p&gt;I was able to build a script that would prompt the user for the new setting name and the required fields along with their types and make changes across files. All the developers would need to do is add the imports (because they were too messy to handle) and handle any complex data types (which would be rather simple as 90% of the code is generated).&lt;/p&gt;

&lt;p&gt;This is the Pull Request that adds the script to our Middleware Open Source Codebase. I would recommend going through the code if you wish to implement a similar solution for your use case: &lt;a href="https://github.com/middlewarehq/middleware/pull/433"&gt;https://github.com/middlewarehq/middleware/pull/433&lt;/a&gt;&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%2Fryfu3pv9u0z5o21sqpjl.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%2Fryfu3pv9u0z5o21sqpjl.gif" alt="Code Generation Script" width="960" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This brought down the development time of adding a setting from a few hours to less than 10 minutes and, most importantly, helped me and other developers escape the boring work 😎!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for sticking till the end 🤝
&lt;/h2&gt;

&lt;p&gt;If you liked the article please spare some time to star the opensource repositories I maintain:&lt;/p&gt;

&lt;p&gt;⭐ &lt;a href="https://github.com/middlewarehq/middleware"&gt;https://github.com/middlewarehq/middleware&lt;/a&gt;&lt;br&gt;
⭐ &lt;a href="https://github.com/RocketChat/Apps.Github22"&gt;https://github.com/RocketChat/Apps.Github22&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can follow me on socials:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/samad-yar-khan"&gt;GitHub/samad-yar-khan&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/samad-yar-khan/"&gt;LinkedIn/samad-yar-khan&lt;/a&gt;&lt;br&gt;
&lt;a href="https://x.com/samadnotyouryar"&gt;X/samadnotyouryar&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>chatgpt</category>
      <category>developer</category>
    </item>
  </channel>
</rss>
