<?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: Connor </title>
    <description>The latest articles on DEV Community by Connor  (@noccor).</description>
    <link>https://dev.to/noccor</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%2F1071476%2Fad37371a-fae3-4019-b3b4-91021b7a2f7b.png</url>
      <title>DEV Community: Connor </title>
      <link>https://dev.to/noccor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noccor"/>
    <language>en</language>
    <item>
      <title>Tracking Custom Metrics in Python with AppSignal</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Thu, 18 Apr 2024 13:55:40 +0000</pubDate>
      <link>https://dev.to/appsignal/tracking-custom-metrics-in-python-with-appsignal-2oi2</link>
      <guid>https://dev.to/appsignal/tracking-custom-metrics-in-python-with-appsignal-2oi2</guid>
      <description>&lt;p&gt;We have improved our custom metrics offering with two recent Python releases. In release 1.1.1 of our Python package, we &lt;a href="https://www.appsignal.com/changelog/python#add-distribution-value-custom-metric-helper" rel="noopener noreferrer"&gt;added the &lt;code&gt;add_distribution_value&lt;/code&gt; helper&lt;/a&gt;, and in version 1.2.0, we &lt;a href="https://www.appsignal.com/changelog/python#add-minutely-probes-and-other-improvements" rel="noopener noreferrer"&gt;added support for minutely probes&lt;/a&gt;, so you can measure the distribution of key data points in your Python application.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll show you how to set up custom metrics in your Python application to gain valuable insights without sifting through logs or querying databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Custom Metrics?
&lt;/h2&gt;

&lt;p&gt;You can use custom metrics to track any data point alongside your core metric data. Custom metrics give you additional context into how your application performs: for example, an active user count or the processing time of critical tasks.&lt;/p&gt;

&lt;p&gt;AppSignal treats custom metrics like any other metric data point; you can create dashboards to visually track them. You can also set up alerts for when custom metrics meet a specific threshold (for example, if a task has been running slowly for over 15 minutes).&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metrics-graph-hover.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metrics-graph-hover.png" alt="Magic Dashboard hover-over, with links to Time Detective"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Metric Types in AppSignal for Python
&lt;/h3&gt;

&lt;p&gt;While our latest change allows you to measure distributions with Python, AppSignal also has Python helper functions for measuring custom metrics as gauges and counters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measure&lt;/th&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gauge&lt;/td&gt;
&lt;td&gt;&lt;code&gt;set_gauge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A number that represents a particular value at a specific point in time that can frequently be overwritten, such as the count of an application's active users.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Counter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;increment_counter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A number you can increment by any given value, such as the count of times a process has run.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distribution&lt;/td&gt;
&lt;td&gt;&lt;code&gt;add_distribution_value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A collection of numbers from which we store an average, count, or percentile. You can use this to track a spread of values in a dataset - for example, the average user cart value of an e-commerce application, or the percentage of tasks completed within a desired time.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Using Custom Metrics for Deeper Context
&lt;/h2&gt;

&lt;p&gt;You can leverage custom metrics to measure virtually any data point within your application. This is especially handy if your application has high-volume mission-critical flows.&lt;/p&gt;

&lt;p&gt;As an example, consider the process of making a purchase. An issue with a third-party payment provider might prevent users from completing their purchase but wouldn't trigger an exception within your application, as it lies outside of your stack.&lt;/p&gt;

&lt;p&gt;However, with custom metrics, you can utilize measurable key performance points to help you proactively monitor your application for exceptions beyond the boundaries of its codebase (by monitoring your order count, for example).&lt;/p&gt;

&lt;p&gt;Custom metrics can help you quickly investigate and resolve an issue before it hurts your bottom line - e.g., if your app often processes dozens of orders per hour, but that count suddenly drops to zero:&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metrics-dip.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metrics-dip.png" alt="Graph showing an in-app purchases dip"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Metrics In Practice
&lt;/h2&gt;

&lt;p&gt;For this article, let's imagine we've got a successful Django webshop that we're already monitoring with AppSignal. To broaden our understanding of our application's behavior, we're going to use custom metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gauge
&lt;/h3&gt;

&lt;p&gt;While AppSignal makes it easy for us to know when and where our application is less performant, we can use the &lt;code&gt;set_gauge&lt;/code&gt; function to track &lt;code&gt;active_shoppers&lt;/code&gt; and help us understand how scale impacts our performance.&lt;/p&gt;

&lt;p&gt;To do this, we'll create a minutely probe task to report the count of carts that were updated within the last minute:&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="c1"&gt;# import helper probe and set_gauge functions
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;appsignal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;probes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_gauge&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_active_carts_gauge&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;one_minute_ago&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;active_carts_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updated_at__gte&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;one_minute_ago&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;set_gauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active_shoppers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active_carts_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;probes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active_shoppers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_active_carts_gauge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once our Celery task is configured and sending data to AppSignal, we'll be able to create a chart in AppSignal that tracks how many &lt;code&gt;active_shoppers&lt;/code&gt; are using our Django app:&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metrics-active-shoppers.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metrics-active-shoppers.png" alt="Graph showing active shoppers metric"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Counter
&lt;/h3&gt;

&lt;p&gt;As our application's usage grows, so too does the usage of critical infrastructure, like tasks.&lt;/p&gt;

&lt;p&gt;Our Django application runs an invoice task for every order made. We can use the &lt;code&gt;increment_counter&lt;/code&gt; helper function when running that task to give us instant insights into how many tasks our Django application is processing:&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="c1"&gt;# Import increment_counter helper function
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;appsignal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;increment_counter&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_order_invoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# task logic
&lt;/span&gt;    &lt;span class="nf"&gt;increment_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invoice_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use the increment counter to track additional metrics, such as &lt;code&gt;order_count&lt;/code&gt;, and create graphs to monitor &lt;code&gt;invoice_count&lt;/code&gt; and &lt;code&gt;order_count&lt;/code&gt; alongside one another:&lt;/p&gt;

&lt;p&gt;&lt;a href="/images/blog/2024-03/custom-metrics-orders-invoices.png" class="article-body-image-wrapper"&gt;&lt;img src="/images/blog/2024-03/custom-metrics-orders-invoices.png" alt="Graph showing invoices and order metrics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This graph gives us instant visual insights into our application's performance. For example, if we notice that the &lt;code&gt;invoice_count&lt;/code&gt; value is flatlining against the &lt;code&gt;order_count&lt;/code&gt;, we can proactively investigate to ensure there aren't any undetected issues preventing invoice tasks from running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Distribution
&lt;/h3&gt;

&lt;p&gt;Let's expand our tracking to include the distribution of item count per order. There are many reasons why this metric may be helpful. We may want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be notified when purchasing trends become irregular - for example, when there are excessive numbers of cart items.&lt;/li&gt;
&lt;li&gt;Ensure our app can scale with demand: large purchases may result in slow tasks and lead to bottlenecks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To do this, we can use the new &lt;code&gt;add_distribution_value&lt;/code&gt; helper function to track the item count of our app's orders:&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="c1"&gt;# import add_distribution_value helper function
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;appsignal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_distribution_value&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;confirm_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# function logic
&lt;/span&gt;
    &lt;span class="n"&gt;item_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;add_distribution_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order_item_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once implemented, our application will report the &lt;code&gt;order_item_count&lt;/code&gt; custom metric value, which we can track on a dashboard (and use to configure alerts):&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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metric-order-count.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%2Fblog.appsignal.com%2Fimages%2Fblog%2F2024-03%2Fcustom-metric-order-count.png" alt="Graph showing order confirmation metric"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Metrics for Powerful Python Insights
&lt;/h2&gt;

&lt;p&gt;Custom metrics provide high-impact insights into your Python application's performance, removing the need to analyze dozens of samples, search through thousands of log-lines, or painfully reproduce a problem.&lt;/p&gt;

&lt;p&gt;When properly utilized, custom metrics can help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quickly find the cause of an issue&lt;/li&gt;
&lt;li&gt;Easily contextualize application performance&lt;/li&gt;
&lt;li&gt;Reduce reproduction times&lt;/li&gt;
&lt;li&gt;Save on unnecessary log storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're interested in using custom metrics to level up your Python performance monitoring, you can read more in-depth information in our &lt;a href="https://docs.appsignal.com/metrics/custom.html" rel="noopener noreferrer"&gt;custom metrics documentation&lt;/a&gt;. We've also got in-depth &lt;a href="https://docs.appsignal.com/python/instrumentation/minutely-probes.html" rel="noopener noreferrer"&gt;documentation about our minutely probes helper functions&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSignal: Making Monitoring Simple
&lt;/h2&gt;

