<?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: shaharglazner</title>
    <description>The latest articles on DEV Community by shaharglazner (@shaharglazner).</description>
    <link>https://dev.to/shaharglazner</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%2F303474%2Fdcc2cb24-81fe-4136-a550-6148c8855b5d.jpeg</url>
      <title>DEV Community: shaharglazner</title>
      <link>https://dev.to/shaharglazner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shaharglazner"/>
    <language>en</language>
    <item>
      <title>Unified API for any alert from any source</title>
      <dc:creator>shaharglazner</dc:creator>
      <pubDate>Sun, 26 Nov 2023 11:55:39 +0000</pubDate>
      <link>https://dev.to/shaharglazner/unified-api-for-any-alert-from-any-source-449h</link>
      <guid>https://dev.to/shaharglazner/unified-api-for-any-alert-from-any-source-449h</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In this blog post, we will demonstrate the strength of a unified API in consolidating and managing alerts. &lt;/p&gt;

&lt;p&gt;We will create a workflow that, upon an alert triggers, generates a ServiceNow ticket, enriches it with data from a production database, and notifies the stakeholders.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's in it for you
&lt;/h2&gt;

&lt;p&gt;This technical blog post will guide you on how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect with any tool that generates alerts.&lt;/li&gt;
&lt;li&gt;Aggregate all alerts in a single interface.&lt;/li&gt;
&lt;li&gt;Enhance alerts with additional information from various sources.&lt;/li&gt;
&lt;li&gt;Automate processes based on these alerts.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Before we delve into the technicalities, let's have a brief introduction.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Keep?
&lt;/h3&gt;

&lt;p&gt;Keep is an &lt;a href="https://github.com/keephq/keep" rel="noopener noreferrer"&gt;open-source alert management and automation platform&lt;/a&gt; that integrates with your monitoring tools' alerts and provides an abstraction layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the problem Keep solves?
&lt;/h3&gt;

&lt;p&gt;Despite a trend towards consolidation in the observability space, many organizations still utilize multiple tools to generate alerts.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://grafana.com/observability-survey-2023/" rel="noopener noreferrer"&gt;Grafana's Observability Survey&lt;/a&gt; from 2023 indicates that over 52% of companies employ more than six observability tools, often due to legacy systems, cost considerations, and specific functionalities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alerting terminology
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Providers&lt;/strong&gt; - These are third-party tools that either trigger alerts, enrich alerts with data, or notify about alerts. Providers can include monitoring tools, databases, ticketing systems, or communication platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alerts&lt;/strong&gt; - Essentially, these are events or signals triggered by your monitoring tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflows&lt;/strong&gt; - Configurable automated processes that are initiated in response to alerts, designed to streamline your response to incidents by executing predefined actions, such as opening tickets, sending notifications, or initiating scripts.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enough talking, let's get started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install the CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone Keep's repo and install Keep CLI using poetry&lt;/span&gt;
gh repo clone keephq/keep 
&lt;span class="nb"&gt;cd &lt;/span&gt;keep &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; poetry &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="c"&gt;# or just install it using pip&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;keepcli
&lt;span class="c"&gt;# for other installation options (e.g. docker) see https://docs.keephq.dev/cli/installation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure the CLI:
&lt;/h3&gt;