&lt;p&gt;At AppSignal, we work hard to make monitoring your application feel like magic. We're here to help developers on projects of all shapes and sizes to get the most out of their applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That's why we're the only APM to offer:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.appsignal.com/plans" rel="noopener noreferrer"&gt;Simple, straight-forward pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.appsignal.com/upgrade-policy" rel="noopener noreferrer"&gt;A flexible upgrade policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Friendly, free dev-to-dev support&lt;/li&gt;
&lt;li&gt;A 30-day free trial&lt;/li&gt;
&lt;li&gt;Sweet, sweet stroopwafels for all new customers 🧇&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://appsignal.com/users/sign_up" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt; today and join thousands of developers who use AppSignal daily to monitor, maintain, and enhance their applications.&lt;/p&gt;

</description>
      <category>python</category>
      <category>apm</category>
    </item>
    <item>
      <title>AppSignal Expands Monitoring Capabilities with Vector</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Wed, 10 Jan 2024 10:00:00 +0000</pubDate>
      <link>https://dev.to/appsignal/appsignal-expands-monitoring-capabilities-with-vector-22cd</link>
      <guid>https://dev.to/appsignal/appsignal-expands-monitoring-capabilities-with-vector-22cd</guid>
      <description>&lt;p&gt;We're excited to announce AppSignal support for Vector logs and metrics!&lt;/p&gt;

&lt;p&gt;AppSignal's &lt;a href="https://vector.dev/"&gt;Vector&lt;/a&gt; support allows you to expand your monitoring horizons beyond our standard language integrations, making it possible to leverage AppSignal to both monitor the performance and manage the logs of components of your stack that fall outside a standard application.&lt;/p&gt;

&lt;p&gt;With Vector, you can use AppSignal to monitor how your databases and Kubernetes clusters perform and metrics from &lt;a href="https://vector.dev/docs/reference/configuration/sources/"&gt;many other sources&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic Dashboards for PostgreSQL and MongoDB
&lt;/h2&gt;

&lt;p&gt;AppSignal's Automated Dashboards take the guesswork out of monitoring, giving you instant performance insights into core metrics.&lt;/p&gt;

&lt;p&gt;We currently offer out-of-the-box Vector support for PostgreSQL and MongoDB Automated Dashboards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tg5LLqK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-12/vector-postgresql-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tg5LLqK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-12/vector-postgresql-dashboard.png" alt="Vector PostgreSQL dashboard example" width="800" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our PostgreSQL and MongoDB dashboards give you deep performance insights, helping you answer important performance questions at a glance, like:&lt;/p&gt;

&lt;h4&gt;
  
  
  PostgreSQL
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;What is the count of each query type: &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;COMMIT&lt;/code&gt;, and &lt;code&gt;ROLLBACK&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;How many queries were rolled back?&lt;/li&gt;
&lt;li&gt;How many deadlocks occurred?&lt;/li&gt;
&lt;li&gt;How many database clients are connected?&lt;/li&gt;
&lt;li&gt;How many temporary files have been written to disk for queries?&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  MongoDB
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;What's the health of the databases? (memory usage, network usage, number of operations, open connections with clients)&lt;/li&gt;
&lt;li&gt;How is the database performing? (number of bytes read and written, cache size, number of in-progress transactions)&lt;/li&gt;
&lt;li&gt;Is database replication delayed? (network usage, buffer size, number of operations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn more about PostgreSQL and MongoDB Automated Dashboards in our &lt;a href="https://docs.appsignal.com/vector/"&gt;Vector documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Vector Source Metrics
&lt;/h2&gt;

&lt;p&gt;You can also create graphs and dashboards with Vector's sources. AppSignal currently supports metrics from the following sources:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Source Name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/aws_ecs_metrics/"&gt;Amazon Elastic Container Service&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;aws_ecs_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/apache_metrics/"&gt;Apache HTTPD Server&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apache_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/eventstoredb_metrics/"&gt;EventStoreDB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eventstoredb_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/mongodb_metrics/"&gt;MongoDB&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mongodb_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/nginx_metrics/"&gt;NGINX&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nginx_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/postgresql_metrics/"&gt;PostgreSQL&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;postgresql_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/host_metrics/"&gt;Vector host metrics&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;host_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vector.dev/docs/reference/configuration/sources/internal_metrics/"&gt;Vector internal metrics&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;internal_metrics&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can also use Vector Remap Language to &lt;a href="https://vector.dev/docs/reference/configuration/transforms/log_to_metric/"&gt;convert logs to metrics&lt;/a&gt;. Allowing you to extract and track valuable metrics like error type or user login count directly from your app's logs!&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with AppSignal and Vector
&lt;/h2&gt;

&lt;p&gt;AppSignal makes monitoring your Vector sources a breeze.&lt;/p&gt;

&lt;p&gt;Just make sure you're using Vector version &lt;code&gt;0.33.0&lt;/code&gt; or higher, as older versions do not come with the sink required to send your monitoring data to AppSignal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending Logs to AppSignal with Vector
&lt;/h3&gt;

&lt;p&gt;You can use Vector to send logs from &lt;a href="https://vector.dev/docs/reference/configuration/sources/"&gt;Vector sources&lt;/a&gt; like Docker or Kubernetes to AppSignal.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, you need to add a new &lt;a href="https://docs.appsignal.com/vector.html#logs"&gt;log source&lt;/a&gt; to your app in AppSignal.&lt;/li&gt;
&lt;li&gt;Once you've created a new log source, configure Vector to send logs to AppSignal, for example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# vector.toml config file example&lt;/span&gt;
&lt;span class="nn"&gt;[sources.my_kubernetes_logs_source]&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"kubernetes_logs"&lt;/span&gt;

&lt;span class="nn"&gt;[sinks.appsignal]&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"appsignal"&lt;/span&gt;
&lt;span class="py"&gt;inputs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"my_kubernetes_logs_source"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;push_api_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Your app-level Push API key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Please note:&lt;/strong&gt; Some Vector sources may require additional configuration; this will be outlined in the Vector's Source documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending Metrics to AppSignal with Vector
&lt;/h3&gt;

&lt;p&gt;To start sending Vector source metrics to AppSignal, you'll have to configure Vector to report metrics from your chosen source. For example, to send Apache HTTPD server metrics you'd write the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# vector.toml config file example&lt;/span&gt;
&lt;span class="nn"&gt;[sources.my_apache_metrics_source]&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"apache_metrics"&lt;/span&gt;
&lt;span class="py"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:8080/server-status/?auto"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[sinks.appsignal]&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"appsignal"&lt;/span&gt;
&lt;span class="py"&gt;inputs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"my_apache_metrics_source"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;push_api_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Your app-level Push API key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To track custom metrics from a source like StatsD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# vector.toml config file example&lt;/span&gt;
&lt;span class="nn"&gt;[sources.my_statsd_source]&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"statsd"&lt;/span&gt;
&lt;span class="py"&gt;address&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0:9000"&lt;/span&gt;
&lt;span class="py"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tcp"&lt;/span&gt;
&lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/path/to/socket"&lt;/span&gt;

&lt;span class="nn"&gt;[sinks.appsignal]&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"appsignal"&lt;/span&gt;
&lt;span class="py"&gt;inputs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"my_statsd_source"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;push_api_key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Your app-level Push API key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tracking metrics with AppSignal
&lt;/h2&gt;

&lt;p&gt;You can track all of the Vector source metrics you send to AppSignal via Custom graphs. Simply create or navigate to an existing dashboard and select &lt;code&gt;Add graph&lt;/code&gt;; you can then create a line, area, or relative graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eTWKEYWD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-12/custom-metrics-create-graph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eTWKEYWD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-12/custom-metrics-create-graph.png" alt="Creating a graph with custom metrics" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Logs with AppSignal
&lt;/h2&gt;

&lt;p&gt;AppSignal's Log Management allows you to manage your vector source logs easily.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/783666526" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Gain deep insights into your code's performance by combining your APM and log management.&lt;/p&gt;

&lt;p&gt;With AppSignal's intuitive UI, you can navigate from an error message to a log line in just a few clicks and query, filter, and share logs effortlessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detecting Anomalies with AppSignal
&lt;/h2&gt;

&lt;p&gt;Anomaly detection lets you define the boundaries of what you consider to be good performance in your application and notifies you when and where metrics go over their limits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DApWieJS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-12/create-anomaly-triggers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DApWieJS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-12/create-anomaly-triggers.png" alt="Screenshot of trigger creation" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, you can create custom triggers to alert you if your MongoDB &lt;code&gt;memory&lt;/code&gt; metric increases by a certain amount within a specific timeframe, giving you the time to solve problems before they become performance bottlenecks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ready to Power-up Your Performance Insights?
&lt;/h2&gt;

&lt;p&gt;Once you've configured Vector to send source metrics and logs to AppSignal, you should be able to begin inspecting log lines and visualizing performance in a matter of minutes.&lt;/p&gt;

&lt;p&gt;You can start with Vector by following the &lt;a href="https://docs.appsignal.com/vector.html"&gt;Vector configuration documentation&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSignal, The Awesome APM
&lt;/h2&gt;

&lt;p&gt;AppSignal is built by developers for developers to give you the visibility and insights needed to manage and scale your application effectively. As well as Vector support AppSignal offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A 360-degree view of your application data.&lt;/li&gt;
&lt;li&gt;An intuitive interface that's easy to navigate.&lt;/li&gt;
&lt;li&gt;A clean approach to connecting errors, logs, and performance incidents.&lt;/li&gt;
&lt;li&gt;The ability to monitor your Node.js, front-end JavaScript, Ruby, Elixir, and Python applications in one place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're a new trial user, &lt;a href="//mailto:support@appsignal.com"&gt;reach out&lt;/a&gt; to us once you've got your application set up with AppSignal, and we'll send a package of stroopwaffles to you 🍪!&lt;/p&gt;

</description>
      <category>apm</category>
      <category>monitoring</category>
      <category>vector</category>
    </item>
    <item>
      <title>Monitor Solid Cache in Rails with AppSignal</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Wed, 06 Dec 2023 11:25:51 +0000</pubDate>
      <link>https://dev.to/appsignal/monitor-solid-cache-in-rails-with-appsignal-35e6</link>
      <guid>https://dev.to/appsignal/monitor-solid-cache-in-rails-with-appsignal-35e6</guid>
      <description>&lt;p&gt;AppSignal now supports Solid Cache, giving you the same deep cache performance insights you'd get from other Rails cache stores.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll give you a quick tour of Solid Cache, and how you can benefit from monitoring your app's cache with AppSignal.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Solid Cache?
&lt;/h2&gt;

&lt;p&gt;Plug and play, database agnostic remote disk storage cache, meaning unlike Redis or Memcached, which are memory stored, Solid Cache uses a SQL database through Active Record, keeping your cache on disk.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ㅤ&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Local&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Remote&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;MemoryStore &lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;
&lt;li&gt;RedisCacheStore&lt;/li&gt;
&lt;li&gt;MemCachedStore&lt;/li&gt;
&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Disk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;FileStore&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;td&gt;&lt;ul&gt;&lt;li&gt;SolidCacheEntries Table&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Solid Cache might be a favorable caching method if you work with an application with a large quantity of relatively stable historical data, like Hey, 37Signal's email service, as besides new mail, previous emails aren't going to change suddenly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring Solid Cache with AppSignal
&lt;/h2&gt;

&lt;p&gt;AppSignal was born in the Netherlands, a country known for its windmills, canals, stroopwaffles, and of course, rain. So much rain. Knowing when it's going to rain is very important when a bike is your primary mode of transport, so we've created a Rails app called &lt;code&gt;SkySignal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;SkySignal connects to APIs to consume weather data from across the Netherlands, letting people know if it will rain in their location and helping developers stay dry while being DRY 🥁.&lt;/p&gt;

&lt;p&gt;Like Hey, we want to optimize our application's response times by using caching to serve the weather forecast to our users quickly. We will use Solid Cache to cache historic weather data in this case.&lt;/p&gt;

&lt;p&gt;We're opting for Solid Cache here for the same reasons Hey did; it allows us to cache large amounts of data for a fraction of the cost of using an alternative cache, like Redis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Solid Cache
&lt;/h3&gt;

&lt;p&gt;Installing Solid Cache is easy, we'll follow the steps outlined in &lt;a href="https://github.com/rails/solid_cache#usage"&gt;Solid Cache's Readme&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we need to configure Solid Cache as our cache store in our desired env config files:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache_store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:solid_cache_store&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Then we need to add &lt;code&gt;solid_cache&lt;/code&gt; to our gemfile.&lt;/li&gt;
&lt;li&gt;Then we need to create, and run Solid Cache migrations to create our database cache:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails solid_cache:install:migrations
rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we want to write our cache to our primary database, but if you want, you can also configure Solid Cache to shard your cache into different data stores. Sharding breaks down your cache into smaller parts and distributes them across different databases (shards).&lt;/p&gt;

&lt;p&gt;Next, we want to install AppSignal to monitor our app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing AppSignal
&lt;/h3&gt;

&lt;p&gt;Installing AppSignal is simple; we've created an installation wizard to get you up and monitoring.&lt;/p&gt;

&lt;p&gt;To start the wizard, you can click the "Add app" button on the AppSignal Applications overview page, or if you are signed in, you can use this link to start the wizard.&lt;/p&gt;

&lt;p&gt;The wizard will let you know once AppSignal has successfully installed, and in the rare event things go wrong, hand you over to our &lt;a href="//support@appsignal.com"&gt;support&lt;/a&gt; for some dev-to-dev assistance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FQde-ABi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-wizard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FQde-ABi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-wizard.png" alt="Wizard installation screen" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to install AppSignal manually, follow our &lt;a href="https://docs.appsignal.com/ruby/installation.html#installing-the-gem"&gt;Installation Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we've installed AppSignal; we can begin monitoring the SkySignal app's performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring Solid Cache
&lt;/h2&gt;

&lt;p&gt;AppSignal collects your application's performance metrics and translates them into actionable insights. AppSignal has a large toolkit of developer-friendly monitoring tools, but for this blog post, we'll focus on the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Metric dashboards:&lt;/strong&gt; Visually track your app's performance data, like error rates and global response times. For SkySignal, we'll look at our cache size and performance times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anomaly detection:&lt;/strong&gt; Create triggers to alert you when a metric exceeds a specific threshold, for example, when our cache size increases significantly within a short time frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oh, and don't worry if you don't use Solid Cache; no matter your Rails cache store, you'll get the same great metrics in AppSignal!&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring Solid Cache with Dashboards
&lt;/h3&gt;

&lt;p&gt;AppSignal's graphs are a great way of visually monitoring your application's performance. You can add markers to share context about performance spikes and click anywhere on the graph to see a snapshot of your application's performance at that exact moment in time, making debugging a breeze.&lt;/p&gt;

&lt;h4&gt;
  
  
  Monitoring Response Times
&lt;/h4&gt;

&lt;p&gt;Let's look at our app's performance now that we've configured Solid Cache:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JHVfIA0Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-response-time.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JHVfIA0Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-response-time.png" alt="Response time graph" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the graph above, we can see SkySignal has relatively fast response times, and we can also see response time spikes caused by SkySignal consuming batches of new weather data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Monitoring Cache Size
&lt;/h4&gt;

&lt;p&gt;We've opted to use caching as a stable, efficient way of enhancing our response times by storing large amounts of data in our remote disk cache.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rrt6Dphg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-cache-size.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rrt6Dphg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-cache-size.png" alt="Cache size graph" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To ensure our cache is optimal, we can track our cache size, see if it's spiking quickly, and use this data to fine-tune our cache configuration to ensure it's optimal for our application's needs.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://blog.appsignal.com/2022/02/03/how-to-keep-database-table-sizes-down-and-prevent-data-bloat.html"&gt;this blog post&lt;/a&gt; for more information on setting up a dashboard tracking your Solid Cache table size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Detecting Cache Anomalies with AppSignal
&lt;/h3&gt;

&lt;p&gt;While AppSignal's dashboards are an elegant and intuitive way to keep tabs on our application's performance. Sadly, we can't spend all day looking at AppSignal's beautiful graphs; this is where Anomaly Detection comes in.&lt;/p&gt;

&lt;p&gt;AppSignal's Anomaly Detection allows you to create triggers that notify you to let you know if a specific metric threshold has been met, for example, the error rate has gone above 10%, or your cache storage is being used up too quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WGaPpIEd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-trigger.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WGaPpIEd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/solid-cache-trigger.png" alt="Creating a trigger" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anomaly detection allows you to get on with your job. You can configure AppSignal to notify you via email or popular third-party collaboration platforms like Slack and Discord, giving you the peace of mind that you'll be alerted if a trigger is triggered, and monitor your application proactively, preventing bottlenecks before they impact the performance and scalability of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ready to Start Monitoring Your App's Cache?
&lt;/h2&gt;

&lt;p&gt;At AppSignal, we strive to be awesome at everything we do; that's why we work hard to ensure we support all the latest Rails features and functionality.&lt;/p&gt;

&lt;p&gt;When we ask our customers why they find AppSignal awesome, they tell us they like our:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An intuitively easy-to-navigate interface.&lt;/li&gt;
&lt;li&gt;Simple and predictable pricing.&lt;/li&gt;
&lt;li&gt;Developer-to-developer support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're not already an AppSignal customer &lt;a href="https://appsignal.com/users/sign_up"&gt;click here&lt;/a&gt; to create a new trial account. If you're a new trial user, reach out to us once you begin pushing monitoring data, and we'll send a package of Stroopwaffles to you 🍪!&lt;/p&gt;

&lt;p&gt;Want to learn more about Solid Cache? We recommend &lt;a href="https://www.youtube.com/watch?v=wYeVne3aRow"&gt;watching Donal McBreen's Rails World talk on YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>solidcache</category>
    </item>
    <item>
      <title>We've Levelled up Our Top Monitoring Features</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Tue, 14 Nov 2023 12:57:44 +0000</pubDate>
      <link>https://dev.to/appsignal/weve-levelled-up-our-top-monitoring-features-bcj</link>
      <guid>https://dev.to/appsignal/weve-levelled-up-our-top-monitoring-features-bcj</guid>
      <description>&lt;p&gt;We've improved our core features to help you debug issues more efficiently and effectively.&lt;/p&gt;

&lt;p&gt;This article will walk you through the changes we've made to our Error Tracking, Performance Monitoring, Anomaly Detection, and Log Incidents features that enable you to gain the insights you need to dive deep into issues quicker than ever before.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Beautiful Overview of Your Errors
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TBJt6Fn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/incidents-error-overview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TBJt6Fn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/incidents-error-overview.png" alt="Error sample search" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've created new, easy-to-read error overview pages with a summary of your error and the ability to explore its occurrences.&lt;/p&gt;

&lt;p&gt;It is now even easier to dive into a new debugging session with all the vital information you need merely one click away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error Sample Search
&lt;/h3&gt;

&lt;p&gt;You can now search and filter error samples to help you quickly find specific deployment occurrences, search for specific users, or for samples that include custom tags. It's never been easier to find the sample data you need!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ueOCkrJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/incidents-error-search.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ueOCkrJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/incidents-error-search.png" alt="Error sample search" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Error Attribute Distributions
&lt;/h3&gt;

&lt;p&gt;With the introduction of error attribute distributions, you can quickly figure out important details like who experiences this error, how often it occurs, and if it's unique to a particular browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  New Logbook Features
&lt;/h3&gt;

&lt;p&gt;You can now pin important comments to the top of the logbook, allowing you to ensure key knowledge is always at hand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9xRlc7fh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/incidents-pinned-log-book.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9xRlc7fh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/incidents-pinned-log-book.png" alt="The re-designed Error Overview" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Monitoring
&lt;/h2&gt;

&lt;p&gt;AppSignal's Performance Monitoring helps you spot where and when your application is slow to respond.&lt;/p&gt;

&lt;p&gt;We've added even more tools to Performance Monitoring to help you quickly identify slow queries and combat performance perils!&lt;/p&gt;

&lt;h3&gt;
  
  
  An Overview of the Latest Samples
&lt;/h3&gt;

&lt;p&gt;The new overview tab provides a quick overview of the last saved performance samples, which includes a deploys table with an overview of the performance per deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Samples Table
&lt;/h3&gt;

&lt;p&gt;Quickly query and filter performance samples with data such as creation date, duration, request ID, and hostname.&lt;/p&gt;

&lt;p&gt;You can save time and easily find the information you need to evaluate performance issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Page Redesign
&lt;/h3&gt;

&lt;p&gt;We've re-vamped the entire sample page and added a more user-friendly event timeline featuring fullscreen mode, making it possible to monitor your application from your coffee machine or anywhere you can hang a screen!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HrMgXN_w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/performance-samples.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HrMgXN_w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/performance-samples.png" alt="New performance samples" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Anomaly Detection
&lt;/h2&gt;

&lt;p&gt;With AppSignal Anomaly Detection, you can create metric triggers to alert you when specific conditions are met. For example, when disk space rises above 90% or a queue has more than 1000 jobs.&lt;/p&gt;

&lt;p&gt;We've enhanced our Anomaly incidents with additional layers of insights, providing you with the clarity needed to resolve them.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://share.vidyard.com/watch/bSzbeV47TKCmRik7SUtWP5" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y5z4sdl8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://play.vidyard.com/bSzbeV47TKCmRik7SUtWP5.jpg%3F" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://share.vidyard.com/watch/bSzbeV47TKCmRik7SUtWP5" rel="noopener noreferrer" class="c-link"&gt;
          Anomaly update
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Vidyard video
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--6zYlX82l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.vidyard.com/hubs/favicons/6ce6ee27-175e-49d4-b91b-3628427e0016.ico" width="48" height="48"&gt;
        share.vidyard.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Issues Layer
&lt;/h3&gt;

&lt;p&gt;The new issues layer lets you quickly understand an alert's state, frequency, and urgency.&lt;/p&gt;

&lt;p&gt;An issue is created per trigger occurrence. For example, if you set a trigger for when disk space exceeds 90%, we'll create a new issue for every server where this happens.&lt;/p&gt;

&lt;p&gt;This change tidies up your anomaly detection table and doesn't bury important alerts. All trigger issue occurrences are saved and accessible under "Occurrences", which you can access by navigating to your Trigger, then to &lt;code&gt;Multiple issues&lt;/code&gt; → &lt;code&gt;Occurrences&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alert Overview
&lt;/h3&gt;

&lt;p&gt;The alert overview has been redesigned to allow you to quickly understand the state of all of your alerts.&lt;/p&gt;

&lt;p&gt;The overview now features the metric data and tags that triggered the alert alongside each alert's most recent logbook activity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Occurrence Detail
&lt;/h3&gt;

&lt;p&gt;You can now view a more detailed overview of alert occurrences.&lt;/p&gt;

&lt;p&gt;With an easy-to-understand timeline of events, you can quickly infer when the alert was triggered and how long it spent in each alert phase from &lt;em&gt;warm up&lt;/em&gt; to &lt;em&gt;cool down&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---aOPuNPx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/anomaly-alert.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---aOPuNPx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/anomaly-alert.png" alt="New anomaly alert incident overview" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Log Incidents
&lt;/h2&gt;

&lt;p&gt;With Log Triggers, you can be notified when specific logging activity occurs, for example, when a logline matches specific data.&lt;/p&gt;

&lt;p&gt;Each log incident has a dedicated logging overview page with the same usability and data insights as you would with our performance incidents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--76-xT8um--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/log-incident.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--76-xT8um--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-11/log-incident.png" alt="New anomaly alert incident overview" width="800" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSignal, The Awesome APM
&lt;/h2&gt;

&lt;p&gt;At AppSignal, we strive to be awesome at everything we do; that's why we work hard to ensure our core features are the best they can be. When we ask our customers why they find AppSignal awesome, they tell us they like our:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An intuitively easy-to-navigate interface.&lt;/li&gt;
&lt;li&gt;Simple and predictable pricing.&lt;/li&gt;
&lt;li&gt;Developer-to-developer support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are a new trial user, you can also get a free box of stroopwafels. Once you start pushing some data, &lt;a href="//mailto:support@appsignal.com"&gt;reach out to us&lt;/a&gt;, and we'll send a package to you 🍪!&lt;/p&gt;

</description>
      <category>appsignal</category>
      <category>apm</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>AppSignal Monitoring Available for Python Applications</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Tue, 07 Nov 2023 13:01:49 +0000</pubDate>
      <link>https://dev.to/appsignal/appsignal-monitoring-available-for-python-applications-26a8</link>
      <guid>https://dev.to/appsignal/appsignal-monitoring-available-for-python-applications-26a8</guid>
      <description>&lt;p&gt;We're happy to announce that &lt;a href="https://www.appsignal.com/python"&gt;AppSignal now offers monitoring tools for Python projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;AppSignal helps you get the most out of your Python application's monitoring metrics, with additional support for multiple Python frameworks and packages such as Django and Celery.&lt;/p&gt;

&lt;p&gt;In this article, we'll walk you through some of our core features to show you how to power up your Python application with AppSignal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring Support for Popular Python Libraries
&lt;/h2&gt;

&lt;p&gt;AppSignal already supports various popular Python libraries, which will only expand with time! We currently offer support for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Celery&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;FastAPI&lt;/li&gt;
&lt;li&gt;Flask&lt;/li&gt;
&lt;li&gt;Jinja2&lt;/li&gt;
&lt;li&gt;Psycopg2&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;Requests&lt;/li&gt;
&lt;li&gt;Starlette&lt;/li&gt;
&lt;li&gt;WSGI/ASGI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is there a Python package we don't support? &lt;a href="//mailto:support@appsignal.com"&gt;Reach out to us&lt;/a&gt;, and we'll investigate it further with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Monitoring
&lt;/h2&gt;

&lt;p&gt;AppSignal is a tool that tells you when, why, and where errors occur in your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1Lm5oLO8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-error-detail.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1Lm5oLO8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-error-detail.png" alt="Screenshot of Python error" width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AppSignal can be configured to track errors per deployment, and tools like Time Detective give you a helicopter view of your application. When an error occurs, you can connect the dots and spend more time solving problems rather than speculating over them.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/809749481" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;AppSignal gives you control of when and where you're notified about errors in your application, whether that's on Slack or Discord; you can even connect AppSignal to popular collaboration tools like GitHub and Jira and leave crucial contextual information about an error in the Logbook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Monitoring
&lt;/h2&gt;

&lt;p&gt;AppSignal monitors your application and tells you when its performance is suboptimal. Spot and fix performance bottlenecks so you can scale your app with confidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yCOmFMDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-performance-monitoring.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yCOmFMDq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-performance-monitoring.png" alt="Screenshot of Python error" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our intuitive UI helps you see where and when performance problems arise, with all the critical insights you need at your fingertips to choose the best resolution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anomaly Detection
&lt;/h2&gt;

&lt;p&gt;Anomaly detection lets you define the boundaries of what you consider to be good performance in your application and notifies you when and where metrics go over their limits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZXOab4TI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-anomalies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZXOab4TI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-anomalies.png" alt="Screenshot of Python anomaly detection" width="800" height="846"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create custom triggers to alert you when performance dips, background job count increases by 20%, or memory suddenly increases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iBhW2NIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-anomalies-triggers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iBhW2NIb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-anomalies-triggers.png" alt="Screenshot of Python triggers" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AppSignal gives you the data-driven confidence to act proactively instead of urgently reacting to issues in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Host Monitoring
&lt;/h2&gt;

&lt;p&gt;AppSignal also monitors your Python application's hosts, giving you at-a-glance access to CPU, disk, network, and memory metrics. This allows you to understand how your Python application is performing beyond just looking at its code. Effectively manage and monitor your hosts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ztn7wMkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-hosts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ztn7wMkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-hosts.png" alt="Screenshot of host metrics" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Python Dashboards
&lt;/h2&gt;

&lt;p&gt;AppSignal's dashboards give you instant visual insights into your application's metrics, allowing you to track and trace performance metrics quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d312ps3f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-metric-dashboards.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d312ps3f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-10/python-metric-dashboards.png" alt="Screenshot of metric dashboard" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you see something you want to investigate further, click on that point on the chart, and you'll view the state of your application at that specific point in time. Add custom markers to help you and your team better understand how your application performs.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/852943845" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  More Than Just Monitoring
&lt;/h2&gt;

&lt;p&gt;AppSignal can ingest and store logs from popular platforms such as AWS Kinesis, Heroku, and Netlify or via our dedicated logging API endpoint. Gain deep insights into your code's performance by combining your APM and log management.&lt;/p&gt;

&lt;p&gt;Our intuitive UI takes you from an error message to a log line in just a few clicks and lets you query, filter, and share logs effortlessly.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/783666526" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Effortless Setup, Immediate Impact
&lt;/h2&gt;

&lt;p&gt;You can have your Python application push metrics to AppSignal in less time than it takes to drink a coffee.&lt;/p&gt;

&lt;p&gt;Sign up for an AppSignal account and follow our &lt;a href="https://appsignal.com/redirect-to/organization?to=sites/new/python"&gt;installation wizard instructions&lt;/a&gt;. The installation wizard will walk you through all the steps needed to send metrics from your Python application to AppSignal!&lt;/p&gt;

&lt;p&gt;Our &lt;a href="https://docs.appsignal.com/python"&gt;Python documentation&lt;/a&gt; will also take you through all the steps required to get the metrics you need, including how you can install AppSignal manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSignal: Your Python APM Tool
&lt;/h2&gt;

&lt;p&gt;AppSignal is built by developers for developers to give you the visibility and insights needed to manage and scale your Python application effectively. AppSignal offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A 360-degree view of your application data.&lt;/li&gt;
&lt;li&gt;An intuitive interface that's easy to navigate.&lt;/li&gt;
&lt;li&gt;A clean approach to connecting errors, logs, and performance incidents.&lt;/li&gt;
&lt;li&gt;The ability to monitor your Node.js, front-end JavaScript, Ruby, Elixir, and Python applications in one place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're a new trial user, &lt;a href="//mailto:support@appsignal.com"&gt;reach out to us&lt;/a&gt; once you've got your Python application set up with AppSignal, and we'll send a package of stroopwafels to you 🍪!&lt;/p&gt;

</description>
      <category>python</category>
      <category>apm</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Boost HTTP Client Monitoring in Elixir with AppSignal and Tesla Templates</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Tue, 18 Jul 2023 11:05:41 +0000</pubDate>
      <link>https://dev.to/appsignal/boost-http-client-monitoring-in-elixir-with-appsignal-and-tesla-templates-5491</link>
      <guid>https://dev.to/appsignal/boost-http-client-monitoring-in-elixir-with-appsignal-and-tesla-templates-5491</guid>
      <description>&lt;p&gt;When relying on data from external services, it's important for the retrieval to be accurate and timely. While we may not control how efficiently an external API responds to our requests, we can control how and when we request data from that API. However, over time as your application and the API that serves it change, once efficient requests may turn into bottlenecks.&lt;/p&gt;

&lt;p&gt;In this article, we'll demonstrate how you can leverage AppSignal's new Tesla integration to monitor your Elixir application's HTTP client performance and use this data to positively influence its architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Templating with Tesla
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To implement what is covered in the post, you will need AppSignal for Elixir 2.7.3 or higher and Tesla 1.4.3 or higher.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's imagine you manage an application that ships stroopwafels around the world. To do this, your application connects with a dedicated Stroopwafels courier, &lt;em&gt;Strooperoo&lt;/em&gt;, using its API to create, update, and track deliveries, with requests structured as follows:&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;# Create a new delivery&lt;/span&gt;
POST https://strooperoo.com/deliveries/create/

&lt;span class="c"&gt;# Update an existing delivery&lt;/span&gt;
POST https://strooperoo.com/deliveries/:delivery_id/update

&lt;span class="c"&gt;# Retrieve the status of a delivery&lt;/span&gt;
GET https://strooperoo.com/deliveries/:delivery_id/status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say you've noticed some issues in your application's performance, especially when retrieving a delivery status. Luckily, you're using AppSignal, so you can investigate this further by checking the application's slow API requests.&lt;/p&gt;

&lt;p&gt;Typically, AppSignal will group slow API requests by their base URL. In our case, all of the following requests would be grouped under the base URL &lt;code&gt;https://strooperoo.com/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://strooperoo.com/deliveries/create/
https://strooperoo.com/deliveries/1971/update
https://strooperoo.com/deliveries/1971/status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful in deducing that the HTTP client is slow but doesn't help us immediately pinpoint which requests are problematic.&lt;/p&gt;

&lt;p&gt;However, with Tesla, AppSignal can group your requests beyond their base URL. This is because Tesla allows you to use URL templates enabling AppSignal to understand how a request was built:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;StrooperooAPI&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Tesla&lt;/span&gt;

  &lt;span class="n"&gt;plug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Tesla&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Telemetry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;plug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Tesla&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PathParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;delivery_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;delivery_id:&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;"https://strooperoo.com/deliveries/:delivery_id/status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;opts:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;path_params:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in the above example, we know you're making a request to the &lt;code&gt;status&lt;/code&gt; endpoint, and can apply the appropriate grouping.&lt;/p&gt;

&lt;p&gt;Which means that in AppSignal, instead of seeing slow API requests grouped like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4E1U4jn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-06/slow-api-request.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q4E1U4jn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-06/slow-api-request.png" alt="Slow API requests sorted by impact" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll see requests grouped accurately like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z2oFV4cG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-06/slow-api-request-tesla.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z2oFV4cG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-06/slow-api-request-tesla.png" alt="Slow API requests sorted by impact, showing URL template" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tesla makes your HTTP client monitoring data &lt;em&gt;way more valuable&lt;/em&gt; as you can now quickly deduce how your application's HTTP client is performing on a request level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wait a Minute, Why Can’t You Do This with Other HTTP Clients!?
&lt;/h3&gt;

&lt;p&gt;Good question. That's because Tesla's templating lets us understand how your request is built. With other HTTP clients, we get a URL string such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://api.wow.com/api/versions/4/users/14383/comments/page/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's very tricky to understand, just from a string, what this request is doing and which elements of the request are parameters. Tesla's templating removes that guesswork for us and allows us to accurately group requests by telling us exactly what parameters are in the request URL. Neat, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving Slow Requests
&lt;/h2&gt;

&lt;p&gt;Looking at our slow API requests, we can now see that requests to &lt;code&gt;/status&lt;/code&gt; perform poorly. So let's investigate the application's &lt;code&gt;delivery_status&lt;/code&gt; logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;delivery_status&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;deliveries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Delivery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deliveries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;delivery&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="no"&gt;StrooperooAPI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delivery_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delivery&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;conn&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;put_flash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Delivery status updated"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="s2"&gt;"/deliveries"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are making many requests synchronously. When we first created the application, we were only managing a small number of deliveries, so we didn't experience any issues. But now, we're managing thousands of deliveries. This means that thousands of synchronous requests are being made every single time someone presses the "sync" button in the application.&lt;/p&gt;

&lt;p&gt;One way we can better handle this is by running the code asynchronously in a scheduled background job using Oban:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;DeliveryStatusJob&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Oban&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Job&lt;/span&gt;

  &lt;span class="nv"&gt;@impl&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_job&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;deliveries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Delivery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deliveries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;delivery&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="no"&gt;StrooperooAPI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delivery_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delivery&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AppSignal supports Oban monitoring, so we'll be able to monitor the performance of our Oban job too!&lt;/p&gt;

&lt;h2&gt;
  
  
  More than Just Monitoring
&lt;/h2&gt;

&lt;p&gt;This is just one of many examples of how monitoring your application with AppSignal can help you make data-driven decisions, in this case, thanks to Tesla's unique templating functionality. You can learn more about utilizing your Tesla HTTP client with AppSignal in our &lt;a href="https://docs.appsignal.com/elixir/integrations/tesla.html"&gt;Tesla documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;AppSignal's slow API request monitoring is just one of our many developer-driven features that help you get the most out of monitoring your application. Developers also enjoy using our monitoring because we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An intuitive interface that is easy to navigate.&lt;/li&gt;
&lt;li&gt;Simple and predictable pricing.&lt;/li&gt;
&lt;li&gt;Developer-to-developer support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you experience any issues when using AppSignal for Elixir or Tesla, our &lt;a href="//support@appsignal.com"&gt;support team&lt;/a&gt; is on hand to help! And remember, if you're new to AppSignal, we'll welcome you onboard with an exceptionally delicious shipment of stroopwafels 🍪 😋&lt;/p&gt;

</description>
      <category>apm</category>
      <category>tesla</category>
      <category>elixir</category>
    </item>
    <item>
      <title>Monitoring Your Elixir GraphQL API with AppSignal</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Tue, 11 Jul 2023 10:51:18 +0000</pubDate>
      <link>https://dev.to/appsignal/monitoring-your-elixir-graphql-api-with-appsignal-3pm7</link>
      <guid>https://dev.to/appsignal/monitoring-your-elixir-graphql-api-with-appsignal-3pm7</guid>
      <description>&lt;p&gt;While a GraphQL API may be less susceptible to the common REST API performance issues of under and over-fetching data, allowing users to request and receive a wide range of data in a single, nestable query can also come with performance risks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.appsignal.com/elixir"&gt;AppSignal for Elixir&lt;/a&gt; now supports Absinthe out of the box, and automatically adds Absinthe spans to your app's metrics. AppSignal also automatically instruments Ecto, giving you insights into your application's queries. When combined, AppSignal can be used to gain insights into how queries passed to the GraphQL endpoint translate to the database.&lt;/p&gt;

&lt;p&gt;This blog post will explore how you can use both AppSignal's Absinthe and Ecto integrations to monitor and fine-tune your GraphQL API.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Request To Response
&lt;/h2&gt;

&lt;p&gt;Unlike a REST API which has data-specific endpoints, the flexibility of a GraphQL API means requests must go through several steps to return the expected information:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Parsing and Validating&lt;/td&gt;
&lt;td&gt;The server parses the request and checks that it is in a valid format.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query Execution&lt;/td&gt;
&lt;td&gt;Root and field resolvers fetch the requested data from the application's database.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transforming and Responding&lt;/td&gt;
&lt;td&gt;The fetched data is transformed, allowing your API to return an array of meaningful data rather than relational IDs. The transformed data is then structured according to the request query. &lt;br&gt;&lt;br&gt;Any errors that occurred while executing and transforming the query will also be included in the response.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response Delivery&lt;/td&gt;
&lt;td&gt;The requested data is delivered in JSON format to the client — it includes all requested data, appropriately formatted, as well as any error messages.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To take full advantage of the performance benefits of a GraphQL API, your application must be able to parse, query, and transform data efficiently, especially when receiving more complex requests that have nested queries or require higher levels of data transformation.&lt;/p&gt;

&lt;p&gt;AppSignal's Absinthe and Ecto integrations assist in monitoring the performance of your application's parsing, querying, and data transformation. They provide clear insights, on an event level, of exactly how your API is responding to requests — enabling you to quickly identify areas where optimizations are needed for specific requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring GraphQL via Absinthe
&lt;/h3&gt;

&lt;p&gt;AppSignal automatically recognizes operations executed by Absinthe and wraps them into a &lt;code&gt;call.graphql&lt;/code&gt; event on your Event Timeline, allowing you to see how much time Absinthe spends parsing, querying, and transforming data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WG9XMNfE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-05/event-timeline-absinthe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WG9XMNfE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-05/event-timeline-absinthe.png" alt="Event timeline showing GraphQL events" width="800" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;call.graphql&lt;/code&gt; is taking up a large portion of the event timeline, this could indicate it is having trouble parsing a request or transforming data. Often, this is due to deeply nested requests or querying modules that have high levels of relational data.&lt;/p&gt;

&lt;p&gt;For example, let's say we have a GraphQL API that returns all courses, exam results, and lecturers for a student. This query requires nesting and several data transformations. If your application is taking a long time to execute GraphQL logic, it may be an indication that you need to take steps such as refactoring resolver logic, data fetching strategies, or implementing caching mechanisms for frequently requested data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring Ecto
&lt;/h3&gt;

&lt;p&gt;With AppSignal's Ecto integration, you can see how long it takes for Ecto queries to be executed in your application's requests, displaying them in the Event Timeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Khp1TF_H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-05/event-timeline-ecto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Khp1TF_H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-05/event-timeline-ecto.png" alt="Event timeline showing Ecto events" width="800" height="762"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can investigate Ecto's performance in slow requests and apply suitable strategies to enhance performance when necessary, such as caching, query optimization, and indexing for large nested data sets. You could also implement pagination, rate, and depth limiting to limit the amount of data requested within reasonable bounds and limit the frequency and complexity of incoming queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Going with GraphQL and AppSignal
&lt;/h2&gt;

&lt;p&gt;Absinthe and Ecto are automatically instrumented and available in AppSignal 2.7.0 or higher. For Ecto, you need to ensure that the value of &lt;code&gt;:otp_app&lt;/code&gt; in your &lt;code&gt;appsignal.exs&lt;/code&gt; configuration matches your application's app name.&lt;/p&gt;

&lt;p&gt;Once correctly configured, AppSignal will automatically display GraphQL and Ecto events in your Event Timeline, giving you effortless insights into two of your API's most important components.&lt;/p&gt;

&lt;p&gt;You can learn more about configuring Absinthe and Ecto in our &lt;a href="https://docs.appsignal.com/elixir/integrations.html"&gt;Elixir integration documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delve Deeper into Absinthe and Ecto
&lt;/h2&gt;

&lt;p&gt;If you enjoyed this blog post, you'll enjoy some of our recent related blog posts on Absinthe and Ecto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.appsignal.com/2023/05/16/an-introduction-to-absinthe-for-elixir.html"&gt;An Introduction to Absinthe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.appsignal.com/2023/05/23/tackling-performance-issues-in-ecto-applications.html"&gt;Tackling Performance Issues in Ecto Applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.appsignal.com/2023/06/06/absinthe-for-large-elixir-applications.html"&gt;Absinthe for Large Elixir Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the meantime, if you have any questions about AppSignal, please don't hesitate to &lt;a href="//mailto:support@appsignal.com"&gt;get in touch&lt;/a&gt;! We offer dev-to-dev support, give free accounts to open-source projects, and if you're new to AppSignal, we'll welcome you onboard with a delicious shipment of stroopwafels 🍪 😋&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>graphql</category>
      <category>apm</category>
    </item>
    <item>
      <title>How to Monitor Custom Metrics with AppSignal</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Thu, 04 May 2023 15:01:13 +0000</pubDate>
      <link>https://dev.to/appsignal/how-to-monitor-custom-metrics-with-appsignal-50fk</link>
      <guid>https://dev.to/appsignal/how-to-monitor-custom-metrics-with-appsignal-50fk</guid>
      <description>&lt;p&gt;Setting up custom metrics is an easy way to gain instant insights into the information you need (without sifting through log lines or struggling with complicated reporting tools). Supplement your application's critical monitoring data by tracking meaningful metrics to quickly identify and resolve potential issues.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll show you how to set up and use custom metrics to remove your monitoring blind spots. We'll demonstrate how you can use custom metrics alongside our suite of monitoring tools to better understand the performance of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Custom Metrics?
&lt;/h2&gt;

&lt;p&gt;When it comes to metrics, AppSignal by default tracks critical data such as error rates, response times, and throughput. We use these metrics to monitor your application and notify you when your application is experiencing performance issues.&lt;/p&gt;

&lt;p&gt;Custom metrics allow you to visualize and track any application data you want, providing deeper insights into your application's performance by relating additional contexts - such as active user counts or job-specific processing times. You can create dashboards in AppSignal to track custom metrics alongside critical metrics such as throughput or database size.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--shk__xr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-graph-hover.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--shk__xr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-graph-hover.png" alt="Magic Dashboard hover-over, with links to Time Detective" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring Your Metrics
&lt;/h2&gt;

&lt;p&gt;When sending your metrics to AppSignal, it's important to consider how you wish to measure them. AppSignal offers three measurement methods:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measure&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gauge&lt;/td&gt;
&lt;td&gt;A number that represents a particular value at a specific point in time that can frequently be overwritten, such as the count of an application's active users.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Counter&lt;/td&gt;
&lt;td&gt;A number you can increment by any given value, such as the count of times a process has run.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distribution&lt;/td&gt;
&lt;td&gt;A collection of numbers from which we store an average, count, or percentile. You can use this to track a spread of values in a dataset - for example, the average user cart value of an e-commerce application, or the percentage of background jobs completed within a desired time.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;AppSignal provides methods and functions to help you easily track your custom metrics using the appropriate form of measurement.&lt;/p&gt;

&lt;p&gt;Let's imagine we're monitoring a webshop. We'll show how you can use gauge, counter, and distribution measurements to track specific data points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gauge
&lt;/h3&gt;

&lt;p&gt;For context into &lt;em&gt;why&lt;/em&gt; our application may be more or less performant than usual, let's see how many active shoppers are currently using our application. We'll use the gauge measure to report an active user count every time a new user session is created in our application.&lt;/p&gt;

&lt;p&gt;To do this, we can create a minutely probe, a mechanism that sends custom metrics to AppSignal periodically. We can use this probe to record how many shopping carts have been updated within the last minute and send this information to AppSignal under the label &lt;code&gt;active_shoppers&lt;/code&gt; using the &lt;code&gt;set_gauge&lt;/code&gt; method. For example:&lt;/p&gt;

&lt;h4&gt;
  
  
  Ruby
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Minutely&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;probes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt; &lt;span class="ss"&gt;:active_shoppers_probe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;active_carts_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Carts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;updated_at: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ago&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;
  &lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_gauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_shoppers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active_carts_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can read our Ruby documentation for more information on &lt;a href="https://docs.appsignal.com/ruby/instrumentation/minutely-probes.html"&gt;minutely probes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Elixir
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Probes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:active_shoppers_probe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="no"&gt;Carts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;where:&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="no"&gt;DateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc_now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="ss"&gt;:second&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;select:&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;active_carts_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_gauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"active_shoppers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active_carts_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can read our Elixir documentation for more information on &lt;a href="https://docs.appsignal.com/elixir/instrumentation/minutely-probes.html"&gt;minutely probes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Node.js
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Appsignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;probes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;meter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;probes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;probes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;activeShoppersProbe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oneMinuteAgo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// use MongoDB to query carts table&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeCartsCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;countDocuments&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oneMinuteAgo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;$lte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;meter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setGauge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active_shoppers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeCartsCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can read our Node.js documentation for more information on &lt;a href="https://docs.appsignal.com/nodejs/3.x/instrumentation/minutely-probes.html"&gt;minutely probes&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once configured, we can create a chart in AppSignal to track how many active shoppers are using our application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UqqoZxVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-active-shoppers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UqqoZxVn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-active-shoppers.png" alt="Graph showing active shoppers metric" width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this information, we are able to quickly infer how our webshop is performing based on the approximate number of people actively using the site. If we notice a particularly high count and anticipate performance issues, we can take measures to ensure our application remains available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Counter
&lt;/h3&gt;

&lt;p&gt;With counters, we can track how often something happens in our application. This feature is handy in scenarios where you need to monitor the frequency of certain events or actions over time - for example, how many times a user completes an action, like adding an item to their cart.&lt;/p&gt;

&lt;p&gt;Let's say we'd like to understand how often our application is invoicing users. To do this, we need to increment our counter each time an invoice is created.&lt;/p&gt;

&lt;p&gt;Use the &lt;code&gt;increment_counter&lt;/code&gt; method in Ruby and Elixir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"invoice_count"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the &lt;code&gt;incrementCounter&lt;/code&gt; function in Node.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Appsignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;meter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;incrementCounter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invoice_count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once set up, we can track how many invoices our application is generating in AppSignal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JrDEtqb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-orders-invoices.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JrDEtqb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-orders-invoices.png" alt="Graph showing invoices and order metrics" width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if we track additional related data points, such as orders placed, and notice that our metrics aren't tracking against each other as expected? Then we can investigate our invoicing and ordering logic, and potentially locate and fix critical issues before they impact many of our customers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Distribution
&lt;/h3&gt;

&lt;p&gt;You can use custom metrics to record data measurements, such as response time or background job duration. Keeping track of such metrics can help you identify poorly performing background jobs or API endpoints, which can negatively impact user experience.&lt;/p&gt;

&lt;p&gt;We want to see the average time it takes for our application to run its order confirmation job, as it's vital customers receive this email within minutes of making a purchase.&lt;/p&gt;

&lt;p&gt;To do this, we use the &lt;code&gt;add_distribution_value&lt;/code&gt; method:&lt;/p&gt;

&lt;h4&gt;
  
  
  Ruby
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
&lt;span class="no"&gt;Ordering&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Confirm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;
&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

&lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_distribution_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"order_confirmation_duration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Elixir
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;system_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:millisecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Ordering&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Confirm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;system_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:millisecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;

&lt;span class="no"&gt;Appsignal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_distribution_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"order_confirmation_duration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Node.js
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Appsignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;confirmOrderStartTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;confirmOrder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;confirmOrderDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;confirmOrderStartTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;meter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addDistributionValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;order_confirmation_duration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;confirmOrderDuration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that's done, we can track the average time our confirm order job is taking to complete in AppSignal. We'll notice if it is performing slower than expected before our users do, allowing us to proactively keep our application available and scalable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZLCokYhL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-order-confirmation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZLCokYhL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-order-confirmation.png" alt="Graph showing order confirmation metric" width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Dashboards for Custom Metrics
&lt;/h2&gt;

&lt;p&gt;Thanks to our intuitive UI, you can start tracking your custom metrics in minutes.&lt;/p&gt;

&lt;p&gt;You can use the "Add dashboard" button in the Dashboard navigation to create a new dashboard. Click the "Add graph" button to start building your graphs with our Graph Builder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GXj8HxWz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-create-graph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GXj8HxWz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/custom-metrics-create-graph.png" alt="Creating a graph with custom metrics" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When creating a graph, you can select which metrics and tags you want to chart and configure your graph's legends and labels. Once that's done, you'll immediately see your graph display current metric data for the specified period of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Metrics Matter
&lt;/h2&gt;

&lt;p&gt;While logging is a fantastic solution to help you debug and troubleshoot application performance issues &lt;em&gt;after&lt;/em&gt; they've occurred, metrics can help you to prevent future issues &lt;em&gt;before&lt;/em&gt; your customers notice anything. With custom metrics, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concentrate on what matters:&lt;/strong&gt; Track specific data points in your application accurately and get focused insights without filtering through large amounts of logging metadata or incident lists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get down to business:&lt;/strong&gt; Understand your application's performance from a business perspective and quickly track critical data such as active user counts, KPIs, or daily sales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamline your logging:&lt;/strong&gt; Logging 'everything everywhere all at once' is unsustainable. With custom metrics, you can track essential data efficiently and use your logs to investigate the cause of incidents, only logging data that's necessary for troubleshooting and debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work proactively, not reactively:&lt;/strong&gt; Set custom triggers to warn you if your application takes too long to send invoices to users, for example, or is experiencing a higher volume of active users than usual. These warnings allow you to proactively investigate and resolve an issue before it impacts your customers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dive Deeper Into Custom Metrics
&lt;/h2&gt;

&lt;p&gt;Ready to get the most out of your application's metrics? This blog post has covered just a small slice of what is possible with custom metrics in AppSignal. Our &lt;a href="https://docs.appsignal.com/metrics/custom.html"&gt;documentation on custom metrics&lt;/a&gt; outlines everything you need to know.&lt;/p&gt;

&lt;p&gt;If you need help, have questions about metrics or anything else AppSignal or monitoring related, you can always &lt;a href="//mailto:support@appsignal.com"&gt;contact us&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSignal: More Than Just an APM Tool
&lt;/h2&gt;

&lt;p&gt;AppSignal's custom metrics are just one of our many developer-driven features that help you to monitor your application. Developers also enjoy using our monitoring because we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An intuitive interface that is easy to navigate.&lt;/li&gt;
&lt;li&gt;Simple and predictable pricing.&lt;/li&gt;
&lt;li&gt;Developer-to-developer support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're new to AppSignal, remember to &lt;a href="//mailto:support@appsignal.com"&gt;ask us&lt;/a&gt; for some free stroopwafels! They taste almost as good as it feels to have all of your application's metrics at your fingertips 😉🍪&lt;/p&gt;

</description>
      <category>node</category>
      <category>elixir</category>
      <category>ruby</category>
      <category>apm</category>
    </item>
    <item>
      <title>Optimize Your Prisma Queries with AppSignal and OpenTelemetry</title>
      <dc:creator>Connor </dc:creator>
      <pubDate>Tue, 25 Apr 2023 13:26:30 +0000</pubDate>
      <link>https://dev.to/appsignal/optimize-your-prisma-queries-with-appsignal-and-opentelemetry-14p1</link>
      <guid>https://dev.to/appsignal/optimize-your-prisma-queries-with-appsignal-and-opentelemetry-14p1</guid>
      <description>&lt;p&gt;AppSignal integrates seamlessly with Prisma via OpenTelemetry to give you invaluable insights into how your application is performing.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll outline how you can use AppSignal to optimize your application's Prisma integration, mitigate inefficient database queries, spot anomalies, and improve your application's scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Monitoring Prisma
&lt;/h2&gt;

&lt;p&gt;If your application handles multiple queries to fulfill a single request, it's important you ensure each query performs optimally (especially if your application has deeply nested object structures).&lt;/p&gt;

&lt;p&gt;For example, imagine an authored blog post that also allows comments from other authors. This can lead to complex, inefficient, and slow database queries. As more and more people comment on a post, the query to retrieve the blog post and related objects can become unwieldy, negatively impacting your application's performance. Joins and subqueries can further exacerbate the issue and potentially retrieve redundant information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CrPKOSlo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/prisma-object-structure-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CrPKOSlo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/prisma-object-structure-diagram.png" alt="Diagram of a blog post's nested object structure" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With AppSignal's Event Timeline, you can identify poorly performing Prisma queries and remedy them before they cause bottlenecks or impact your application's availability as it scales.&lt;/p&gt;

&lt;h2&gt;
  
  
  Metrics That Matter with AppSignal
&lt;/h2&gt;

&lt;p&gt;AppSignal provides the insights you need to help your application scale, not fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find Timeline Anomalies
&lt;/h3&gt;

&lt;p&gt;AppSignal's Event Timeline provides a clear overview of your application's performance on a request level. It shows what actions are executed by a request.&lt;/p&gt;

&lt;p&gt;This example shows how our Event Timeline interprets your application's Prisma OpenTelemetry data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xUjewvAD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2022-11/node-3-0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xUjewvAD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2022-11/node-3-0.png" alt="Event timeline" width="800" height="876"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Micro and Macro Metrics
&lt;/h3&gt;

&lt;p&gt;Clicking on a Prisma event in your event log allows you to delve deeper into your database performance. You can view charts depicting your database's response time and throughput (the number of processed events) when an event occurs.&lt;/p&gt;

&lt;p&gt;In the below graphs, multiple requests to view our blog post indicate slow database queries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PPKQwyMD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/prisma-event-charts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PPKQwyMD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.appsignal.com/images/blog/2023-04/prisma-event-charts.png" alt="Event database performance charts" width="800" height="1230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see a handy list of other application actions that involve the same event. Use this list to identify where query optimization is needed, spot potential correlations between incidents, and avoid time-consuming debugging sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending Prisma Data to AppSignal
&lt;/h2&gt;

&lt;p&gt;Thanks to OpenTelemetry, it's easy to &lt;a href="https://docs.appsignal.com/nodejs/3.x/integrations/prisma.html"&gt;integrate AppSignal and Prisma&lt;/a&gt;. First, ensure your application uses Prisma 4.2 or higher and AppSignal for Node 3.0 or higher.&lt;/p&gt;

&lt;p&gt;To automatically instrument Prisma with your AppSignal for Node.js package, enable the tracing preview feature in your Prisma schema, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;generator&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prisma-client-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;previewFeatures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tracing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once instrumented, the Prisma integration sends AppSignal a child span for each query (including child spans for the database connection and serialization process). Each query span shows the query that was performed and how long it took to complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  AppSignal 💚 OpenTelemetry
&lt;/h2&gt;

&lt;p&gt;Due to &lt;a href="https://blog.appsignal.com/2022/11/17/appsignals-future-with-open-telemetry.html"&gt;our adoption of OpenTelemetry&lt;/a&gt;, AppSignal instruments &lt;a href="https://docs.appsignal.com/nodejs/3.x/integrations.html"&gt;16 libraries and frameworks out-of-the-box&lt;/a&gt;. Get the data you need to effectively and efficiently monitor and optimize your application.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Supported Libraries and Frameworks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Express&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fastify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fs module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphQL (Apollo, Yoga)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP/HTTPs module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knex (Bookshelf)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Koa.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MongoDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mongoose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MySQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NestJS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prisma&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restify&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try AppSignal and Get Stroopwafels 🍪
&lt;/h2&gt;

&lt;p&gt;We look forward to introducing you to more open source-powered features and framework support in the future!&lt;/p&gt;

&lt;p&gt;In the meantime, if you have any questions about AppSignal, please don't hesitate to &lt;a href="//mailto:support@appsignal.com"&gt;get in touch&lt;/a&gt;! We offer dev-to-dev support, &lt;a href="https://www.appsignal.com/open-source"&gt;give free accounts to open-source projects&lt;/a&gt;, and if you're new to AppSignal, we'll welcome you onboard with a delicious shipment of stroopwafels 🍪 😋&lt;/p&gt;

</description>
      <category>prisma</category>
      <category>node</category>
      <category>typescript</category>
      <category>apm</category>
    </item>
  </channel>
</rss>