&lt;p&gt;You can easily start using Keep's managed platform without any other prerequisites by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This will launch an oauth2 flow that will create a tenant for you and set you up&lt;/span&gt;
keep auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using Keep's open source, run &lt;code&gt;keep config&lt;/code&gt; to configure the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keep config
Enter your keep url &lt;span class="o"&gt;[&lt;/span&gt;http://localhost:8080]: 
Enter your api key &lt;span class="o"&gt;(&lt;/span&gt;leave blank &lt;span class="k"&gt;for &lt;/span&gt;localhost&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;: 
Config file created at .keep.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify everything is OK&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keep &lt;span class="nb"&gt;whoami
&lt;/span&gt;Api key valid
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'tenant_id'&lt;/span&gt;: &lt;span class="s1"&gt;'XXXXXX-YYYY-ZZZZ-8b5a-939af9d7f63b'&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1. Connect your tools
&lt;/h4&gt;

&lt;p&gt;Now we are going to connect all the providers we need - Datadog to get the alerts, ServiceNow to create and track the tickets, MySQL to enrich alerts with production data, and Slack - to notify who is needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# no providers&lt;/span&gt;
keep provider list
+----+------+------+--------------+-------------------+
| ID | Type | Name | Installed by | Installation &lt;span class="nb"&gt;time&lt;/span&gt; |
+----+------+------+--------------+-------------------+
+----+------+------+--------------+-------------------+

&lt;span class="c"&gt;# list available providers&lt;/span&gt;
keep provider list &lt;span class="nt"&gt;--available&lt;/span&gt;
+-----------------+-------------------------------------------------------+
|     Provider    |                      Description                      |
+-----------------+-------------------------------------------------------+
|       aks       |           Enrich alerts using data from AKS.          |
...
|      zabbix     |        Pull/Push alerts from Zabbix into Keep.        |
|     zenduty     |              Create incident &lt;span class="k"&gt;in &lt;/span&gt;Zenduty.              |
+-----------------+-------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's connect datadog, MySQL, servicenow and slack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For every provider, you can what authentication details needed&lt;/span&gt;
keep provider connect datadog &lt;span class="nt"&gt;--help&lt;/span&gt;
+----------+--------------+----------+-----------------+
| Provider | Config Param | Required |   Description   |
+----------+--------------+----------+-----------------+
| datadog  |   api_key    |   True   | Datadog Api Key |
|          |   app_key    |   True   | Datadog App Key |
+----------+--------------+----------+-----------------+
&lt;span class="c"&gt;# Connect Slack&lt;/span&gt;
keep provider connect slack &lt;span class="nt"&gt;--provider-name&lt;/span&gt; slack-prod &lt;span class="nt"&gt;--webhook-url&lt;/span&gt; https://hooks.slack.com/services/T03PMXXXXX/B0656YYYY/yQ7zncdkuhzrGDWILtuZZZZZ
Provider slack-prod installed successfully
Provider &lt;span class="nb"&gt;id&lt;/span&gt;: 82a2c69d26e64d3f8ec81eb25d13f972

&lt;span class="c"&gt;# Connect datadog&lt;/span&gt;
keep provider connect datadog &lt;span class="nt"&gt;--provider-name&lt;/span&gt; datadog-prod &lt;span class="nt"&gt;--api-key&lt;/span&gt; XXXXXXX &lt;span class="nt"&gt;--app-key&lt;/span&gt; YYYYYYY
Provider datadog-prod installed successfully
Provider &lt;span class="nb"&gt;id&lt;/span&gt;: e33c9960d862453dace829f6a8aecbcf

&lt;span class="c"&gt;# Connect mysql&lt;/span&gt;
keep provider connect mysql &lt;span class="nt"&gt;--provider-name&lt;/span&gt; mysql-prod &lt;span class="nt"&gt;--username&lt;/span&gt; dbuser &lt;span class="nt"&gt;--password&lt;/span&gt; dbpass &lt;span class="nt"&gt;--host&lt;/span&gt; keepdb
Provider mysql-prod installed successfully
Provider &lt;span class="nb"&gt;id&lt;/span&gt;: d1c3a24621254565970ac6fab74697b7

&lt;span class="c"&gt;# Connect Service Now&lt;/span&gt;
keep provider connect servicenow &lt;span class="nt"&gt;--provider-name&lt;/span&gt; servicenow-prod &lt;span class="nt"&gt;--service-now-base-url&lt;/span&gt; https://dev123456.service-now.com &lt;span class="nt"&gt;--username&lt;/span&gt; user &lt;span class="nt"&gt;--password&lt;/span&gt; password

&lt;span class="c"&gt;# Verify the providers connected&lt;/span&gt;
keep provider list
+----------------------------------+------------+-----------------+-------------------+----------------------------+
|                ID                |    Type    |       Name      |    Installed by   |     Installation &lt;span class="nb"&gt;time&lt;/span&gt;      |
+----------------------------------+------------+-----------------+-------------------+----------------------------+
| e33c9960d862453dace829f6a8aecbcf |  datadog   |   datadog-prod  | apikey@keephq.dev | 2023-11-08T13:23:29.531775 |
| d1c3a24621254565970ac6fab74697b7 |   mysql    |    mysql-prod   | apikey@keephq.dev | 2023-11-08T13:26:12.249923 |
| 066f2a02326c41819c19d61ed6976b65 | servicenow | servicenow-prod | apikey@keephq.dev | 2023-11-08T13:28:35.930792 |
| 82a2c69d26e64d3f8ec81eb25d13f972 |   slack    |    slack-prod   | apikey@keephq.dev | 2023-11-08T13:19:00.539780 |
+----------------------------------+------------+-----------------+-------------------+----------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we go the the UI at &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;, we can see that the providers are installed:&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%2F32402ewd1xigc5koub4e.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%2F32402ewd1xigc5koub4e.png" alt="Keep UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Review alerts
&lt;/h4&gt;

&lt;p&gt;In this section, we are going to review the alerts, show how the alert looks in Keep, and demonstrate enrichment and filtering capabilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# list all alerts&lt;/span&gt;
keep alert list
+---------------------+------------------------------------------------------------------+--------------------------------+----------+-----------+-------------+---------+-------------+---------------------+
|          ID         |                           Fingerprint                            |              Name              | Severity |   Status  | Environment | Service |    Source   |    Last Received    |
+---------------------+------------------------------------------------------------------+--------------------------------+----------+-----------+-------------+---------+-------------+---------------------+
| 7308482322424796476 | 5bcafb4ea94749f36871a2e1169d5252ecfb1c589d7464bd8bf863cdeb76b864 |  Unauthorized access to API    |   high   | Recovered |  undefined  |   None  | &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'datadog'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; | 2023-11-13T15:32:38 |
| 7308433771057253905 | 39f3a0d2cfe87885be0283c94ffd1cc35be1fd1bdd108c86ddf8e9db5d3bd7f0 |           Test Alert           | critical | Recovered |  undefined  |   None  | &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'datadog'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; | 2023-11-13T14:44:24 |
...
more alerts
...
+-----------+----------------------------+----------------------------+----------+--------+-------------+----------+-------------+---------------------------+

&lt;span class="c"&gt;# Filter by attribute&lt;/span&gt;
keep alert list &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;keep-api
+-----------+----------------------------+----------------------------+----------+--------+-------------+----------+-------------+---------------------------+
|     ID    |        Fingerprint         |            Name            | Severity | Status | Environment | Service  |    Source   |       Last Received       |
+-----------+----------------------------+----------------------------+----------+--------+-------------+----------+-------------+---------------------------+
| 120458754 | 5bcafb4ea94749f36871a2e1169d5252ecfb1c589d7464bd8bf863cdeb76b864  | 4xx-5xx Status Code Alert  |  medium  |   OK   |  production | keep-api | &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'datadog'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; | 2023-05-31T10:59:29+00:00 |
| 122655180 | 5bcafb4ea94749f36871a2e1169d5252ecfb1c389d7464bd8bf863cdeb76b864 | Unauthorized access to API |   high   |   OK   |  production | keep-api | &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'datadog'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; | 2023-11-08T13:29:31+00:00 |
+-----------+----------------------------+----------------------------+----------+--------+-------------+----------+-------------+---------------------------+


keep alert list &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="nv"&gt;severity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;critical
+-----------+-------------+------------+----------+--------+-------------+----------+-------------+---------------------------+
|     ID    | Fingerprint |    Name    | Severity | Status | Environment | Service  |    Source   |       Last Received       |
+-----------+-------------+------------+----------+--------+-------------+----------+-------------+---------------------------+
| 117493674 |  5bcafb4ea94749f36871a2e1169d5252ecfb1c589d7464bd8bf863cdeb76b862 | Prod Alert | critical |   OK   |  production | tal-test | &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'datadog'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; | 2023-09-13T11:20:25+00:00 |
+-----------+-------------+------------+----------+--------+-------------+----------+-------------+---------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what's even cooler is that we can filter on ANY alert attribute. Together with that Keep lets you enrich alerts with attributes from different sources, and you can achieve very cool things. &lt;/p&gt;

&lt;p&gt;To put things into earth, let's say we created (we will of course automate this later) a ticket in our ticketing system. &lt;br&gt;
We want to correlate the alert with the ticket, so we will be able to sync any further changes to the ticket.&lt;/p&gt;

&lt;p&gt;We also want information about the customer that is stored on our customers' database.&lt;/p&gt;

&lt;p&gt;We can get this information by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+---------------------+------------+---------------------+--------------+---------------+-----------------------------+--------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;                &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;tier&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;               &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt;                       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;                          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+---------------------+------------+---------------------+--------------+---------------+-----------------------------+--------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt; &lt;span class="n"&gt;Corporation&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Enterprise&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;456&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7890&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt; &lt;span class="n"&gt;St&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;since&lt;/span&gt; &lt;span class="mi"&gt;2010&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="n"&gt;bc71af&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;820&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="n"&gt;ee&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b23f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0242&lt;/span&gt;&lt;span class="n"&gt;ac110002&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming we want to enrich the alert with customer name, customer email and ticket id:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keep alert enrich &lt;span class="nt"&gt;--fingerprint&lt;/span&gt; 39f3a0d2cfe87885be0283c94ffd1cc35be1fd1bdd108c86ddf8e9db5d3bd7f0 &lt;span class="nv"&gt;customer_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1234 &lt;span class="nv"&gt;ticket_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;INC00001 &lt;span class="nv"&gt;customer_email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;abd@example.com

&lt;span class="c"&gt;# Now we can filter by responder:&lt;/span&gt;
keep alert list &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="nv"&gt;ticket_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;INC00001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Create workflows
&lt;/h4&gt;

&lt;p&gt;So far, we connected the providers, reviewed our Datadog alerts, and enriched them with customer data and ServiceNow tickets.&lt;/p&gt;

&lt;p&gt;Now we will wrap it up and automate the whole process using Keep Workflows.&lt;/p&gt;

&lt;h5&gt;
  
  
  Anatomy of a Workflow
&lt;/h5&gt;

&lt;p&gt;Before diving into the CLI commands, let's review the workflow we are going to run. Keep Workflows are very similar to GitHub Action workflows. We didn't want to invent the wheel here, so you should be pretty familiar with the syntax.&lt;/p&gt;

&lt;p&gt;The full workflow YAML can be found &lt;a href="https://github.com/keephq/keep/examples/workflows" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;workflow:
  &lt;span class="c"&gt;# some metadata&lt;/span&gt;
  &lt;span class="nb"&gt;id&lt;/span&gt;: example-workflow
  description: Enriches the alert and create a ServiceNow ticket

  &lt;span class="c"&gt;# The first part is the triggers. We want this workflow to execute only on critical alerts. We can filter on any alert attribute and also use regex.&lt;/span&gt;
  triggers:
    - &lt;span class="nb"&gt;type&lt;/span&gt;: alert
      filters:
        - key: severity
          value: critical
  steps:
  &lt;span class="c"&gt;# The first step is to enrich the alert based on the SQL query. We want to add the customer name, email, and tier. &lt;/span&gt;
  - name: get-more-details
    provider:
      &lt;span class="nb"&gt;type&lt;/span&gt;: mysql 
      config: &lt;span class="s2"&gt;" {{ providers.mysql-prod }} "&lt;/span&gt;
      &lt;span class="c"&gt;# {{ alert.customer_id }} will be extracted on runtime&lt;/span&gt;
      with:
        query: &lt;span class="s2"&gt;"select * from customers where customer_id = {{ alert.customer_id }}"&lt;/span&gt;
        &lt;span class="c"&gt;# Add those fields to the alert so we can use it&lt;/span&gt;
        enrich_alert:
          - key: customer_name
            value: results[0].name
          - key: customer_email
            value: results[0].email
          - key: customer_tier
            value: results[0].tier
  &lt;span class="c"&gt;# second part - the actions &lt;/span&gt;
  actions:
    &lt;span class="c"&gt;# create the servicenow ticket&lt;/span&gt;
    - name: create-service-now-ticket
      &lt;span class="c"&gt;# In case the alert already assigned a ticket id, don't create a new one (imagine the case when the alert was triggered and then resolved, we don't want another ticket for the resolved). Also, we want to create a ticket only for Enterprise customers.&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;: &lt;span class="s2"&gt;"not '{{ alert.ticket_id }}' and '{{ alert.tier }}' == 'Enterprise'"&lt;/span&gt;
      provider:
        &lt;span class="nb"&gt;type&lt;/span&gt;: servicenow
        config: &lt;span class="s2"&gt;" {{ providers.servicenow }} "&lt;/span&gt;
        with:
          table_name: INCIDENT
          payload:
            short_description: &lt;span class="s2"&gt;"{{ alert.name }} - {{ alert.description }} [created by Keep]"&lt;/span&gt;
            description: &lt;span class="s2"&gt;"{{ alert.description }}"&lt;/span&gt;
          &lt;span class="c"&gt;# Enrich the alert with these fields so we will have correlation between the alert and the ticket&lt;/span&gt;
          enrich_alert:
            - key: ticket_type
              value: servicenow
            - key: ticket_id
              value: results.sys_id
            - key: ticket_url
              value: results.link
            - key: ticket_status
              value: results.stage
            - key: table_name
              value: &lt;span class="s2"&gt;"{{ alert.annotations.ticket_type }}"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now after we have the workflow, let's apply and run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# no workflows&lt;/span&gt;
keep workflow list
+--------------------------------------+--------------------------------------+----------------------------+-------------------------------------------------+--------------------------+----------------+
|                  ID                  |             Workflow ID              |         Start Time         |                   Triggered By                  |          Status          | Execution Time |
+--------------------------------------+--------------------------------------+----------------------------+-------------------------------------------------+--------------------------+----------------+
+--------------------------------------+--------------------------------------+----------------------------+-------------------------------------------------+--------------------------+----------------+
&lt;span class="c"&gt;# Apply it:&lt;/span&gt;
keep workflow apply &lt;span class="nt"&gt;-f&lt;/span&gt; workflow.yaml
Workflow examples/workflows/blogpost.yml applied successfully
Workflow &lt;span class="nb"&gt;id&lt;/span&gt;: 652fe84e-5239-425b-8271-40accb1af72f
Workflow revision: 1
keep workflow list
+--------------------------------------+-------------------+-----------------------------------+----------+--------------+----------------------------+----------------------------+----------------------------+-----------------------+
|                  ID                  |        Name       |            Description            | Revision |  Created By  |       Creation Time        |        Update Time         |    Last Execution Time     | Last Execution Status |
+--------------------------------------+-------------------+-----------------------------------+----------+--------------+----------------------------+----------------------------+----------------------------+-----------------------+
| 652fe84e-5239-425b-8271-40accb1af72f | blogpost-workflow | Enrich the alerts and open ticket |    10    |     keep     | 2023-11-12T08:08:43.585226 | 2023-11-12T14:34:07.544301 |            None            |          None         |
+--------------------------------------+-------------------+-----------------------------------+----------+--------------+----------------------------+----------------------------+----------------------------+-----------------------+
&lt;span class="c"&gt;# Run it with alert as input &lt;/span&gt;
keep workflow run &lt;span class="nt"&gt;--workflow-id&lt;/span&gt; blogpost-workflow &lt;span class="nt"&gt;--fingerprint&lt;/span&gt; 39f3a0d2cfe87885be0283c94ffd1cc35be1fd1bdd108c86ddf8e9db5d3bd7f0
Workflow blogpost-workflow run successfully
Workflow Run ID 33e71955-81f4-4118-9771-7b638f8c59b0

&lt;span class="c"&gt;# Let's review the run&lt;/span&gt;
keep workflow runs logs 33e71955-81f4-4118-9771-7b638f8c59b0

+-----+----------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |  ID |         Timestamp          | Message                                                                                                                                                                                                                                                         |
+-----+----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 733 | 2023-11-13T16:11:40.462000 | Running step get-more-details                                                                                                                                                                                                                                   |
| 734 | 2023-11-13T16:11:40.463000 | Action get-more-details evaluated to run! Reason: no condition, hence true.                                                                                                                                                                                     |
| 735 | 2023-11-13T16:11:40.524000 | Step get-more-details ran successfully                                                                                                                                                                                                                          |
| 736 | 2023-11-13T16:11:40.525000 | Running action create-service-now-ticket                                                                                                                                                                                                                        |
| 737 | 2023-11-13T16:11:40.525000 | Action create-service-now-ticket evaluated to run! Reason: no condition, hence true.                                                                                                                                                                            |
| 738 | 2023-11-13T16:11:44.784000 | Created ticket: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'result'&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'parent'&lt;/span&gt;: &lt;span class="s1"&gt;''&lt;/span&gt;, &lt;span class="s1"&gt;'made_sla'&lt;/span&gt;: &lt;span class="s1"&gt;'true'&lt;/span&gt;, &lt;span class="s1"&gt;'caused_by'&lt;/span&gt;: &lt;span class="s1"&gt;''&lt;/span&gt;, &lt;span class="s1"&gt;'watch_list'&lt;/span&gt;: &lt;span class="s1"&gt;''&lt;/span&gt;, &lt;span class="s1"&gt;'upon_reject'&lt;/span&gt;: &lt;span class="s1"&gt;'cancel'&lt;/span&gt;, &lt;span class="s1"&gt;'sys_updated_on'&lt;/span&gt;: &lt;span class="s1"&gt;'2023-11-13 14:11:41'&lt;/span&gt;, &lt;span class="s1"&gt;'child_incidents'&lt;/span&gt;: &lt;span class="s1"&gt;'0'&lt;/span&gt;, &lt;span class="s1"&gt;'hold_reason'&lt;/span&gt;: &lt;span class="s1"&gt;''&lt;/span&gt;, &lt;span class="s1"&gt;'origin_table'&lt;/span&gt;: &lt;span class="s1"&gt;''&lt;/span&gt;, &lt;span class="s1"&gt;'task_effective_number'&lt;/span&gt;: &lt;span class="s1"&gt;'INC'&lt;/span&gt; |
| 740 | 2023-11-13T16:12:47.552000 | Enriching alert                                                                                                                                                                                                                                                 |
| 741 | 2023-11-13T16:12:47.572000 | Alert enriched                                                                                                                                                                                                                                                  |
| 742 | 2023-11-13T16:12:47.573000 | Action create-service-now-ticket ran successfully                                                                                                                                                                                                               |
| 743 | 2023-11-13T16:12:47.574000 | Finish to run workflow blogpost-workflow                                                                                                                                                                                                                        |
+-----+----------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

keep workflow runs list
+--------------------------------------+--------------------------------------+----------------------------+-------------------------------+-------------+----------------------------------------------------+----------------+
|                  ID                  |             Workflow ID              |         Start Time         |          Triggered By         |    Status   | Error                                              | Execution Time |
+--------------------------------------+--------------------------------------+----------------------------+-------------------------------+-------------+----------------------------------------------------+----------------+
| 103df0aa-d6be-4290-9938-1563f8005e55 | 75c7eba2-51dc-411d-b39c-a500c98e3893 | 2023-11-13T14:11:37.911898 | manually by apikey@keephq.dev |   success   | None                                               |       69       |
+--------------------------------------+--------------------------------------+----------------------------+-------------------------------+-------------+----------------------------------------------------+----------------+
&lt;span class="c"&gt;# Let's make sure the alert was enriched with the ticket id&lt;/span&gt;
keep alert get 39f3a0d2cfe87885be0283c94ffd1cc35be1fd1bdd108c86ddf8e9db5d3bd7f0 | jq .ticket_id
&lt;span class="s2"&gt;"0f9982ec97667110beb0f0571153afa1"&lt;/span&gt;
&lt;span class="c"&gt;# :)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Voila! Now, whenever an alert is triggered, it will be automatically enriched with data from our production database, and appropriate actions will be taken. If the alert is of high or critical severity, a ServiceNow ticket will be created and the alert will be updated with the ticket ID. For less severe alerts, the relevant individual will simply be notified.&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%2Fy4voce15eqqg7vl2g0d4.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%2Fy4voce15eqqg7vl2g0d4.png" alt="The alert has ticket assigned"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Next steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Join our Slack at &lt;a href="https://slack.keephq.dev" rel="noopener noreferrer"&gt;https://slack.keephq.dev&lt;/a&gt; and start talking about alerting and monitoring. &lt;/li&gt;
&lt;li&gt;⭐️ our repo at &lt;a href="https://github.com/keephq/keep" rel="noopener noreferrer"&gt;https://github.com/keephq/keep&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Start playing with Keep (no credit card needed!) at &lt;a href="https://platform.keephq.dev" rel="noopener noreferrer"&gt;https://platform.keephq.dev&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Missing any provider/feature? just open an issue at &lt;a href="https://github.com/keephq/keep" rel="noopener noreferrer"&gt;https://github.com/keephq/keep&lt;/a&gt; and we will add it ASAP (and of course contributions are welcome!)&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Current problems in the alerting space</title>
      <dc:creator>shaharglazner</dc:creator>
      <pubDate>Tue, 28 Mar 2023 19:25:16 +0000</pubDate>
      <link>https://dev.to/shaharglazner/current-problems-in-the-alerting-space-1gi0</link>
      <guid>https://dev.to/shaharglazner/current-problems-in-the-alerting-space-1gi0</guid>
      <description>&lt;h3&gt;
  
  
  Current problems in the alerting space
&lt;/h3&gt;

&lt;h4&gt;
  
  
  In the past month, we have engaged in conversations with over 50 engineers, engineering managers, and SREs to gather feedback on the products we are developing at &lt;a href="https://www.keephq.dev/"&gt;Keep&lt;/a&gt;. Here is a summary of what we have learned.
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;TL;DR:&lt;br&gt;
 Creating and maintaining effective alerts, avoiding alert fatigue, and promoting a strong alerting culture can be difficult tasks. Keep addresses these challenges by treating alerts as code, integrating with observability tools, and using LLMs.&lt;br&gt;
 Want to learn more? talk with me at &lt;a href="//mailto:shahar@keephq.dev"&gt;shahar@keephq.dev&lt;/a&gt;, join Keep Slack — &lt;a href="https://keephq.dev/slack"&gt;https://keephq.dev/slack&lt;/a&gt; or just start play with Keep &lt;a href="https://github.com/keephq/keep"&gt;https://github.com/keephq/keep&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why alerting?
&lt;/h3&gt;

&lt;p&gt;Now, let’s discuss why alerting is crucial.&lt;/p&gt;

&lt;p&gt;With the increasing reliance on digital systems, monitoring, and alerting have become more critical than ever. Downtime or slow website performance can lead to significant financial losses and drive customers away to other competitors.&lt;/p&gt;

&lt;p&gt;To meet the growing demand for observability, there has been a significant proliferation of observability tools, with companies like Datadog, Grafana, New Relic, Elasticsearch, and Splunk dominating the market. In addition, many other tools like Sentry, Coralogix, Sumo Logic, and BugSnag have also gained widespread adoption.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://grafana.com/observability-survey-2023/"&gt;Grafana Labs Observability Survey 2023&lt;/a&gt;, 52% of companies use 6 or more observability tools (!) highlighting the significance of the problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gsr012fG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2116/1%2ASSTAJ29_RwjGwFgBNufKVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gsr012fG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2116/1%2ASSTAJ29_RwjGwFgBNufKVA.png" alt="Tools that fire alerts" width="880" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  So what’s the problem, if any?
&lt;/h3&gt;

&lt;p&gt;There are several current problems around alerting that hinder companies from getting the most out of their monitoring systems. Let’s review them.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Alerts fatigue
&lt;/h3&gt;

&lt;p&gt;One of the significant problems with alerting is alert fatigue. When you receive too many alerts, it can be challenging to determine which ones are critical and which ones can be ignored. This can lead to a lack of attention to alerts, which can ultimately result in missing critical issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Monitoring your monitoring
&lt;/h3&gt;

&lt;p&gt;It’s essential to ensure that your monitoring tools are working correctly and providing accurate and timely alerts. However, it can be challenging to keep track of all the monitoring tools that you’re using, and it can be even more challenging to keep them all in sync.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Alerts maintenance
&lt;/h3&gt;

&lt;p&gt;As systems change, alerts may need to be updated to reflect these changes. However, it can be challenging to keep track of all the alerts that need to be updated, leading to outdated alerts being triggered (or not triggered at all).&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Lack of developer experience
&lt;/h3&gt;

&lt;p&gt;Many companies rely on developers to set up and maintain their alerting systems. However, not all developers have the necessary experience to create effective alerting systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Too many tools
&lt;/h3&gt;

&lt;p&gt;Finally, many companies have too many alerting tools, making it challenging to keep track of alerts, leading to confusion and missed alerts.&lt;/p&gt;

&lt;p&gt;In conclusion, monitoring and alerting are critical for companies to ensure their systems run efficiently and effectively. However, several current problems with alerting can hinder companies from getting the most out of their monitoring systems. By understanding these problems, companies can work to overcome them and ensure that their monitoring systems provide accurate and timely alerts.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does keep solving that?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PAZkmmYD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2820/1%2AnObtldjTxegBtS2Z8u5HBQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PAZkmmYD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2820/1%2AnObtldjTxegBtS2Z8u5HBQ.png" alt="Keep High-Level Architecture" width="880" height="709"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep takes a holistic approach to solving all these problems with alerting. By treating alerts as code and integrating them with existing observability tools, along with leveraging AI, Keep can achieve the following objectives -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Measure engagement, reduce noise, add context, and fine-tune the alerts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Single pane of glass — by integrating with all of your observability tools, Keep decoupling and deduplicating alerts so if your database is down, you’ll know that the alerts from the frontend are because of that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using Keep’s CI/CD integration, you can maintain your alerts as easily as adding a new step in your GitHub Action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decouple what you want to alert from the actual tool —using Keep’s semantic layer, a developer can just write “Using Datadog, alert me when service X is down for than Y minutes”.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In today’s digital age, monitoring and alerting are critical for ensuring the smooth functioning of a company’s systems. However, several problems with alerting are hindering companies from getting the most out of their monitoring systems. These problems include alert fatigue, difficulty in monitoring your monitoring, alert maintenance, lack of developer experience, and too many alerting tools. Keep, a platform that treats alerts as code and integrates them with existing observability tools, provides a holistic approach to solving these issues. By leveraging AI and using a semantic layer, Keep can measure engagement, reduce noise, add context, and fine-tune alerts, providing a single pane of glass for all observability tools, and allowing for easy maintenance of alerts.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>alerting</category>
      <category>devops</category>
    </item>
    <item>
      <title>Keep – Open-source alerting CLI</title>
      <dc:creator>shaharglazner</dc:creator>
      <pubDate>Tue, 28 Feb 2023 14:40:45 +0000</pubDate>
      <link>https://dev.to/shaharglazner/keep-open-source-alerting-cli-1d7o</link>
      <guid>https://dev.to/shaharglazner/keep-open-source-alerting-cli-1d7o</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;Simple alerting tool, builtin providers (e.g. sentry/datadog or slack/pagerduty), 100% open sourced, free forever.&lt;br&gt;
Simple and intuitive (GitHub actions-like) syntax.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Declarative alerting that can be easily managed and versioned in your version control and service repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alerts from multiple data sources for added context and insights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Freedom from vendor lock-in, making it easier to switch to a different observability tool if and when needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;DevOps&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/keephq/keep"&gt;https://github.com/keephq/keep&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.keephq.dev/"&gt;https://www.keephq.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/keephq/keep"&gt;https://github.com/keephq/keep&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MIT License&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;We believe that alerting has historically been neglected in existing monitoring platforms, leading to subpar alerting practices. With Keep, we aim to change that.&lt;/p&gt;

</description>
      <category>python</category>
      <category>monitoring</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
