<?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>Forem: New Relic</title>
    <description>The latest articles on Forem by New Relic (@newrelic).</description>
    <link>https://forem.com/newrelic</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2621%2F9f60ba91-e078-4981-a2a3-9848e4e4fafa.png</url>
      <title>Forem: New Relic</title>
      <link>https://forem.com/newrelic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/newrelic"/>
    <language>en</language>
    <item>
      <title>Build AI Agents You Can Actually Trust — Hackathon in Mountain View 🚀</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Wed, 11 Mar 2026 20:12:07 +0000</pubDate>
      <link>https://forem.com/newrelic/build-ai-agents-you-can-actually-trust-hackathon-in-mountain-view-1edf</link>
      <guid>https://forem.com/newrelic/build-ai-agents-you-can-actually-trust-hackathon-in-mountain-view-1edf</guid>
      <description>&lt;h2&gt;
  
  
  You Founded a Startup. Your AI Agents Are Hallucinating. Your Investors Are Watching
&lt;/h2&gt;

&lt;p&gt;Sound fun? It is, actually.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;March 27&lt;/strong&gt;, we're hosting a free, in-person hackathon at the &lt;strong&gt;Microsoft Mountain View Campus&lt;/strong&gt; (1045 La Avenida St, Mountain View, CA) where you'll build an AI-powered travel planning assistant from scratch — and then make it production-ready with real observability and security controls.&lt;/p&gt;

&lt;p&gt;This is part of &lt;a href="https://aka.ms/wth" rel="noopener noreferrer"&gt;Microsoft's What The Hack&lt;/a&gt; series: collaborative, challenge-based hackathons where you learn by &lt;em&gt;doing&lt;/em&gt;, not by watching someone else's screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌍 The Scenario: Welcome to WanderAI
&lt;/h2&gt;

&lt;p&gt;You've just founded &lt;strong&gt;WanderAI&lt;/strong&gt;, a travel planning startup. Your customers describe their dream trip, and your AI agents craft personalized itineraries.&lt;/p&gt;

&lt;p&gt;But here's the catch — your investors want answers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 Are the agents making &lt;em&gt;good&lt;/em&gt; recommendations?&lt;/li&gt;
&lt;li&gt;⚡ How fast are they responding?&lt;/li&gt;
&lt;li&gt;🚨 When something breaks, can we debug it?&lt;/li&gt;
&lt;li&gt;✅ Are the travel plans actually... good?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your mission: go from "cool demo" to "production-ready AI service" in a single day.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ What You'll Build (and Learn)
&lt;/h2&gt;

&lt;p&gt;The hack is structured as 8 progressive challenges:&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;Challenge&lt;/th&gt;
&lt;th&gt;What You'll Do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;00&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Set up your GitHub Codespace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;01&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Master the Foundations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Understand agent architecture, tools &amp;amp; orchestration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;02&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Build Your MVP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Create a Flask web app + your first AI agent with tool calling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;03&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Add OpenTelemetry&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Instrument with built-in telemetry, verify traces in console &amp;amp; New Relic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;04&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;New Relic Integration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom spans, metrics, and correlated logging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;05&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Monitoring Best Practices&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dashboards, alerting, and production monitoring patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;06&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LLM Quality Gates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Build evaluation tests and CI/CD quality gates for AI outputs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;07&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Platform Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Configure Microsoft Foundry Guardrails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;08&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;App-Level Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prompt injection detection and blocking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;By the end, you'll have a fully instrumented, observable, and secure multi-agent AI system. Not bad for one day.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧰 The Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Agent Framework&lt;/strong&gt; — for building multi-agent orchestrations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenTelemetry&lt;/strong&gt; — the open standard for traces, metrics, and logs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Relic&lt;/strong&gt; — for sending, visualizing, and alerting on all that telemetry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure&lt;/strong&gt; — the cloud backbone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python + Flask&lt;/strong&gt; — the app layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Codespaces&lt;/strong&gt; — zero local setup headaches&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🍕 The Details
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When:&lt;/strong&gt; March 27, 2026&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where:&lt;/strong&gt; Microsoft Mountain View Campus, 1045 La Avenida St, Mountain View, CA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; Free&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Food:&lt;/strong&gt; Provided&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duration:&lt;/strong&gt; ~3–5 hours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to bring:&lt;/strong&gt; Your laptop and curiosity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who Is This For?
&lt;/h2&gt;

&lt;p&gt;Anyone who's building (or thinking about building) AI agents and wants to understand what's happening under the hood. Whether you're a backend engineer, an ML practitioner, a platform engineer, or just AI-curious — this hack meets you where you are.&lt;/p&gt;

&lt;p&gt;No prior experience with New Relic or OpenTelemetry is required. Basic Python and web dev knowledge is helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎟️ Register Now
&lt;/h2&gt;

&lt;p&gt;Space is limited — grab your seat before it fills up:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://aka.ms/AzNewRelicWTH" rel="noopener noreferrer"&gt;Register here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;See you in Mountain View! 🏔️&lt;/p&gt;

</description>
      <category>ai</category>
      <category>observability</category>
      <category>opentelemetry</category>
      <category>newrelic</category>
    </item>
    <item>
      <title>Unleashing the Power of Monitoring: Master Your WordPress with New Relic</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Tue, 25 Nov 2025 19:58:22 +0000</pubDate>
      <link>https://forem.com/newrelic/unleashing-the-power-of-monitoring-master-your-wordpress-with-new-relic-1gjg</link>
      <guid>https://forem.com/newrelic/unleashing-the-power-of-monitoring-master-your-wordpress-with-new-relic-1gjg</guid>
      <description>&lt;p&gt;WordPress powers countless websites across various domains, offering incredible versatility. This Content Management System (CMS) is the undisputed leader in the CMS market, powering an impressive 43.6% of all websites globally, according to &lt;a href="https://growthscribe.com/wordpress-statistics/" rel="noopener noreferrer"&gt;these statistics&lt;/a&gt;. With over 810 million websites built on the platform and hundreds more launching daily (500+), its adoption continues to surge. This widespread use gives WordPress a massive 62% CMS market share, significantly outpacing its rivals.&lt;/p&gt;

&lt;p&gt;However, even the most robust WordPress sites can face performance challenges. Slowdowns are often caused by factors such as slow-loading plugins, database connection issues, infrastructure capacity problems, network trouble, large page assets (like images or fonts), and broken links. This is why robust monitoring is essential for maintaining a fast, reliable, and user-friendly website.&lt;/p&gt;

&lt;p&gt;The question now is: what should be monitored in WordPress?&lt;/p&gt;

&lt;p&gt;To truly master your WordPress environment, monitoring needs to extend across the entire stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WordPress Application Code&lt;/strong&gt;: The core of your site and any custom code or plugins you've added.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Underlying Infrastructure&lt;/strong&gt;: This includes the hosts, servers, or virtual machines (VMs) that power your site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;(Apache) Web Server&lt;/strong&gt;: Monitoring the web server ensures it's handling requests efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;(MySQL) Database&lt;/strong&gt;: Database performance is critical, as slow queries can quickly bottleneck your site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;End-User Experience (Frontend)&lt;/strong&gt;: How your website performs for your actual users, measuring factors like page load times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business Objectives&lt;/strong&gt;: Tracking metrics like visitor count, device usage, and post performance, which tie directly to your business goals.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Monitor WordPress
&lt;/h2&gt;

&lt;p&gt;You have several powerful options for implementing comprehensive WordPress monitoring:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. New Relic Observability Platform
&lt;/h3&gt;

&lt;p&gt;New Relic offers a powerful &lt;a href="https://docs.newrelic.com/docs/apm/agents/php-agent/frameworks-libraries/wordpress-fullstack-integration/?ref=kimpel.com" rel="noopener noreferrer"&gt;full-stack WordPress integration&lt;/a&gt; that monitors your application's performance. It helps you diagnose issues and optimize your code by leveraging New Relic's existing PHP, Apache, and MySQL integrations. This provides pre-built dashboards with crucial metrics like transactions, visitors, and call duration. The installation process is often surprisingly quick, with agents installed in minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqepp08u3v855x17scd0y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqepp08u3v855x17scd0y.gif" alt="New Relic Agent install in less than two minutes" width="525" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. OpenTelemetry (Open-Source Standard)
&lt;/h3&gt;

&lt;p&gt;OpenTelemetry (CNCF project) is a vendor-agnostic set of APIs, libraries, and a collector service designed to standardize how you collect telemetry data (Traces, Metrics, and Logs) from your applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traces&lt;/strong&gt;: Show the path of a request through your application and services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;: A measurement captured at runtime, such as Avg. CPU, Throughput, or Max. Memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs&lt;/strong&gt;: A recording of an event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://github.com/opentelemetry-php/contrib-auto-wordpress" rel="noopener noreferrer"&gt;OpenTelemetry WordPress extension&lt;/a&gt; monitors performance and, unlike some WordPress setups, relies on a composer for managing dependencies, including the OpenTelemetry SDK and an exporter to send telemetry data to an observability platform of your choice.What Monitoring Reveals&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of WordPress monitoring
&lt;/h2&gt;

&lt;p&gt;Implementing monitoring gives you deep visibility into your site's performance:&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend Monitoring
&lt;/h3&gt;

&lt;p&gt;This focuses on the user experience, revealing how quickly pages load and identifying performance bottlenecks visible to the end-user.&lt;/p&gt;

&lt;p&gt;New Relic monitoring capabilities automatically include &lt;a href="https://developer.chrome.com/docs/lighthouse/performance/performance-scoring" rel="noopener noreferrer"&gt;Google’s lighthouse metrics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi755gequzpzbpyu7jyv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi755gequzpzbpyu7jyv3.png" alt="Core Web Vitals dashboard within New Relic UI" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows you to either visualize a comparison between frontend and backend duration or dive deeper into the breakdowns of the frontend sections of your page view load time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe96creghyomccnibkpym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe96creghyomccnibkpym.png" alt="Page view load time, Front end vs. Back end response time, and HTTP Error rate dashboards within New Relic UI" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another key aspect of frontend aka real user monitoring is New Relic’s Geography UI page. It provides a world view with color-coded performance information about your frontend experience in cities, regions, and countries anywhere around the world. The map shows your user data by region, so you can visualize your traffic and error hotspots alongside device type information. You can also examine critical Core Web Vitals data so that you can prioritize areas around the globe needing attention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdquelgn7lbofu7dbni5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdquelgn7lbofu7dbni5w.png" alt="Average load time by geography within the New Relic UI" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend Analysis
&lt;/h3&gt;

&lt;p&gt;Monitoring provides detailed insight into your server-side performance, allowing you to examine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Golden Signals&lt;/strong&gt;: Web transaction time, throughput, errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2kyp4xy4yk8egultx8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2kyp4xy4yk8egultx8v.png" alt="Golden Signals dashboard within the New Relic UI" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Especially when seeing spikes, a timeseries view provides visual representations of patterns and anomalies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdb3lic9zclczkn2xroks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdb3lic9zclczkn2xroks.png" alt="Web transactions time and Throughput dashboards within the New Relic UI" width="800" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transactions&lt;/strong&gt;: The processing time for various key requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjmsro5clk4l4qw7xp67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjmsro5clk4l4qw7xp67.png" alt="Transaction monitoring dashboard within New Relic UI" width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: Slow or inefficient database queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft43810nrl1lh8y6k4wq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft43810nrl1lh8y6k4wq6.png" alt="Database monitoring dashboard within New Relic UI" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hooks&lt;/strong&gt;: Performance of WordPress action and filter hooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjx2kygm0rfmx2uo7t0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjx2kygm0rfmx2uo7t0e.png" alt="Database monitoring dashboard within New Relic UI" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traces&lt;/strong&gt;: Detailed views of a single request's journey through your system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hl3vvdqqrhr9y2aeqlr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hl3vvdqqrhr9y2aeqlr.png" alt="Trace details dashboard within the New Relic UI" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1wxlx9m2pusv98llzet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1wxlx9m2pusv98llzet.png" alt="Query performance analysis within New Relic UI" width="686" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Business Metrics
&lt;/h3&gt;

&lt;p&gt;Beyond technical performance, monitoring allows you to track metrics that directly impact your business:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visitors&lt;/strong&gt;: Analyze user traffic and trends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo3cjm4inzsdzahmgp1q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo3cjm4inzsdzahmgp1q.png" alt="Website visitor analytics within the New Relic UI" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Devices&lt;/strong&gt;: See which devices your visitors are using&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzaa9c468v2lcjw2vho0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzaa9c468v2lcjw2vho0i.png" alt="Website visitor device analytics within the New Relic UI" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Posts&lt;/strong&gt;: Monitor the performance and traffic of specific content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftozwaivkd6io1dgswhbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftozwaivkd6io1dgswhbz.png" alt="Content performance analytics within New Relic UI" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend Users&lt;/strong&gt;: Track activity and performance related to logged-in users and administrators.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion: Why, What, and How
&lt;/h2&gt;

&lt;p&gt;Effective WordPress monitoring answers three key questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Why Monitor?&lt;/strong&gt; To resolve slowdowns, address infrastructure issues, and ensure a positive end-user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to Monitor?&lt;/strong&gt; The technical aspects (code, infrastructure, database), the end-user experience, and business objectives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How to Monitor?&lt;/strong&gt; By utilizing powerful options like the New Relic observability platform or the vendor-agnostic OpenTelemetry standard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ultimately, monitoring is about understanding where your application is excelling and where it needs attention, allowing you to proactively optimize performance and achieve your business goals.&lt;/p&gt;

&lt;p&gt;Ready to gain deep insights into your WordPress performance?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://newrelic.com/signup?ref=kimpel.com" rel="noopener noreferrer"&gt;Get started with New Relic today&lt;/a&gt;&lt;/strong&gt; and leverage the power of comprehensive observability, whether through our native integrations or the flexibility of OpenTelemetry.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>newrelic</category>
      <category>observability</category>
    </item>
    <item>
      <title>Optimizing Kafka Tracing with OpenTelemetry: Boost Visibility &amp; Performance</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Tue, 25 Nov 2025 19:55:31 +0000</pubDate>
      <link>https://forem.com/newrelic/optimizing-kafka-tracing-with-opentelemetry-boost-visibility-performance-442j</link>
      <guid>https://forem.com/newrelic/optimizing-kafka-tracing-with-opentelemetry-boost-visibility-performance-442j</guid>
      <description>&lt;p&gt;Ideally, you should be using distributed tracing to trace requests through your system, but &lt;a href="https://kafka.apache.org/" rel="noopener noreferrer"&gt;Kafka&lt;/a&gt; decouples producers and consumers, which means there are no direct transactions to trace between them. Kafka also uses asynchronous processes, which have implicit, not explicit, dependencies. That makes it challenging to understand how your microservices are working together.&lt;/p&gt;

&lt;p&gt;However, it is possible to monitor your Kafka clusters with distributed tracing and &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt;. You can then analyze and visualize your traces in an open-source distributed tracing tool like Jaeger or a full observability platform like New Relic. In this post, I will leverage a simple application to show how you can achieve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Considerations &amp;amp; Guidelines
&lt;/h2&gt;

&lt;p&gt;OpenTelemetry typically comes in two flavors:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn05devmng1isc0qtvxzs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn05devmng1isc0qtvxzs.png" alt="OTel design considerations and guidelines" width="512" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I talk about these flavors, I typically use the analogy above. You can either buy a ready-made cake and enjoy it or buy all the ingredients and make the cake yourself. With OpenTelemetry, the approach is very similar and the flavors are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-code instrumentation&lt;/strong&gt;: in this approach, you will use an OpenTelemetry agent and attach it to your application at startup time. This agent will then do its magic and automatically (without any source code changes) provide a lot of telemetry signals (metrics, traces and logs) and insights into your application.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;/li&gt;
&lt;li&gt;Getting started quickly
&lt;/li&gt;
&lt;li&gt;No source code changes
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;/li&gt;
&lt;li&gt;Limited customization
&lt;/li&gt;
&lt;li&gt;Depth of visibility into your application may be limited
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Manual instrumentation&lt;/strong&gt;: this option requires you to add some dependencies and packages to your source code that you need to manage as part of your regular software development lifecycle (SDLC). However, this also allows you to be more specific and custom about your instrumentation. You can easily add custom metrics, traces, attributes to your telemetry.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;:
&lt;/li&gt;
&lt;li&gt;Way more flexible with customizing telemetry
&lt;/li&gt;
&lt;li&gt;Easily able to add, remove and tweak the depth of your instrumentation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;:
&lt;/li&gt;
&lt;li&gt;Dependencies in your source code
&lt;/li&gt;
&lt;li&gt;More effort to implement&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sample application
&lt;/h2&gt;

&lt;p&gt;The sample application (available in this &lt;a href="https://github.com/harrykimpel/java-kafka-otel-producer-consumer" rel="noopener noreferrer"&gt;public GitHub repository&lt;/a&gt;) that I am using in this blog is based on this high-level architecture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh2ldd9krkdki54pe0c8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh2ldd9krkdki54pe0c8q.png" alt="APM entity map" width="512" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It contains these components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kafka-java-producer&lt;/strong&gt;: a Java Spring Boot application that produces messages into a Kafka topic
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka broker&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kafka-java-consumer&lt;/strong&gt;: a Java Spring Boot application that subscribes to a Kafka topic and reads messages from it. This component also makes calls to an external REST API service (that is not in our control)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kafka-java-service&lt;/strong&gt;: a downstream Java Spring Boot application that is being called from the consumer service&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Zero-code instrumentation
&lt;/h2&gt;

&lt;p&gt;Let’s start with zero-code instrumentation, aka automatic instrumentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Each of the different services contain a &lt;code&gt;run.sh&lt;/code&gt; script to get the service up and running. The script looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqccp4bxre8lsehdb8f92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqccp4bxre8lsehdb8f92.png" alt="run script Java tool options" width="512" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key line in this is the first one. Here we are defining the &lt;code&gt;JAVA_TOOL_OPTIONS&lt;/code&gt; and configuring the &lt;code&gt;-javaagent&lt;/code&gt; to point to the location of the &lt;a href="https://github.com/open-telemetry/opentelemetry-java" rel="noopener noreferrer"&gt;OpenTelemetry Java agent&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The next three lines configure how we want to deal with the different telemetry signals. In our case, I define the traces, metrics and logs to be exported via OpenTelemetry Line Protocol (OTLP).&lt;/p&gt;

&lt;p&gt;There are three additional environment variables that are quite important to configure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/strong&gt;: the target system where we want to export the data to, i.e. our telemetry backend. In my case, this is for sure New Relic and so I configure New Relic’s native OTLP endpoint
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTEL_EXPORTER_OTLP_HEADERS&lt;/strong&gt;: the above exporter endpoint is an open API, so we need to configure an API key. In the case of New Relic, this is a New Relic license key.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTEL_SERVICE_NAME&lt;/strong&gt;: ideally, we want to give the service a meaningful name, so that New Relic can create an appropriate entity from it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is basically all we need to configure. Everything else is dealt by the OpenTelemetry Java agent. No need to change anything in our source code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observability
&lt;/h3&gt;

&lt;p&gt;Let’s see what level of visibility into the services we can achieve from zero-code instrumentation.&lt;/p&gt;

&lt;p&gt;When navigating to my New Relic account, I can see all services reporting into separate entities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4unlp4fo63yl9gpybq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4unlp4fo63yl9gpybq5.png" alt="New Relic all entities" width="512" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s start by exploring the &lt;strong&gt;kafka-java-producer&lt;/strong&gt; service.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Summary&lt;/strong&gt; view offers a great overview of all the most important telemetry and metrics I should be focusing on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjipojvwykrwyc8350tu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjipojvwykrwyc8350tu.png" alt="New Relic APM summary UI" width="512" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As part of this blog, I am mostly interested in the &lt;strong&gt;Distributed Tracing&lt;/strong&gt; section, so let’s dive deeper into this area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zt2yqi4rk74kom3y4bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zt2yqi4rk74kom3y4bg.png" alt="New Relic APM distributed tracing UI" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By looking at a single trace, this allows me to view the detailed information on how long this specific trace took to execute and where the time was spent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnc77i70lb464lslqy5yj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnc77i70lb464lslqy5yj.png" alt="New Relic APM distributed tracing trace details UI" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also automatically draw an &lt;strong&gt;Entity map&lt;/strong&gt; of all the different services involved in a given trace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xqxeod65yiodgav44r3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1xqxeod65yiodgav44r3.png" alt="New Relic APM distributed tracing trace details entity map" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The interesting area that I want to draw your attention to lies in the &lt;a href="https://opentelemetry.io/docs/specs/otel/overview/#traces" rel="noopener noreferrer"&gt;trace&lt;/a&gt; and &lt;a href="https://opentelemetry.io/docs/specs/otel/overview/#spans" rel="noopener noreferrer"&gt;span&lt;/a&gt; breakdown. You can see how the trace gets initiated on the producer, the consumer then picks up the message and how the consumer then also makes two separate calls to the downstream service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm57g9uhlfjfc2dnqvp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm57g9uhlfjfc2dnqvp7.png" alt="New Relic APM distributed tracing trace details spans zero-code" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is interesting here is the span that says “Uninstrumented time”. This is code in the consumer where the agent was not able to capture some more detailed information about what is going on in its internal methods.&lt;/p&gt;

&lt;p&gt;This already shows the limits of zero-code instrumentation. The agent by default will not instrument all the various methods and source code, but rather stops - by design - at some level to get deeper visibility into your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual instrumentation
&lt;/h2&gt;

&lt;p&gt;In the previous section, you saw how zero-code instrumentation has some limits when it comes to visibility into your application. This is exactly where manual instrumentation comes into play.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;I have configured the same application, but this time, no agent at all is configured when starting the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhi54flnmwfqwoepqgor0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhi54flnmwfqwoepqgor0.png" alt="run script Maven wrapper" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I simply use the Maven wrapper to run the application.&lt;/p&gt;

&lt;p&gt;The other configuration details are then part of my application.properties:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fw5s7bbjmxzccdaktfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9fw5s7bbjmxzccdaktfx.png" alt="Java application.properties" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These properties are then used in my Spring Boot application code to define the configuration for OpenTelemetry for traces, metrics and logs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fel2yxupwhksv6por0p6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fel2yxupwhksv6por0p6m.png" alt="Java OpenTelemetry SDK configuration" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Observability
&lt;/h3&gt;

&lt;p&gt;Before I jump into the details of how I implemented some manual instrumentation, let’s have a look at the result first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85i6px8wbw63a2inp7z7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85i6px8wbw63a2inp7z7.png" alt="New Relic APM distributed tracing trace details spans manual" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you notice how the span, which previously was called out with “Uninstrumented time”, now shows much more detailed information? I now can see these additional spans:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ExecuteLongRunningTask
&lt;/li&gt;
&lt;li&gt;WhyTheHeckDoWeSleepHere
&lt;/li&gt;
&lt;li&gt;SomeTinyTask
&lt;/li&gt;
&lt;li&gt;AnotherShortRunningTask&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one that says “WhyTheHeckDoWeSleepHere” seems to be taking the most time. No wonder, as the name suggests 😉.&lt;/p&gt;

&lt;p&gt;Let’s have a look at the source code to reveal the manual instrumentation I put in place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5z2y7g71fdr64g34tzii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5z2y7g71fdr64g34tzii.png" alt="Java source code ewith custom OTel spans" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the method named &lt;strong&gt;ExecuteLongRunningTask&lt;/strong&gt; I have created a new span on the current tracer by using the &lt;strong&gt;spanBuilder()&lt;/strong&gt; Method.&lt;/p&gt;

&lt;p&gt;In addition to that, you may also notice that - just for the fun of it - I created another span called “WhyTheHeckDoWeSleepHere” that contains an artificial unit of work or rather a sleep instruction on the current thread.&lt;/p&gt;

&lt;p&gt;These concepts to leverage the OpenTelemetry SDK allow me to be much more specific in getting insights and details into my application and source code. But, as you can imagine, also have the caveat that I need to have some dependencies and custom code available in my source code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope I was able to show you how easy it can be to leverage OpenTelemetry in order to get insights into your application and services. We looked into zero-code instrumentation to get started without any code changes, but the level of details may be limited. We then also looked into manual instrumentation. This allowed us to be more specific and customize the instrumentation, but the effort to get started is a little higher.&lt;/p&gt;

&lt;p&gt;I encourage you to have a look into OpenTelemetry and its fascinating capabilities. Let me know your thoughts and please get in touch if you have any questions or need further information.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>opentelemetry</category>
      <category>newrelic</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Monitoring PM2 in production</title>
      <dc:creator>Zameer Fouzan</dc:creator>
      <pubDate>Fri, 01 Nov 2024 13:30:00 +0000</pubDate>
      <link>https://forem.com/newrelic/monitoring-pm2-in-production-eak</link>
      <guid>https://forem.com/newrelic/monitoring-pm2-in-production-eak</guid>
      <description>&lt;p&gt;In large-scale Node.js production environments, monitoring multiple applications can become challenging. The New Relic APM agent for Node.js helps capture logs, traces, and in-depth performance metrics from individual applications. But what about the overall health and resource consumption of all Node.js processes themselves, and critical process-level metrics like CPU and memory usage?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pm2.io/" rel="noopener noreferrer"&gt;PM2&lt;/a&gt; is a popular process manager for Node.js applications, designed to simplify deployment and ensure reliability. It provides robust features, including automatic application restarts, load balancing, and monitoring capabilities, making it an essential tool for managing production-grade Node.js environments.&lt;/p&gt;

&lt;p&gt;PM2's monitoring API provides easy access to detailed telemetry data, like active processes, and resource consumption, along with additional helpful details like Git commit, active branch, Node.js version, and entry script. These insights can be invaluable when troubleshooting and identifying the root cause of performance issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can I monitor from PM2?
&lt;/h2&gt;

&lt;p&gt;PM2 API provides generous information that can be captured. Ideally, all the metrics that can be visualized using the PM2’s monitor API on your host can be captured and exported to New Relic.&lt;/p&gt;

&lt;p&gt;&lt;a href="PM2%20monitor%20Live%20View%20Gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftc1bddnts2vuoylzd9wy.gif" alt="PM2 monitor view" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll focus on several key metrics that are important for monitoring PM2. &lt;/p&gt;

&lt;h3&gt;
  
  
  Application identity and host information
&lt;/h3&gt;

&lt;p&gt;Application details, including the host ID, for applications currently running as part of PM2, make it easy to pinpoint which instance is associated with each application. This is especially helpful in environments with multiple services, as you can easily identify specific processes and manage them effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt;: &lt;code&gt;appName&lt;/code&gt;, &lt;code&gt;hostId&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource metrics
&lt;/h3&gt;

&lt;p&gt;Metrics from each process, like CPU and memory usage, provide essential insights into the resource consumption and performance of your application. With &lt;code&gt;axm_monitor&lt;/code&gt;, you can also track HTTP latency, active requests, and event loop latency to monitor responsiveness in real time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt;: &lt;code&gt;monit.cpu&lt;/code&gt;, &lt;code&gt;monit.memory&lt;/code&gt;, &lt;code&gt;axm_monitor&lt;/code&gt; (for example, HTTP latency, active requests, event loop latency)&lt;/p&gt;

&lt;h3&gt;
  
  
  Process information
&lt;/h3&gt;

&lt;p&gt;Process-level details such as process ID, status, and uptime help monitor each application's health and lifecycle. Tracking when a process was last updated or started helps you identify issues like frequent restarts or unusually high uptime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt;: &lt;code&gt;pid&lt;/code&gt;, &lt;code&gt;pm2_env.status&lt;/code&gt;, &lt;code&gt;pm2_env.pm_uptime&lt;/code&gt;, &lt;code&gt;pm2_env.created_at&lt;/code&gt;, &lt;code&gt;timestamp&lt;/code&gt;, &lt;code&gt;pm2_env.update_time&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Debug pointers: Logs, errors, restarts, and crashes
&lt;/h3&gt;

&lt;p&gt;Debugging details like log paths, error codes, and restart counts allow quick troubleshooting. Having both the standard output and error logs, alongside information on restarts, helps pinpoint stability issues or potential bugs within applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt;: &lt;code&gt;pm2_env.error_file&lt;/code&gt;, &lt;code&gt;pm2_env.out_file&lt;/code&gt;, &lt;code&gt;pm2_env.exit_code&lt;/code&gt;, &lt;code&gt;pm2_env.unstable_restarts&lt;/code&gt;, &lt;code&gt;pm2_env.restart_time&lt;/code&gt;, &lt;code&gt;pm2_env.status&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Version control and deployment insights
&lt;/h3&gt;

&lt;p&gt;Deployment details, including Git commit history and Node.js version, make it easy to track deployed versions. PM2 captures branch, revision, and commit data, giving clear visibility into which version is running and simplifying root cause analysis after code changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt;: &lt;code&gt;pm2_env.node_version&lt;/code&gt;, &lt;code&gt;pm2_env.version&lt;/code&gt;, &lt;code&gt;pm2_env.versioning.*&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I capture insights from PM2?
&lt;/h2&gt;

&lt;p&gt;Currently, there’s no direct integration between New Relic agents and PM2, but we can &lt;a href="https://docs.newrelic.com/docs/infrastructure/host-integrations/host-integrations-list/flex-integration-tool-build-your-own-integration/" rel="noopener noreferrer"&gt;build our own integration using Flex&lt;/a&gt;. Flex is an easy and agentless option to build integrations between your data source and New Relic. &lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Create a new configuration file named &lt;code&gt;pm2_monit.yml&lt;/code&gt;, then add the following configuration.&lt;/p&gt;

&lt;p&gt;This configuration is simply calling the &lt;code&gt;PM2 jlist&lt;/code&gt; API and sanitizing the JSON output data using &lt;a href="https://jqlang.github.io/jq/" rel="noopener noreferrer"&gt;JQ&lt;/a&gt;. JQ is a command line utility that's used to process, query, and transform JSON data. Flex has support for JQ built in, which makes sanitizing and transforming the data easier. &lt;/p&gt;

&lt;p&gt;As the original output can also include additional, sensitive data, which could be unnecessary, it can be easily dropped with the JQ and &lt;code&gt;remove_keys&lt;/code&gt; functions of Flex.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic configuration&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;integrations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nri-flex&lt;/span&gt;
    &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60s&lt;/span&gt;
    &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PM2status&lt;/span&gt;
      &lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PM2Process&lt;/span&gt;
          &lt;span class="na"&gt;event_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PM2Sample&lt;/span&gt;
          &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Linux specific command&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;USER=ubuntu; su - $USER bash -c "pm2 jlist"&lt;/span&gt;
        &lt;span class="c1"&gt;# command for windows/mac&lt;/span&gt;
        &lt;span class="c1"&gt;# - run: npx pm2 jlist&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON transformation with JQ&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
At this stage, the output from &lt;code&gt;pm2 jlist&lt;/code&gt; is a raw JSON. Let’s sanitize and transform the JSON output with JQ to retain only the necessary fields, using the &lt;code&gt;remove_keys&lt;/code&gt; and &lt;code&gt;rename_keys&lt;/code&gt; functions to streamline the data further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;       &lt;span class="c1"&gt;# Sanitize and transform the JSON output to required format   &lt;/span&gt;
          &lt;span class="na"&gt;jq&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt; 
              &lt;span class="s"&gt;[] | { &lt;/span&gt;
                  &lt;span class="s"&gt;pid,&lt;/span&gt;
                  &lt;span class="s"&gt;name,&lt;/span&gt;
                  &lt;span class="s"&gt;pm2_env: {&lt;/span&gt;
                    &lt;span class="s"&gt;script: .pm2_env.script?,&lt;/span&gt;
                    &lt;span class="s"&gt;out_file: .pm2_env.out_file?,&lt;/span&gt;
                    &lt;span class="s"&gt;error_file: .pm2_env.error_file?,&lt;/span&gt;
                    &lt;span class="s"&gt;watch: .pm2_env.watch?,&lt;/span&gt;
                    &lt;span class="s"&gt;exit_code: .pm2_env.exit_code?,&lt;/span&gt;
                    &lt;span class="s"&gt;node_version: .pm2_env.node_version?,&lt;/span&gt;
                    &lt;span class="s"&gt;versioning: .pm2_env.versioning?,&lt;/span&gt;
                    &lt;span class="s"&gt;version: .pm2_env.version?,&lt;/span&gt;
                    &lt;span class="s"&gt;unstable_restarts: .pm2_env.unstable_restarts?,&lt;/span&gt;
                    &lt;span class="s"&gt;restart_time: .pm2_env.restart_time?,&lt;/span&gt;
                    &lt;span class="s"&gt;created_at: .pm2_env.created_at?,&lt;/span&gt;
                    &lt;span class="s"&gt;pm_uptime: .pm2_env.pm_uptime?,&lt;/span&gt;
                    &lt;span class="s"&gt;status: .pm2_env.status?,&lt;/span&gt;
                    &lt;span class="s"&gt;unique_id: .pm2_env.unique_id?&lt;/span&gt;
                  &lt;span class="s"&gt;},&lt;/span&gt;
                  &lt;span class="s"&gt;pm_id,&lt;/span&gt;
                  &lt;span class="s"&gt;monit&lt;/span&gt;
                &lt;span class="s"&gt;} | del(.pm2_env.versioning.remotes) &lt;/span&gt;
          &lt;span class="na"&gt;remove_keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pm_id&lt;/span&gt;
          &lt;span class="na"&gt;rename_keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appName&lt;/span&gt;
          &lt;span class="na"&gt;custom_attributes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;hostId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Switching user context&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;command&lt;/code&gt; block in Flex configuration switches the user context to where PM2 processes are running, which is necessary, as Flex runs under the root (sudo) user by default. If you're running PM2 locally on Windows or Mac, use &lt;code&gt;npx pm2 jlist&lt;/code&gt; command block instead of the Linux-specific command.&lt;/p&gt;

&lt;p&gt;The complete configuration should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;integrations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nri-flex&lt;/span&gt;
    &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60s&lt;/span&gt;
    &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PM2status&lt;/span&gt;
      &lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PM2Process&lt;/span&gt;
          &lt;span class="na"&gt;event_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PM2Sample&lt;/span&gt;
          &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;USER=ubuntu; su - $USER bash -c "pm2 jlist"&lt;/span&gt;
        &lt;span class="c1"&gt;# - run: npx pm2 jlist&lt;/span&gt;
       &lt;span class="c1"&gt;# Sanitize and transform the JSON output to required format   &lt;/span&gt;
          &lt;span class="na"&gt;jq&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt; 
              &lt;span class="s"&gt;[] | { &lt;/span&gt;
                  &lt;span class="s"&gt;pid,&lt;/span&gt;
                  &lt;span class="s"&gt;name,&lt;/span&gt;
                  &lt;span class="s"&gt;pm2_env: {&lt;/span&gt;
                    &lt;span class="s"&gt;script: .pm2_env.script?,&lt;/span&gt;
                    &lt;span class="s"&gt;out_file: .pm2_env.out_file?,&lt;/span&gt;
                    &lt;span class="s"&gt;error_file: .pm2_env.error_file?,&lt;/span&gt;
                    &lt;span class="s"&gt;watch: .pm2_env.watch?,&lt;/span&gt;
                    &lt;span class="s"&gt;exit_code: .pm2_env.exit_code?,&lt;/span&gt;
                    &lt;span class="s"&gt;node_version: .pm2_env.node_version?,&lt;/span&gt;
                    &lt;span class="s"&gt;versioning: .pm2_env.versioning?,&lt;/span&gt;
                    &lt;span class="s"&gt;version: .pm2_env.version?,&lt;/span&gt;
                    &lt;span class="s"&gt;unstable_restarts: .pm2_env.unstable_restarts?,&lt;/span&gt;
                    &lt;span class="s"&gt;restart_time: .pm2_env.restart_time?,&lt;/span&gt;
                    &lt;span class="s"&gt;created_at: .pm2_env.created_at?,&lt;/span&gt;
                    &lt;span class="s"&gt;pm_uptime: .pm2_env.pm_uptime?,&lt;/span&gt;
                    &lt;span class="s"&gt;status: .pm2_env.status?,&lt;/span&gt;
                    &lt;span class="s"&gt;unique_id: .pm2_env.unique_id?&lt;/span&gt;
                  &lt;span class="s"&gt;},&lt;/span&gt;
                  &lt;span class="s"&gt;pm_id,&lt;/span&gt;
                  &lt;span class="s"&gt;monit&lt;/span&gt;
                &lt;span class="s"&gt;} | del(.pm2_env.versioning.remotes) &lt;/span&gt;
          &lt;span class="na"&gt;remove_keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pm_id&lt;/span&gt;
          &lt;span class="na"&gt;rename_keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appName&lt;/span&gt;
          &lt;span class="na"&gt;custom_attributes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;hostId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validation
&lt;/h3&gt;

&lt;p&gt;Once the configuration is ready, we can validate it with Flex's debug mode. If you’re using the standalone binary mode of Flex, use the following command to test your configuration:&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="nb"&gt;sudo&lt;/span&gt; ./nri-flex &lt;span class="nt"&gt;-config_file&lt;/span&gt; pm2_monit.yml &lt;span class="nt"&gt;--pretty&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test the configuration using New Relic's infrastructure agent Flex integration, execute the following command:&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="nb"&gt;sudo&lt;/span&gt; /var/db/newrelic-infra/newrelic-integrations/bin/nri-flex &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;--pretty&lt;/span&gt; &lt;span class="nt"&gt;--config_file&lt;/span&gt; ./pm2_monit.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Read more about Flex testing and debugging in &lt;a href="https://docs.newrelic.com/docs/infrastructure/host-integrations/host-integrations-list/flex-integration-tool-build-your-own-integration" rel="noopener noreferrer"&gt;this&lt;/a&gt; &lt;a href="https://docs.newrelic.com/docs/infrastructure/host-integrations/host-integrations-list/flex-integration-tool-build-your-own-integration/" rel="noopener noreferrer"&gt;document&lt;/a&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Upon successful execution of your configuration, you should expect an output similar to the one displayed below, without the Flex debug output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.newrelic.nri-flex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protocol_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"integration_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.15.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"metrics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"appName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expressApp-otel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"event_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PM2Sample"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"hostId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ec2-webserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"integration_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.newrelic.nri-flex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"integration_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.15.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"monit.cpu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"monit.memory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;46641152&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1304&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1728589283166&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.error_file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/error.log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.exit_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.node_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16.17.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.out_file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/app.log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.pm_uptime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1729058602005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.restart_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.script"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"online"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.unique_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"858b1616-bfd7-41c0-8861-de5babcfe106"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.unstable_restarts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.ahead"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.branch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"master"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.branch_exists_on_remote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.comment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"update: Added query param to fetch mapped category in response&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;fix: fallback envvar value&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.next_rev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s2"&gt;003cnil&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s2"&gt;003e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.prev_rev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f195db41aec0592142ef478c424ec1722c7318a4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.remote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.repo_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/ubuntu/workspace/node-express-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.revision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8d31b501b38229171be428db1dc7e2b412694116"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.unstaged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.update_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-10-16T06:03:22.325Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git@github.com:zmrfzn/node-express-app.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"event_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"flexStatusSample"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.Hostname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ip-172-31-30-74"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.IntegrationVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.15.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.counter.ConfigsProcessed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.counter.EventCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.counter.EventDropCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.counter.PM2Sample"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.time.elapsedMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;263&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.time.endMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1730119876587&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"flex.time.startMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1730119876324&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"inventory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;Here’s the simplified data that we’re capturing with Flex from the PM2 processes after transformations with JQ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"appName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expressApp-otel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"hostId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ec2-webserver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"integration_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.newrelic.nri-flex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"integration_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.15.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"monit.cpu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"monit.memory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80068608&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1310&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1728589676754&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.error_file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/error.log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.exit_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.node_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16.17.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.out_file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"logs/app.log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.pm_uptime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1729058602010&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.restart_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.script"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"online"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.unique_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"83e7e3d5-17d7-41b0-87fe-5201148c826a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.unstable_restarts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.ahead"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.branch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"otel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.branch_exists_on_remote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.comment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chore: update OTEL SDK packages to latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.next_rev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;nil&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.prev_rev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f9fb795ec5ec07d24bd858b55287cbffda44b365"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.remote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.repo_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/ubuntu/workspace/otel/node-express-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.revision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aad10ae5445469718cd2da5041d140e39be8ef78"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.unstaged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.update_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-10-16T06:03:22.319Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.versioning.url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git@github.com:zmrfzn/node-express-app.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pm2_env.watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1729513381684&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verification
&lt;/h3&gt;

&lt;p&gt;Flex sends all processed data via the New Relic &lt;a href="https://docs.newrelic.com/docs/data-apis/ingest-apis/event-api/introduction-event-api/" rel="noopener noreferrer"&gt;events API&lt;/a&gt;, which allows efficient handling of various types of event data. In this configuration, we’re naming our event PM2Sample, which helps clearly identify and differentiate it from other events in the system. &lt;/p&gt;

&lt;p&gt;All the data associated with this event can be easily queried using New Relic Query Language (NRQL) on this table itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PM2Sample&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;SINCE&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="n"&gt;MINUTES&lt;/span&gt; &lt;span class="n"&gt;AGO&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7x27blmw8vxkdlo315ch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7x27blmw8vxkdlo315ch.png" alt="PM2 Verify" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualization
&lt;/h3&gt;

&lt;p&gt;Once the data is accessible on the New Relic platform, you can easily query specific metrics relevant to your needs and create tailored visualizations. This allows you to analyze performance trends, monitor process health, and also gather versioning details for the individual applications currently running with PM2.&lt;/p&gt;

&lt;p&gt;With customizable visualizations, you can present the data in a way that best suits your objectives and enhances your understanding of complex information. Additionally, these metrics can also be used to set up personalized alerts. &lt;/p&gt;

&lt;p&gt;Let’s dive into the &lt;code&gt;PM2Sample&lt;/code&gt;. Now we can effortlessly query the average CPU utilization from individual applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PM2Sample&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'CPU Usage %'&lt;/span&gt; &lt;span class="n"&gt;facet&lt;/span&gt; &lt;span class="n"&gt;appName&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstpl3rye80xcscminook.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstpl3rye80xcscminook.png" alt="PM2Sample CPU Utilization by application" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also capture time series data, showcasing how memory consumption compares to CPU usage over time for all your applications under PM2, which are outside of your APM metrics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PM2Sample&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1048576&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'Avg Memory M/b'&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s1"&gt;'Avg CPU%'&lt;/span&gt; &lt;span class="n"&gt;EXTRAPOLATE&lt;/span&gt; &lt;span class="n"&gt;TIMESERIES&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7ea8dqgad6r8mqkafhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7ea8dqgad6r8mqkafhf.png" alt="PM2Sample memory vs CPU timeseries" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NRQL provides an easy way to query and visualize metrics, with powerful dashboard capabilities. Below is an example of a custom dashboard setup specifically designed for PM2 monitoring. It captures various metrics, including memory usage per application, CPU vs. memory for all active applications, and the latest app revision details of the active processes with PM2.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftqd038sf53423l6hpi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftqd038sf53423l6hpi5.png" alt="Custom Pre-built Dashboard for PM2Sample" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import this dashboard using the JSON from this location: &lt;a href="https://raw.githubusercontent.com/zmrfzn/nri-flex/refs/heads/master/examples/pm2-monitor-dashboard.json" rel="noopener noreferrer"&gt;PM2_monit_dashboard&lt;/a&gt;. Make sure to replace all the placeholder account Ids (&lt;code&gt;1234567)&lt;/code&gt; with your New Relic account ID before importing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;PM2’s telemetry offers process-level insights, capturing essential metrics like CPU, memory, and application logs. Flex’s customizable integration with New Relic allows you to bring these data points into a single, unified view. This combination not only enhances visibility into application performance, but also simplifies root-cause analysis and proactive monitoring&lt;/p&gt;

&lt;h2&gt;
  
  
  What Next?
&lt;/h2&gt;

&lt;p&gt;For more information, visit the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://newrelic.com/blog/how-to-relic/what-is-flex" rel="noopener noreferrer"&gt;Build your own integrations with Flex&lt;/a&gt; [link: &lt;a href="https://newrelic.com/blog/how-to-relic/what-is-flex" rel="noopener noreferrer"&gt;https://newrelic.com/blog/how-to-relic/what-is-flex&lt;/a&gt;]
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://newrelic.com/blog/best-practices/nodejs-application-monitoring" rel="noopener noreferrer"&gt;Explore the New Relic APM agent for Node.js&lt;/a&gt;  [link: &lt;a href="https://newrelic.com/blog/best-practices/nodejs-application-monitoring" rel="noopener noreferrer"&gt;https://newrelic.com/blog/best-practices/nodejs-application-monitoring&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>apm</category>
      <category>pm2</category>
      <category>extendnewrelic</category>
      <category>node</category>
    </item>
    <item>
      <title>Observability as code for AI apps with New Relic and Pulumi</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Mon, 14 Oct 2024 18:30:45 +0000</pubDate>
      <link>https://forem.com/newrelic/observability-as-code-for-ai-apps-with-new-relic-and-pulumi-5fgo</link>
      <guid>https://forem.com/newrelic/observability-as-code-for-ai-apps-with-new-relic-and-pulumi-5fgo</guid>
      <description>&lt;p&gt;To read this full article, &lt;a href="https://newrelic.com/blog/how-to-relic/observability-as-code-ai-apps-new-relic-pulumi?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;AI applications are complex and distributed, making effective monitoring challenging. Combining the New Relic intelligent observability platform with Pulumi's infrastructure-as-code and secret management solutions allows for an end-to-end "observability as code" approach. This method enables teams to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define artificial intelligence (AI) and large language model (LLM) monitoring instrumentation along with cloud resources programmatically.&lt;/li&gt;
&lt;li&gt;Securely manage API keys and cloud account credentials.&lt;/li&gt;
&lt;li&gt;Automatically deploy New Relic instrumentation alongside AI applications and infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistent monitoring across environments&lt;/li&gt;
&lt;li&gt;Version-controlled observability configuration&lt;/li&gt;
&lt;li&gt;Easier detection of performance issues&lt;/li&gt;
&lt;li&gt;Deeper insights into AI model behavior and resource usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The observability-as-code approach helps developers maintain visibility into their AI applications as they scale and evolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Pulumi?
&lt;/h2&gt;

&lt;p&gt;Pulumi provides a range of products and services for platform engineers and developers, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/product/" rel="noopener noreferrer"&gt;&lt;strong&gt;Pulumi infrastructure as code (IaC)&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;:&lt;/strong&gt; An open-source tool for defining cloud infrastructure. It supports multiple programming languages. For example, you can use Python to declare AWS Fargate services, Pinecone indexes, and custom New Relic dashboards.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/docs/pulumi-cloud/" rel="noopener noreferrer"&gt;&lt;strong&gt;Pulumi Cloud&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;:&lt;/strong&gt; A hosted service that provides additional features on top of the open-source tool, such as state and secrets management, team collaboration, policy enforcement, and an AI-powered chat assistant, &lt;a href="https://www.pulumi.com/product/copilot/" rel="noopener noreferrer"&gt;&lt;strong&gt;Pulumi Copilot&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pulumi.com/docs/esc/" rel="noopener noreferrer"&gt;&lt;strong&gt;Pulumi Environments, Secrets, and Configuration (ESC)&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;:&lt;/strong&gt; This ensures the secure management of sensitive information necessary for observability. For example, you can manage New Relic, OpenAI, and Pinecone API keys and configure OpenID Connect (OIDC) in AWS. This service is also part of Pulumi Cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pulumi allows teams to version control their observability configurations and infrastructure definitions. This ensures consistency across environments and simplifies the correlation of application changes with monitoring updates and underlying infrastructure modifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to achieve observability as code with New Relic and Pulumi
&lt;/h2&gt;

&lt;p&gt;In this guide, you’ll add &lt;a href="https://newrelic.com/platform/ai-monitoring?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;AI and LLM monitoring&lt;/a&gt; capabilities to an existing chat application by configuring the New Relic application performance monitoring (APM) agent, and by defining New Relic dashboards in Python using Pulumi.&lt;/p&gt;

&lt;p&gt;The final version of the application and infrastructure referenced throughout the guide resides in the &lt;a href="https://github.com/desteves/ai-chat-app" rel="noopener noreferrer"&gt;AI chat app public GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before you start
&lt;/h3&gt;

&lt;p&gt;Ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://newrelic.com/signup?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;New Relic account&lt;/a&gt; and a valid &lt;a href="https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/#overview-keys?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;New Relic license key&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://app.pulumi.com/signup" rel="noopener noreferrer"&gt;Pulumi Cloud account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://www.pulumi.com/docs/install/" rel="noopener noreferrer"&gt;Pulumi CLI&lt;/a&gt; installed locally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;All the services used throughout this guide qualify under the respective free tiers.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Explore the OpenAI demo application
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/desteves/ai-chat-app" rel="noopener noreferrer"&gt;OpenAI demo application&lt;/a&gt; used throughout this guide is written in Node.js for the backend and Python for the frontend. It interacts with OpenAI to generate various gameplays through generative conversational AI interactions. It uses the public OpenAI platform to call its API to access different LLMs like GPT-3.5 Turbo, GPT-4 Turbo, and GPT-4o.&lt;/p&gt;

&lt;p&gt;Below is a screenshot of a "higher or lower" gameplay:&lt;/p&gt;

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

&lt;p&gt;The demo simulates a retrieval-augmented generation (RAG) flow, which commonly looks up information that the AI either doesn't know or might hallucinate. The app stores a handful of common game names and instructions in a Pinecone vector database and then uses it as an embedding when calling OpenAI.&lt;/p&gt;

&lt;p&gt;This application is configured to observe its performance, such as traces, metrics, and logs. It leverages &lt;a href="https://newrelic.com/blog/nerdlog/ai-monitoring-ga?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;New Relic's latest innovation in monitoring AI interactions&lt;/a&gt;, such as requests and responses. This capability ensures compliance, promotes quality, and observes your AI costs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Run the app locally with Docker Compose
&lt;/h4&gt;

&lt;p&gt;The easiest way to run the chat on your local machine is via Docker Compose. Inspect the &lt;code&gt;docker-compose.yml&lt;/code&gt; file in the &lt;code&gt;./app&lt;/code&gt; folder and create the required &lt;code&gt;.env&lt;/code&gt; file as shown. Then, in your terminal, run:&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="nb"&gt;cd &lt;/span&gt;app 
docker compose up &lt;span class="se"&gt;\-&lt;/span&gt;d –build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the web service will run on &lt;a href="http://localhost:8888/" rel="noopener noreferrer"&gt;http://localhost:8888/&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Try out the API endpoints
&lt;/h4&gt;

&lt;p&gt;The API backend provides various endpoints that expose all of its AI functionality. The frontend leverages these endpoints to simulate a flow of activity for end users to select a game and initiate a game interaction, that is, play the game, with OpenAI.&lt;/p&gt;

&lt;p&gt;Follow these steps to simulate a higher or lower gameplay:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the web service &lt;a href="http://localhost:8888/" rel="noopener noreferrer"&gt;http://localhost:8888/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Get Games&lt;/strong&gt; button. A list of games is displayed.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Input&lt;/strong&gt; field, copy &lt;strong&gt;higher or lower&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;To retrieve a game prompt for the next step, click &lt;strong&gt;Get Game Prompt&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;To send the OpenAI request to interact with the game, click &lt;strong&gt;Submit Prompt&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter your first guess into the &lt;strong&gt;Insert Your Game Interaction&lt;/strong&gt; textbox. You’ll get a message about whether your guess was correct when compared to the number the AI picked. Repeat this step until you have guessed the correct number.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Configure New Relic agents with AI
&lt;/h3&gt;

&lt;p&gt;The chat application is configured to capture telemetry using the New Relic APM agent for API and web services. This agent also leverages New Relic's latest innovation in monitoring AI interactions, such as requests and responses. This capability ensures compliance, promotes quality, and observes AI costs.&lt;/p&gt;

&lt;p&gt;Enable the &lt;a href="https://docs.newrelic.com/docs/ai-monitoring/customize-agent-ai-monitoring/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;New Relic AI monitoring&lt;/a&gt; capabilities through the &lt;a href="https://docs.newrelic.com/docs/ai-monitoring/customize-agent-ai-monitoring/#nodejs-config?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;New Relic APM agent configuration&lt;/a&gt; or via environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NEW_RELIC_AI_MONITORING_ENABLED &lt;span class="o"&gt;=&lt;/span&gt; TRUE
NEW_RELIC_SPAN_EVENTS_MAX_SAMPLES_STORED &lt;span class="o"&gt;=&lt;/span&gt; 10000
NEW_RELIC_CUSTOM_INSIGHTS_EVENTS_MAX_SAMPLES_STORED &lt;span class="o"&gt;=&lt;/span&gt; 100000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before exploring the data streamed by the New Relic agents, you’ll use Pulumi to deploy the application to AWS and create custom dashboards. This will enable you to simulate global traffic interacting with the application, thus generating representative AI metrics to forecast performance and cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manage your secrets with Pulumi ESC
&lt;/h3&gt;

&lt;p&gt;While running everything locally is always a good first step in the software development lifecycle, moving to a cloud test environment and beyond involves ensuring .env files are securely available and all the application infrastructure dependencies are deployed and configured. The "Ops" side of DevOps comes into the picture, but it need not be a daunting task. You’ll leverage Pulumi ESC to manage the chat application's secrets.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Pulumi ESC Environment
&lt;/h4&gt;

&lt;p&gt;You'll create a Pulumi ESC environment to store all your .env secrets in Pulumi Cloud. This enables teams to share sensitive information with authorized accounts. Ensure that your New Relic license key, OpenAI token, and Pinecone API keys are handy.&lt;/p&gt;

&lt;p&gt;In your terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pulumi login
&lt;span class="nv"&gt;E&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-cool-chat-app-env
pulumi &lt;span class="nb"&gt;env &lt;/span&gt;init &lt;span class="nv"&gt;$E&lt;/span&gt; &lt;span class="nt"&gt;--non-interactive&lt;/span&gt;
pulumi &lt;span class="nb"&gt;env set&lt;/span&gt;  &lt;span class="nv"&gt;$E&lt;/span&gt; environmentVariables.NEW_RELIC_LICENSE_KEY 123ABC &lt;span class="nt"&gt;--secret&lt;/span&gt;
pulumi &lt;span class="nb"&gt;env set&lt;/span&gt;  &lt;span class="nv"&gt;$E&lt;/span&gt; environmentVariables.OPENAI_API_KEY 123ABC &lt;span class="nt"&gt;--secret&lt;/span&gt;
pulumi &lt;span class="nb"&gt;env set&lt;/span&gt;  &lt;span class="nv"&gt;$E&lt;/span&gt; environmentVariables.PINECONE_API_KEY 123ABC &lt;span class="nt"&gt;--secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Load your .env file with the Pulumi CLI
&lt;/h4&gt;

&lt;p&gt;Now that you’ve defined your ESC environment, you can consume it in several ways. For instance, you can populate our .env files by opening the environment using dotenv formatting:&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="nb"&gt;cd&lt;/span&gt; ./app
pulumi &lt;span class="nb"&gt;env &lt;/span&gt;open &lt;span class="nv"&gt;$E&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; dotenv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./.env
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; –build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Pulumi commands may be scripted to run inside an Amazon EC2 instance or AWS Fargate. Next, you’ll define AWS resources using Pulumi IaC and Python so that you can run the application in AWS. To learn more, visit the &lt;a href="https://www.pulumi.com/docs/esc/" rel="noopener noreferrer"&gt;Pulumi ESC documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate infrastructure code with Pulumi Copilot
&lt;/h3&gt;

&lt;p&gt;Nowadays, you don’t need to start from scratch when using infrastructure as code. Instead, you’ll use the power of generative AI to write Python code to declare all the cloud resources needed for our chat application. This entails declaring New Relic, AWS, and Pinecone resources.&lt;/p&gt;

&lt;p&gt;Pulumi Copilot is a conversational chat interface integrated into Pulumi Cloud. It can assist with Pulumi IaC authoring and deployment. Let's have an intelligent conversation with Pulumi Copilot to help us start writing a Python-based Pulumi program that will also have access to the previously created ESC environment.&lt;/p&gt;

&lt;p&gt;Prompt Pulumi Copilot with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can you help me create a new and empty Python Pulumi project called "my-cool-chat-app" with a new stack called dev? Add "my-cool-chat-app-provider-creds" to the imports in the dev stack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Declare New Relic AI LLM monitoring dashboards
&lt;/h4&gt;

&lt;p&gt;A standard method for sharing dashboards is through the &lt;a href="https://docs.newrelic.com/docs/query-your-data/explore-query-data/dashboards/dashboards-charts-import-export-data/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;JSON copy and import feature&lt;/a&gt;. However, importing these through the console can result in reproducibility issues over time. For example, what happens when the dashboard JSON definition changes in an undesirable way? It becomes a challenge because there are no versioning details readily available.&lt;/p&gt;

&lt;p&gt;Instead, using a declarative approach to "import" the JSON file unlocks several benefits. It allows for managing the dashboard's lifecycle (creation, deletion, updates) through code, thereby tracking changes over time. Also, it makes it easy to incorporate into deployment pipelines and share these across teams.&lt;/p&gt;

&lt;p&gt;You have an AI/LLM monitoring dashboard JSON file and want to use it to create a new dashboard under our New Relic account. Let's continue our chat with Pulumi Copilot and prompt it to update the current solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Okay great! Can you update the Python code to deploy a New Relic dashboard based on an existing JSON file I will provide as input?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Declare a Pinecone index
&lt;/h4&gt;

&lt;p&gt;A Pinecone index was needed beforehand to test the chat application locally. Let's ensure its existence before deploying the chat application to the cloud.&lt;/p&gt;

&lt;p&gt;Let's ask Pulumi Copilot to define this resource on our behalf:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thank you! I also need a serverless Pinecone index named "games" in the "default" namespace on AWS us-east-1 with 1536 dimensions. Can you generate the Python code to define this resource?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Declare an Amazon EC2 instance
&lt;/h4&gt;

&lt;p&gt;To test the chat application in a cloud environment, you'll use an EC2 instance. Let's ask Pulumi Copilot to define all the AWS resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Perfect! I also want to deploy my chat application to an Amazon EC2 Linux instance. 
Create a VPC, security group, public subnet, and route table for the EC2 instance.
Ensure the security group allows inbound SSH traffic on port 22 from anywhere.
Ensure the EC2 instance is publicly accessible and runs a Docker Compose command to start the application.
Associate the EC2 instance with a public IP
Update the EC2 instance with a depends_on resource option for the route table association.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Deploy the application with Pulumi
&lt;/h4&gt;

&lt;p&gt;You’ve asked Copilot to help with the Python infrastructure code, so it's time to deploy our application. In the chat window, expand the &lt;strong&gt;Pulumi Code&lt;/strong&gt; drop-down. Click the &lt;strong&gt;Deploy with Pulumi&lt;/strong&gt; button to create a new project.&lt;/p&gt;

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

&lt;p&gt;Once you download the project, you'll add credentials, modify the code slightly, and deploy our application on AWS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the &lt;strong&gt;Deploy with Pulumi&lt;/strong&gt; button to create a new project. Then,&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;CLI Deployment&lt;/strong&gt; deployment method and click &lt;strong&gt;Create Project&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Follow step 3 from the "Get started" steps in the next window to download the project onto your development environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given that you already have a relatively small application in a GitHub repository, you’ll add a new empty folder at the root level named &lt;strong&gt;infra&lt;/strong&gt;, where you'll unzip the contents of the Pulumi project. Compare your solution with the &lt;a href="https://github.com/desteves/ai-chat-app/tree/main/infra" rel="noopener noreferrer"&gt;final version hosted on GitHub&lt;/a&gt; and fix any minor details Copilot may have overlooked.&lt;/p&gt;

&lt;p&gt;Also, include the following changes from the final version shared:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the custom &lt;a href="https://github.com/desteves/ai-chat-app/blob/main/infra/aws_module.py#L97" rel="noopener noreferrer"&gt;user_data&lt;/a&gt; script.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/desteves/ai-chat-app/blob/main/infra/newrelic_module.py#L12" rel="noopener noreferrer"&gt;Update the dashboard.json to include your New Relic account id&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Optionally, include the &lt;a href="https://github.com/desteves/ai-chat-app/blob/main/infra/docker_build_module.py" rel="noopener noreferrer"&gt;Docker build code&lt;/a&gt; to build and push the images to Dockerhub.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more, visit the &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/copilot/" rel="noopener noreferrer"&gt;Pulumi Copilot documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In order for Pulumi to deploy all the declared resources, it needs access to your cloud accounts. These credentials will reside in a Pulumi ESC Environment named "my-cool-chat-app-provider-creds". Refer to the &lt;a href="https://github.com/desteves/ai-chat-app/tree/main?tab=readme-ov-file#2-store-infra-secrets-in-pulumi-esc" rel="noopener noreferrer"&gt;README&lt;/a&gt; to configure the Environment and set up the Python virtual environment before deploying everything via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pulumi up &lt;span class="nt"&gt;--stack&lt;/span&gt; dev  &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes about a minute for all resources to be created. Once created, access the public URL displayed and run load tests.&lt;/p&gt;

&lt;p&gt;Example partial output from the above command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;     Type                                Name                        Status              
 +   pulumi:pulumi:Stack                 my-cool-chat-app-dev-dev    created &lt;span class="o"&gt;(&lt;/span&gt;57s&lt;span class="o"&gt;)&lt;/span&gt;       
 +   ├─ newrelic:index:OneDashboardJson  my_cool_dashboard           created &lt;span class="o"&gt;(&lt;/span&gt;2s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ pinecone:index:PineconeIndex     my_cool_index               created &lt;span class="o"&gt;(&lt;/span&gt;7s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ docker-build:index:Image         ai-chat-demo-api            created &lt;span class="o"&gt;(&lt;/span&gt;2s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ docker-build:index:Image         ai-chat-demo-web            created &lt;span class="o"&gt;(&lt;/span&gt;3s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ aws:ec2:Vpc                      my_cool_vpc                 created &lt;span class="o"&gt;(&lt;/span&gt;13s&lt;span class="o"&gt;)&lt;/span&gt;       
 +   ├─ aws:ec2:Subnet                   my_cool_subnet              created &lt;span class="o"&gt;(&lt;/span&gt;11s&lt;span class="o"&gt;)&lt;/span&gt;       
 +   ├─ aws:ec2:SecurityGroup            my_cool_security_group      created &lt;span class="o"&gt;(&lt;/span&gt;4s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ aws:ec2:InternetGateway          my_cool_igw                 created &lt;span class="o"&gt;(&lt;/span&gt;1s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ aws:ec2:RouteTable               my_cool_route_table         created &lt;span class="o"&gt;(&lt;/span&gt;2s&lt;span class="o"&gt;)&lt;/span&gt;        
 +   ├─ aws:ec2:RouteTableAssociation    my-route-table-association  created &lt;span class="o"&gt;(&lt;/span&gt;0.89s&lt;span class="o"&gt;)&lt;/span&gt;     
 +   └─ aws:ec2:Instance                 my_cool_instance            created &lt;span class="o"&gt;(&lt;/span&gt;24s&lt;span class="o"&gt;)&lt;/span&gt;       

Outputs:
    url: &lt;span class="s2"&gt;"52.41.60.240"&lt;/span&gt;

Resources:
    + 12 created

Duration: 1m0s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explore your New Relic AI LLM dashboards
&lt;/h3&gt;

&lt;p&gt;To recap, the chat application is configured to observe its performance, such as traces, metrics, and logs, using the New Relic APM agent and the infrastructure agent. Now that we’ve simulated traffic, let's review the collected telemetry data in New Relic.&lt;/p&gt;

&lt;h4&gt;
  
  
  AI Response metrics
&lt;/h4&gt;

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

&lt;p&gt;The &lt;strong&gt;AI Responses&lt;/strong&gt; section will highlight key metrics when observing your AI/LLM applications. It includes data such as &lt;strong&gt;Total responses&lt;/strong&gt;, &lt;strong&gt;Response time&lt;/strong&gt;, &lt;strong&gt;Token usage per response,&lt;/strong&gt; and &lt;strong&gt;Errors&lt;/strong&gt; within your AI interactions. Time series graphs show you the same information with some more historical context.&lt;/p&gt;

&lt;p&gt;The bottom part of that screen provides more insights into the requests and responses your end customers used to interact with the chat application.&lt;/p&gt;

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

&lt;h4&gt;
  
  
  AI Model comparison
&lt;/h4&gt;

&lt;p&gt;Another very important aspect of New Relic AI monitoring is the &lt;strong&gt;Model Inventory&lt;/strong&gt; section.&lt;/p&gt;

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

&lt;p&gt;This view provides an intuitive overview of all your AI/LLM models being leveraged in our chat application. As you can see, we ran the same application with OpenAI models &lt;strong&gt;GPT-3.5 Turbo&lt;/strong&gt;, &lt;strong&gt;GPT-4 Turbo,&lt;/strong&gt; and &lt;strong&gt;GPT-4o&lt;/strong&gt;. The AI model used is reflected in the &lt;a href="https://github.com/desteves/ai-chat-app/blob/ae7090cbc6d0b6d2adcdc72d6f4d50aa22121ff9/app/api/src/ai.ts#L13" rel="noopener noreferrer"&gt;chatModel variable for the API AI backend.&lt;/a&gt; This view shows you all the critical aspects of the performance, quality of responses, errors, and cost at a glance.&lt;/p&gt;

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

&lt;p&gt;When combining the raw data from AI monitoring and custom &lt;a href="https://docs.newrelic.com/docs/logs/ui-data/lookup-tables-ui/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q3-devtoupdates" rel="noopener noreferrer"&gt;lookup tables&lt;/a&gt;, New Relic also allows you to build custom dashboards (see Deploy the application with Pulumi for a reference to import custom dashboards). These custom dashboards can bring additional data, such as the actual &lt;a href="https://openai.com/api/pricing/" rel="noopener noreferrer"&gt;cost (in $) for my OpenAI platform&lt;/a&gt;, and leverage the input and output tokens from our monitoring to calculate the total AI cost for running the chat application.&lt;/p&gt;

&lt;h4&gt;
  
  
  OpenAI custom dashboards
&lt;/h4&gt;

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

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;In this guide, you explored an AI demo application powered by OpenAI and Pinecone. The application uses New Relic AI dashboards to monitor costs and other performance metrics. You used Pulimi Copilot to generate all the cloud components needed to run the chat application in AWS successfully while storing all sensitive information in Pulumi ESC.&lt;/p&gt;

&lt;p&gt;Join us in the &lt;a href="https://www.pulumi.com/resources/observability-as-code-for-ai-apps-new-relic/" rel="noopener noreferrer"&gt;Observability as Code for AI Apps with New Relic and Pulumi&lt;/a&gt; virtual workshop, where you'll see the chat application, Pulumi, and New Relic in action.&lt;/p&gt;

</description>
      <category>observability</category>
      <category>ai</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>New Relic Integrates its Observability Platform with NVIDIA NIM to Accelerate AI Adoption and ROI</title>
      <dc:creator>samanthadondero</dc:creator>
      <pubDate>Mon, 24 Jun 2024 22:16:30 +0000</pubDate>
      <link>https://forem.com/newrelic/new-relic-integrates-its-observability-platform-with-nvidia-nim-to-accelerate-ai-adoption-and-roi-514l</link>
      <guid>https://forem.com/newrelic/new-relic-integrates-its-observability-platform-with-nvidia-nim-to-accelerate-ai-adoption-and-roi-514l</guid>
      <description>&lt;p&gt;Hi, devs! &lt;/p&gt;

&lt;p&gt;Today we're announcing that New Relic and NVIDIA released the first observability integration making it easy for companies to monitor the health and performance of their AI applications built with NVIDIA NIM. &lt;/p&gt;

&lt;p&gt;Key features and use cases for AI monitoring include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full AI stack integration&lt;/li&gt;
&lt;li&gt;Deep trace insights for every response &lt;/li&gt;
&lt;li&gt;Model inventory &lt;/li&gt;
&lt;li&gt;Deep GPU insights&lt;/li&gt;
&lt;li&gt;Enhanced data security &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;➡️ &lt;a href="https://newrelic.com/blog/how-to-relic/ai-monitoring-for-nvidia-nim?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-ai-monitoring-for-nvidia-nim"&gt;Check it out&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-Sam&lt;/p&gt;

</description>
      <category>ai</category>
      <category>observability</category>
    </item>
    <item>
      <title>Using .NET Aspire eShop application to collect all the telemetry</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Mon, 10 Jun 2024 08:15:37 +0000</pubDate>
      <link>https://forem.com/newrelic/using-net-aspire-eshop-application-to-collect-all-the-telemetry-1olp</link>
      <guid>https://forem.com/newrelic/using-net-aspire-eshop-application-to-collect-all-the-telemetry-1olp</guid>
      <description>&lt;p&gt;To read this full article, &lt;a href="https://newrelic.com/blog/how-to-relic/using-net-aspire-eshop-application-to-collect-all-the-telemetry?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Learn how to collect all the telemetry from the .NET Aspire eShop application and send it to an OpenTelemetry backend such as New Relic&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview"&gt;.NET Aspire&lt;/a&gt; is the new kid on the block when it comes to an opinionated, cloud-ready stack for building observable, production-ready, distributed applications. Having a built-in dashboard for the monitoring data is nice during development. But how do you configure OpenTelemetry correctly to send it to an observability backend? This is what this blog post is all about. And you’ll also learn how to send custom attributes by leveraging OpenTelemetry SDKs.&lt;/p&gt;

&lt;h2&gt;
  
  
  .NET Aspire
&lt;/h2&gt;

&lt;p&gt;.NET Aspire was first announced and introduced at &lt;a href="https://www.youtube.com/watch?v=mna5fg7QGz8&amp;amp;t=2655s"&gt;.NET Conf 2023 Keynote&lt;/a&gt;. The challenges it tries to solve are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complex&lt;/strong&gt;: Cloud computing is fundamentally hard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting started&lt;/strong&gt;: For new developers in this space, a first step into cloud native can be overwhelming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choices&lt;/strong&gt;: Developers need to make a lot of choices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paved path&lt;/strong&gt;: .NET did not have a golden paved path available for developers to build cloud-native applications.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This is exactly where .NET Aspire comes into play. It includes the following features as part of the stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f9gd6ebc415hj3dhr2s.png" alt="Image description" width="800" height="398"&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/components-overview"&gt;Components&lt;/a&gt;: Curated suite of NuGet packages specifically selected to facilitate the integration of cloud-native applications with prominent services and platforms, including but not limited to Redis and PostgreSQL. Each component furnishes essential cloud-native functionalities through either automatic provisioning or standardized configuration patterns.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqc4w322gwii2ub7hgdd.png" alt="Image description" width="800" height="401"&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard"&gt;Developer Dashboard&lt;/a&gt;: Allows you to track closely various aspects of your application, including logs, traces, and environment configurations, all in real time. It’s purpose-built to enhance the local development experience, providing an insightful overview of your app’s state and structure.&lt;/li&gt;
&lt;li&gt;
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuu73qjpofmex0hzgqu5k.png" alt="Image description" width="800" height="422"&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview#why-net-aspire"&gt;Tooling/Orchestration&lt;/a&gt;: .NET Aspire includes project templates and tooling experiences for Visual Studio and the dotnet command-line interface (CLI) help you create and interact with .NET Aspire apps. It also provides features for running and connecting multi-project applications and their dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  eShop demo application
&lt;/h2&gt;

&lt;p&gt;A reference .NET application implementing an ecommerce website using a services-based architecture.&lt;/p&gt;

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

&lt;p&gt;In the latest version of the application, the source code is already updated to include .NET Aspire as part of the project. You can install the latest &lt;a href="https://github.com/dotnet/installer#installers-and-binaries"&gt;.NET 8 SDK&lt;/a&gt; and clone the repository. Additionally, you can run the following commands to install the Aspire workload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet workload update
dotnet workload &lt;span class="nb"&gt;install &lt;/span&gt;aspire
dotnet restore eShop.Web.slnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have all the other prerequisites ready on your machine, you can run the application from your terminal with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; src/eShop.AppHost/eShop.AppHost.csproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  .NET Aspire developer dashboard
&lt;/h2&gt;

&lt;p&gt;Once the application is up and running, go to the developer dashboard to identify the various resources that are part of the eShop application, including the endpoints and URL(s) to reach the running resources directly.&lt;/p&gt;

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

&lt;p&gt;This dashboard also includes monitoring telemetry, including logs, traces, and metrics.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  .NET Aspire orchestration
&lt;/h2&gt;

&lt;p&gt;.NET Aspire provides APIs for expressing resources and dependencies within your distributed application.&lt;/p&gt;

&lt;p&gt;Before continuing, consider some common terminology used in .NET Aspire:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App model&lt;/strong&gt;: A collection of resources that make up your distributed application (&lt;a href="https://learn.microsoft.com/en-us/dotnet/api/aspire.hosting.distributedapplication"&gt;DistributedApplication&lt;/a&gt;). For a more formal definition, see &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/app-host-overview#define-the-app-model"&gt;Define the app model&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App host/Orchestrator project&lt;/strong&gt;: The .NET project that orchestrates the app model, named with the *.AppHost suffix (by convention).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource&lt;/strong&gt;: A &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/app-host-overview#built-in-resource-types"&gt;resource&lt;/a&gt; represents a part of an application whether it be a .NET project, container, or executable, or some other resource like a database, cache, or cloud service (such as a storage service).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference&lt;/strong&gt;: A reference defines a connection between resources, expressed as a dependency. For more information, see &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/app-host-overview#reference-resources"&gt;Reference resources&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;.NET Aspire empowers you to seamlessly build, provision, deploy, configure, test, run, and observe your cloud application. This is achieved through the utilization of an app model that outlines the resources in your app and their relationships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending telemetry to an OpenTelemetry backend such as New Relic
&lt;/h2&gt;

&lt;p&gt;Having a built-in dashboard for the monitoring data is nice during development. In this section I focus on how to configure OpenTelemetry correctly to send all telemetry into New Relic as my observability backend of choice.&lt;/p&gt;

&lt;p&gt;For the scenario described in this article, I created my own fork of the official eShop application. Within this &lt;a href="https://github.com/harrykimpel/dotnet-eShop"&gt;repository&lt;/a&gt;, you’ll be able to find the &lt;a href="https://github.com/harrykimpel/dotnet-eShop/tree/main/src/eShop.AppHost"&gt;app host project&lt;/a&gt; that contains its &lt;a href="https://github.com/harrykimpel/dotnet-eShop/blob/main/src/eShop.AppHost/Program.cs"&gt;main component&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lines 17 through 26 define some basic configuration variables that you can provide using environment variables in your terminal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NEW_RELIC_LICENSE_KEY&lt;/strong&gt;: New Relic license key for the OpenTelemetry protocol (OTLP) API header value&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NEW_RELIC_REGION&lt;/strong&gt;: US or EU region configuration for your New Relic account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Based on the New Relic region configuration, the code will define the &lt;a href="https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-set-up-your-app/#review-settings?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;New Relic OTLP endpoint for OpenTelemetry&lt;/a&gt; and use it in the &lt;strong&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/strong&gt; variable.&lt;/p&gt;

&lt;p&gt;The rest of the app host project is already prepared to add an environment configuration for each of the projects that are part of the Aspire application. For example, here’s the configuration for the &lt;a href="https://github.com/harrykimpel/dotnet-eShop/tree/main/src/Identity.API"&gt;Identity.API project&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// Services&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;identityApi&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Identity_API&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"identity-api"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;identityDb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OTEL_EXPORTER_OTLP_ENDPOINT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OTEL_EXPORTER_OTLP_HEADERS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OTEL_EXPORTER_OTLP_HEADERS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OTEL_SERVICE_NAME"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"identity-api"&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;In this fork of the eShop application I’ve added some additional environment configuration. Each of the &lt;strong&gt;.WithEnvironment&lt;/strong&gt; statements adds a necessary environment variable for the service:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/strong&gt;: The OTLP endpoint for all the telemetry for this service; in our case, the New Relic OTLP endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTEL_EXPORTER_OTLP_HEADERS&lt;/strong&gt;: The API header value, which includes our New Relic license key (&lt;strong&gt;string OTEL_EXPORTER_OTLP_HEADERS = "api-key=" + NEW_RELIC_LICENSE_KEY;&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OTEL_SERVICE_NAME&lt;/strong&gt;: The name of the service relevant to create a respective entity in New Relic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rest of the services are configured appropriately.&lt;/p&gt;

&lt;p&gt;Once you’ve configured the environment variables in your terminal (that is, &lt;strong&gt;NEW_RELIC_LICENSE_KEY&lt;/strong&gt; and &lt;strong&gt;NEW_RELIC_REGION&lt;/strong&gt;), you can start the Aspire application with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; src/eShop.AppHost/eShop.AppHost.csproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can confirm whether everything is configured correctly by looking at the environment and clicking on the view icon for one of the projects:&lt;/p&gt;

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

&lt;p&gt;The &lt;strong&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/strong&gt; should point to the New Relic OTLP endpoint.&lt;/p&gt;

&lt;p&gt;After a little while, you should be able to see data from your application visible in the &lt;strong&gt;APM &amp;amp; Services - OpenTelemetry&lt;/strong&gt; section of New Relic:&lt;/p&gt;

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

&lt;p&gt;You can then observe and analyze all your telemetry. For example, look at the &lt;strong&gt;New Relic Services map&lt;/strong&gt;:&lt;/p&gt;

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

&lt;p&gt;… or the distributed tracing view:&lt;/p&gt;

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

&lt;p&gt;Happy observing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Integrating OpenTelemetry with the .NET Aspire eShop application and New Relic allows you to leverage powerful telemetry tools to monitor and improve your application's performance. This setup not only provides valuable insights but also enhances your ability to diagnose issues quickly and efficiently. With the steps outlined in this guide, you're well on your way to building a more resilient and observant application. Start harnessing the full potential of your telemetry data today and keep your systems running smoothly!&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explore more&lt;/strong&gt;: Dive deeper into &lt;a href="https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/opentelemetry-introduction/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;New Relic’s OpenTelemetry documentation&lt;/a&gt; to unlock advanced features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Join the community&lt;/strong&gt;: Engage with other developers on New Relic’s community forum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay updated&lt;/strong&gt;: Follow &lt;a href="https://newrelic.com/blog?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;our blog&lt;/a&gt; for the latest tips, tutorials, and industry news.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try New Relic for free&lt;/strong&gt;: Sign up for a &lt;a href="https://www.newrelic.com/signup?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;free New Relic account&lt;/a&gt; and start exploring how New Relic can enhance your application's telemetry today.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experiment and iterate&lt;/strong&gt;: Continuously monitor, analyze, and improve your telemetry setup for peak performance.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>observability</category>
      <category>opensource</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>How to observe your Blazor WebAssembly application with OpenTelemetry and real user monitoring</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Mon, 10 Jun 2024 08:01:46 +0000</pubDate>
      <link>https://forem.com/newrelic/how-to-observe-your-blazor-webassembly-application-with-opentelemetry-and-real-user-monitoring-kfn</link>
      <guid>https://forem.com/newrelic/how-to-observe-your-blazor-webassembly-application-with-opentelemetry-and-real-user-monitoring-kfn</guid>
      <description>&lt;p&gt;To read this full article, &lt;a href="https://newrelic.com/blog/how-to-relic/how-to-observe-your-blazor-webassembly-application-with-opentelemetry-and-real-user-monitoring?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Observing WebAssembly applications presents unique challenges that stem from its design and execution environment. Unlike traditional web applications, where monitoring tools can hook directly into JavaScript and the Document Object Model (DOM), WebAssembly runs as binary code executed within the browser's sandbox. This layer of abstraction complicates direct introspection, as traditional monitoring tools are not designed to interact with the lower-level operations of WebAssembly. The &lt;a href="https://bytecodealliance.org/"&gt;Bytecode Alliance&lt;/a&gt; plays a crucial role here, promoting standards and tools that aim to enhance the security and usability of WebAssembly, including better support for observability. Moreover, the performance characteristics of WebAssembly, which can closely approach native speeds, demand monitoring solutions that are both highly efficient and minimally invasive to avoid impacting the user experience. This creates a complex scenario for developers who need detailed visibility into their applications' behavior without sacrificing performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blazor WebAssembly: Leveraging .NET in the browser
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-8.0"&gt;.NET Blazor WebAssembly&lt;/a&gt; is a cutting-edge framework that allows developers to build interactive client-side web UIs using .NET rather than JavaScript. By compiling C# code into WebAssembly, Blazor WebAssembly empowers developers to leverage the full-stack capabilities of .NET, utilizing the same language and libraries on both the server and client sides. This unique approach streamlines the development process and enables rich, responsive user experiences with significant performance benefits.&lt;/p&gt;

&lt;p&gt;With the release of .NET 8, Blazor WebAssembly has introduced new rendering modes that enhance flexibility and performance across diverse deployment scenarios. These modes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Static server rendering&lt;/strong&gt; (also called static server-side rendering or static SSR) to generate static HTML on the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive server rendering&lt;/strong&gt; (also called interactive server-side rendering or interactive SSR) to generate interactive components with prerendering on the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive WebAssembly rendering&lt;/strong&gt; (also called client-side rendering or CSR, which is always assumed to be interactive) to generate interactive components on the client with prerendering on the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive auto (automatic) rendering&lt;/strong&gt; to initially use the server-side ASP.NET Core runtime for content rendering and interactivity. The .NET WebAssembly runtime on the client is used for subsequent rendering and interactivity after the Blazor bundle is downloaded and the WebAssembly runtime activates. Interactive auto rendering usually provides the fastest app startup experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The auto rendering mode in particular make Blazor WebAssembly an even more compelling choice for developers who are looking to build modern web applications using .NET technologies.&lt;/p&gt;

&lt;p&gt;This blog post focuses specifically on Blazor WebAssembly and explores its capabilities and practical applications in modern web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhancing Blazor WebAssembly observability with OpenTelemetry in .NET
&lt;/h2&gt;

&lt;p&gt;In this exploration of Blazor WebAssembly, we delve into how OpenTelemetry (sometimes referred to as OTel) can be integrated with .NET to provide comprehensive observability for these applications. OpenTelemetry, a set of APIs, libraries, agents, and instrumentation, allows developers to collect and export telemetry data such as traces, metrics, and logs to analyze the performance and health of applications. For .NET developers, the integration with OpenTelemetry is particularly seamless, as all telemetry for .NET is considered stable, ensuring reliability and robust support across various deployment scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring a sample Blazor WebAssembly application
&lt;/h2&gt;

&lt;p&gt;In this blog post, we'll be utilizing a sample application that embodies the principles of Blazor WebAssembly combined with OpenTelemetry. The application, which can be found in the &lt;a href="https://github.com/harrykimpel/dotnet-blazor-samples/tree/main/8.0/BlazorWebAssemblyStandaloneWithIdentity"&gt;GitHub repository&lt;/a&gt;, serves as an excellent example of a standalone Blazor WebAssembly application. This practical example will serve as the foundation for our discussion on implementing and observing OpenTelemetry in a .NET environment. By dissecting this application, we can better understand the interaction between Blazor’s client-side component as a Blazor WebAssembly application running in the browser and a Blazor WebAssembly backend application that the web frontend talks to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated and manual instrumentation of the backend
&lt;/h2&gt;

&lt;p&gt;When deploying OpenTelemetry in a Blazor WebAssembly application, automated instrumentation becomes a pivotal component, particularly when interfacing with the .NET backend. OpenTelemetry's .NET libraries offer out-of-the-box instrumentation for ASP.NET Core, which effortlessly captures telemetry data such as HTTP requests, database queries, and much more. This automated process simplifies the task of implementing comprehensive monitoring, as it requires minimal manual configuration and coding. Additionally, integrating OpenTelemetry into your project is as straightforward as adding the respective NuGet packages to your solution.&lt;/p&gt;

&lt;p&gt;For developers working with Blazor WebAssembly, this means enhanced visibility into the backend operations that power their applications. Automated instrumentation ensures that all relevant data transactions between the client and server are meticulously monitored, providing insights into performance metrics and potential bottlenecks. By leveraging this feature, developers can focus more on building features and less on the intricacies of setting up and maintaining observability infrastructure, making it easier to deliver high-performance, reliable applications.&lt;/p&gt;

&lt;p&gt;The project file for the .NET Blazor WebAssembly backend looks like this (you can find the full &lt;a href="https://github.com/harrykimpel/dotnet-blazor-samples/blob/main/8.0/BlazorWebAssemblyStandaloneWithIdentity/Backend/Backend.csproj"&gt;project file in the repository&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;lt;PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.0" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.9" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.8.0" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry" Version="1.8.0" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.AutoInstrumentation.Runtime.Native" Version="1.5.0" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.8.0" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.8.0" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" /&amp;gt;
   &amp;lt;PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;When running the Blazor backend with automated OpenTelemetry instrumentation and exporting the telemetry to the console, we can easily see the traces, metrics, and logs as part of the console output (here in VS Code terminal).&lt;/p&gt;

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

&lt;p&gt;But looking at telemetry such as traces, metrics, and logs in the console output is not really helpful. So, ideally, we want to export that data to an OpenTelemetry telemetry backend. I am of course using New Relic.&lt;/p&gt;

&lt;p&gt;In a typical OpenTelemetry fashion, I only need to provide a few environment variables when executing the application. I highlighted the most important ones in the below screenshot. You can find the full &lt;a href="https://github.com/harrykimpel/dotnet-blazor-samples/blob/main/8.0/BlazorWebAssemblyStandaloneWithIdentity/Backend/run.sh"&gt;run script in the repository&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Once the application is up and running, you find the application entity in APM &amp;amp; Services under the OpenTelemetry section. The screenshot below shows the &lt;strong&gt;Summary&lt;/strong&gt; view.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Distributed Tracing&lt;/strong&gt; view:&lt;/p&gt;

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

&lt;p&gt;View of a single trace (I highlighted the backend span to &lt;strong&gt;/roles&lt;/strong&gt; endpoint):&lt;/p&gt;

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

&lt;p&gt;When you look at the above span to the &lt;strong&gt;BlazorWASMBackend&lt;/strong&gt; service &lt;strong&gt;GET /roles&lt;/strong&gt;, you’ll notice that the total time spent in the backend span is 4.61s. We cannot really tell where exactly the time is spent. Out of the box, when using auto instrumentation, I don’t get further detail into what is actually happening in that method.&lt;/p&gt;

&lt;p&gt;In order for me to provide more details into that method, I’ll need to add some manual instrumentation into my source code by leveraging the OpenTelemetry SDK for .NET.&lt;/p&gt;

&lt;p&gt;In this case, I changed the original code of the&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;app.MapGet("/roles", …&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 method from this original implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;           // Instantiate random number generator using system-supplied value as seed.
           var rand = new Random();
           int waitTime = rand.Next(500, 5000);

           // do some heavy lifting work
           Thread.Sleep(waitTime);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and added in some .NET-specific implementation of a custom OpenTelemetry span:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;           // Instantiate random number generator using system-supplied value as seed.
           var rand = new Random();
           int waitTime = rand.Next(500, 5000);


           using (var sleepActivity = DiagnosticsConfig.ActivitySource.StartActivity("RolesHeavyLiftingSleep"))
           {
               // do some heavy lifting work
               Thread.Sleep(waitTime);


               string waitMsg = string.Format(@"ChildActivty simulated wait ({0}ms)", waitTime);
               sleepActivity?.SetTag("simulatedWaitMsg", waitMsg);
               sleepActivity?.SetTag("simulatedWaitTimeMs", waitTime);
               DiagnosticsConfig.logger.LogInformation(eventId: 123, waitMsg);
           }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The using-block actually triggers a new span to be created with the name &lt;strong&gt;RolesHeavyLiftingSleep&lt;/strong&gt;. I save the activity into the &lt;strong&gt;sleepActivity&lt;/strong&gt; variable. You’ll further notice that I’m also adding some custom tags to that same activity by calling &lt;strong&gt;sleepActivity?.SetTag()&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We can see in the screenshot below what the result of that change looks like if we restart our application.&lt;/p&gt;

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

&lt;p&gt;The trace in the screenshot above allows me to drill deeper into the backend span by enabling the in-process spans. In here, we can see that there’s a &lt;strong&gt;RolesParentActivity&lt;/strong&gt;, followed by a &lt;strong&gt;RolesChildActivity&lt;/strong&gt;, and finally our &lt;strong&gt;RolesHeavyLiftingSleep&lt;/strong&gt; span from our manual instrumentation. This screenshot also shows a section of the attributes that are associated with that span. As you can see, the custom tags &lt;strong&gt;simulatedWaitTimeMs&lt;/strong&gt; and &lt;strong&gt;simulatedWaitMsg&lt;/strong&gt; are visible as well. These custom tags are potentially helpful when doing some root cause analysis or troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instrumentation of the frontend
&lt;/h2&gt;

&lt;p&gt;Now that we’ve seen how the backend can be instrumented with OpenTelemetry, let’s focus on the frontend now, that is, the Blazor WebAssembly component.&lt;/p&gt;

&lt;p&gt;When we try to instrument the WebAssembly component with auto instrumentation for OpenTelemetry, the &lt;a href="https://github.com/harrykimpel/dotnet-blazor-samples/blob/main/8.0/BlazorWebAssemblyStandaloneWithIdentity/BlazorWasmAuth/BlazorWasmAuth.csproj"&gt;C# project file&lt;/a&gt; looks similar to the backend. This is actually the benefit of Blazow WebAssembly—that we can use C# not only for the backend, but also for the WebAssembly frontend.&lt;/p&gt;

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

&lt;p&gt;Let’s configure the console exporter again for our OpenTelemetry telemetry. Unsurprisingly, the output will be visible in the respective developer tools of our web browser.&lt;/p&gt;

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

&lt;p&gt;The screenshot above shows the actual UI of the Blazor WebAssembly frontend in the upper section of the screenshot. If the user of the application clicks the &lt;strong&gt;Click me&lt;/strong&gt; button, a trace is generated and output in the browsers console view.&lt;/p&gt;

&lt;p&gt;Again, this is adequate for testing, but in order to actually leverage the telemetry in a meaningful way, we need to export all telemetry to an OpenTelemetry backend, in my case New Relic. For this to happen, we need to define an OpenTelemetry protocol (OTLP) exporter and configure the OTLP endpoint as well as the OTLP header information similar to what we’ve seen for the backend.&lt;/p&gt;

&lt;p&gt;But wait; as soon as we implement these changes and rerun the application, an exception is generated.&lt;/p&gt;

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

&lt;p&gt;The exception is &lt;strong&gt;Operation is not supported on this platform&lt;/strong&gt;. If we think about it, it does make sense since we’re trying to make a HTTP request from our WebAssembly component to an external endpoint. However, since WebAssembly by itself doesn't have any access to its host environment, it doesn't have any built-in input/output (I/O) capabilities. For security reasons, it’s not possible to make HTTP requests from within a WebAssembly component.&lt;/p&gt;

&lt;p&gt;So, if plain OpenTelemetry instrumentation isn’t possible, what is it that we can do for the frontend then?&lt;/p&gt;

&lt;p&gt;As part of OpenTelemetry, the community is also working on some real user monitoring capabilities.&lt;/p&gt;

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

&lt;p&gt;However, this is very early stages and not fully spec’d out. The current draft is also only focusing on Node.js and TypeScript. In the future this may be an option that could be leveraged for the frontend component.&lt;/p&gt;

&lt;p&gt;One way to get details of the WebAssembly component is to leverage real user monitoring capabilities via the New Relic browser.&lt;/p&gt;

&lt;p&gt;After getting the JavaScript snippet from a newly created New Relic browser application copied into the Blazor WebAssembly project (&lt;a href="https://github.com/harrykimpel/dotnet-blazor-samples/blob/main/8.0/BlazorWebAssemblyStandaloneWithIdentity/BlazorWasmAuth/wwwroot/newrelic.js"&gt;this&lt;/a&gt; is the place to put it), we can already see some high-level telemetry from the frontend.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Distributed tracing&lt;/strong&gt; view:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;AJAX&lt;/strong&gt; requests:&lt;/p&gt;

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

&lt;p&gt;What else can we do with the frontend? Some parts of the frontend will have interactions with the backend (like login and logout authentication). Other parts just execute code within the WebAssembly component. An example of this is the &lt;strong&gt;Counter&lt;/strong&gt; section.&lt;/p&gt;

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

&lt;p&gt;As you can see in the page source of that page, there’s no actual HTML representation.&lt;/p&gt;

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

&lt;p&gt;Let’s see what we can do there.&lt;/p&gt;

&lt;p&gt;One way is to invoke JavaScript functions from the actual .NET code. The following screenshot shows how this can be achieved (here is the link to the &lt;strong&gt;respective file&lt;/strong&gt; in the repository).&lt;/p&gt;

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

&lt;p&gt;The New Relic browser API allows users to add some custom page actions. This way we can observe all clicks on the counter and also capture the current value of the counter as a custom attribute.&lt;/p&gt;

&lt;p&gt;Once we’ve implemented this and deployed a new release of the application, we can for example show this data on a custom dashboard to see the distribution of the actual counter values across all users of the application.&lt;/p&gt;

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

&lt;p&gt;Furthermore, New Relic quickstarts, also known as Instant Observability, contain a sample dashboard that you can deploy into your account in order to see some additional Blazor WebAssembly specific telemetry in a pre-built dashboard.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Observing Blazor WebAssembly applications is not quite straightforward as of today. There are many moving parts that the industry and the respective open-source communities are working on. This applies to the WebAssembly component model, as well as the OpenTelemetry implementation of real user monitoring. I think these challenges will soon be solved and there will be easier ways to get started.&lt;/p&gt;

&lt;p&gt;Until then, in this blog post I showed a way to get some insights into your Blazor WebAssembly backend and frontend components.&lt;/p&gt;

&lt;p&gt;New Relic provides a &lt;a href="https://newrelic.com/signup?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates"&gt;free account&lt;/a&gt; that you can use to get started with your journey on observing Blazor WebAssembly applications.&lt;/p&gt;

</description>
      <category>observability</category>
      <category>opentelemetry</category>
      <category>opensource</category>
    </item>
    <item>
      <title>New Relic AI monitoring, the industry’s first APM for AI, is here!</title>
      <dc:creator>samanthadondero</dc:creator>
      <pubDate>Tue, 23 Apr 2024 22:28:52 +0000</pubDate>
      <link>https://forem.com/newrelic/new-relic-ai-monitoring-the-industrys-first-apm-for-ai-is-here-46af</link>
      <guid>https://forem.com/newrelic/new-relic-ai-monitoring-the-industrys-first-apm-for-ai-is-here-46af</guid>
      <description>&lt;p&gt;Hi, devs! &lt;/p&gt;

&lt;p&gt;Want to know how you can streamline troubleshooting and optimize for performance, quality, and cost all in one? &lt;/p&gt;

&lt;p&gt;New Relic AI monitoring provides engineers and developers unprecedented visibility across your AI stack, making it easier to troubleshoot and optimize your AI applications for performance and more!&lt;/p&gt;

&lt;p&gt;Key features and benefits include: &lt;br&gt;
Quick and easy setup via existing APM agents&lt;br&gt;
Visibility across the entire AI app stack&lt;br&gt;
Deep trace insights  with end-user feedback for every response&lt;br&gt;
Compare performance and costs across models in production&lt;br&gt;
Enhanced data privacy and security&lt;/p&gt;

&lt;p&gt;➡️ &lt;a href="https://newrelic.com/blog/nerdlog/ai-monitoring-ga?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-ai-monitoring-ga"&gt;Get started now&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-Sam&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Guide: How to route Docker logs correctly in New Relic</title>
      <dc:creator>Harry Kimpel</dc:creator>
      <pubDate>Fri, 12 Apr 2024 05:36:57 +0000</pubDate>
      <link>https://forem.com/newrelic/guide-how-to-route-docker-logs-correctly-in-new-relic-iid</link>
      <guid>https://forem.com/newrelic/guide-how-to-route-docker-logs-correctly-in-new-relic-iid</guid>
      <description>&lt;p&gt;To read this full article, &lt;a href="https://newrelic.com/blog/how-to-relic/guide-how-to-route-docker-logs-correctly-in-new-relic?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Streamlining Container Log Management for Clarity and Control&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hello, New Relic aficionados! Picture this: you're at a bustling local user group meetup, exchanging ideas and sharing tech stories. Amidst the animated discussions and clinking coffee cups, a fellow developer—let’s call him Alex—shares a frustrating puzzle. Alex’s Docker Compose applications are acting like rebellious teenagers, sending their logs to the New Relic Host UI instead of their designated New Relic Container UI. As you dive deeper into the problem, a light bulb goes off. This isn't just Alex's struggle; it’s a common snag affecting many of us in the Docker and New Relic community.&lt;/p&gt;

&lt;p&gt;Why do these logs prefer the scenic route, and how can we guide them to their proper home? Inspired by this real-life challenge, I embarked on a quest to demystify the log misdirection issue and share a roadmap to log management nirvana with New Relic. So, grab your digital compasses, dear readers—it's time to navigate through the foggy waters of Docker logging and ensure your data logs exactly where it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the core issue: Where do my container logs end up?
&lt;/h2&gt;

&lt;p&gt;So, what's the fuss about where logs end up anyway? Let's break it down. When you're running applications in containers, especially when using Docker, logging isn't just about keeping a record; it's about clarity and context. The &lt;a href="https://docs.newrelic.com/docs/infrastructure/install-infrastructure-agent/get-started/install-infrastructure-agent/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates" rel="noopener noreferrer"&gt;New Relic infrastructure agent&lt;/a&gt; (along with the &lt;a href="https://github.com/newrelic/nri-docker" rel="noopener noreferrer"&gt;New Relic integration for Docker&lt;/a&gt;) is designed to be thorough—it dutifully collects logs from the host and any containers running on it. But here’s the snag: instead of neatly categorizing container logs under each container, all logs get lumped together. Your container logs are showing up right alongside host/server logs in the &lt;a href="https://docs.newrelic.com/docs/infrastructure/infrastructure-ui-pages/infra-hosts-ui-page/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates" rel="noopener noreferrer"&gt;New Relic infrastructure Hosts UI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.kimpel.com%2F20240411-container-logs-1.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%2Fcdn.kimpel.com%2F20240411-container-logs-1.png" alt="hosts ui container logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the Logs section of your Container UI does not show any logs:&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%2Fcdn.kimpel.com%2F20240411-container-logs-2.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%2Fcdn.kimpel.com%2F20240411-container-logs-2.png" alt="container ui no logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why does this matter? Imagine trying to find a specific conversation in a bustling, crowded room. Every discussion, whether it’s crucial or trivial, merges into one overwhelming cacophony. That's your current logging scenario—container logs are getting lost in the noise of the host logs, making it challenging to pinpoint issues or understand the behavior of specific containers.&lt;/p&gt;

&lt;p&gt;This misassignment doesn’t just clutter your view; it complicates monitoring and troubleshooting by obscuring the boundaries between container-specific operations and overall host activity. You need to see your container logs isolated from host logs to quickly diagnose issues, scale effectively, and understand exactly how your containers are performing in the wild.&lt;/p&gt;

&lt;p&gt;In the following sections, we'll explore why this log misplacement occurs and how you can reroute your logs to their correct destinations in New Relic, ensuring that your monitoring setup is as sharp and efficient as your development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring your environment for precise log routing
&lt;/h2&gt;

&lt;p&gt;Now that we understand the issue at hand, let's roll up our sleeves and tackle the solution. Organizing your logs with New Relic starts with a few key adjustments in your environment. Here’s a simple guide to ensure your container logs aren’t just collected but correctly associated with their respective container entities in New Relic Logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Adjust your logging configuration
&lt;/h3&gt;

&lt;p&gt;Chances are, this step might already be in place if you've been monitoring with New Relic. Your goal here is to ensure that the logs from each container are being captured effectively. This involves tweaking your &lt;a href="https://docs.newrelic.com/docs/logs/forward-logs/forward-your-logs-using-infrastructure-agent/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates" rel="noopener noreferrer"&gt;logging configurations&lt;/a&gt; to include detailed information about each container's operations. If this isn't set up yet, here's what you typically need to modify in your environment settings to start capturing those logs.&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%2Fcdn.kimpel.com%2F20240411-container-logs-3.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%2Fcdn.kimpel.com%2F20240411-container-logs-3.png" alt="container logs infra config"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the snippet that you can copy and use in your logging.yml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containers&lt;/span&gt;
    &lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/lib/docker/containers/*/*.log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Tagging containers in Docker
&lt;/h3&gt;

&lt;p&gt;Next, you’ll need to make your containers recognizable by tags when running your containers manually using ‘docker run’ command or within your Docker Compose configuration file. Adding the below &lt;a href="https://docs.docker.com/config/containers/logging/log_tags/" rel="noopener noreferrer"&gt;tag&lt;/a&gt; makes this happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker run command example
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--log-opt&lt;/span&gt; &lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{{.Name}}"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; log-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Docker Compose example in docker-compose.yml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.kimpel.com%2F20240411-container-logs-4.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%2Fcdn.kimpel.com%2F20240411-container-logs-4.png" alt="container logs docker compose tag"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the snippet that you can copy and use in your &lt;strong&gt;docker-compose.yml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.9'&lt;/span&gt;
&lt;span class="na"&gt;x-default-logging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;logging&lt;/span&gt;
  &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json-file"&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;max-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5m"&lt;/span&gt;
    &lt;span class="na"&gt;max-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;
    &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{.Name}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration ensures that each log entry from your containers includes the container's name as a tag, making it easier to track in the logs collected by New Relic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Set up a log parsing rule in New Relic Logs
&lt;/h3&gt;

&lt;p&gt;Once you start seeing the container tags coming through in your New Relic environment, it’s time to refine how these logs are parsed and displayed. &lt;a href="https://docs.newrelic.com/docs/logs/ui-data/parsing/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates" rel="noopener noreferrer"&gt;Setting up a log parsing rule&lt;/a&gt; helps in categorizing and querying logs based on specific attributes.&lt;/p&gt;

&lt;p&gt;Here’s how to configure it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: container name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Field to parse&lt;/strong&gt;: attrs.tag&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter logs based on New Relic Query Language (NRQL)&lt;/strong&gt;: attrs.tag is not null&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parsing rule&lt;/strong&gt;: %{NOTSPACE:containerName}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.kimpel.com%2F20240411-container-logs-5.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%2Fcdn.kimpel.com%2F20240411-container-logs-5.png" alt="container logs parsing rule tag"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This parsing rule will extract the container name from the &lt;strong&gt;attrs.tag&lt;/strong&gt; field of each log entry and add an additional attribute named &lt;strong&gt;containerName&lt;/strong&gt;, enabling you to filter and analyze logs by specific containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With these three steps, your container logs will not only be more organized but also more insightful. By ensuring that each log entry is correctly tagged and parsed, they'll directly feed into New Relic's powerful logging tools, allowing you to monitor and troubleshoot with unmatched precision. This setup not only enhances your ability to respond to issues swiftly but also empowers your team with data-driven insights, ensuring your applications run smoothly and efficiently.&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%2Fcdn.kimpel.com%2F20240411-container-logs-6.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%2Fcdn.kimpel.com%2F20240411-container-logs-6.png" alt="container ui with logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we wrap up our guide on streamlining Docker logs in New Relic, remember that effective log management is just one piece of the observability puzzle. To further illustrate the power of integrated monitoring tools, I recently contributed to enhancing the OpenTelemetry demo application. My pull request (&lt;a href="https://github.com/open-telemetry/opentelemetry-demo/pull/1495" rel="noopener noreferrer"&gt;PR #1495&lt;/a&gt;) has been accepted and merged, introducing a new tagging feature that you'll find particularly useful when &lt;a href="https://opentelemetry.io/docs/demo/docker-deployment/" rel="noopener noreferrer"&gt;running the demo with Docker Compose&lt;/a&gt;. This addition helps ensure that container logs are easily distinguishable and accurately attributed, enhancing your ability to monitor and troubleshoot effectively. Check out the changes and explore how they can benefit your setup &lt;a href="https://github.com/open-telemetry/opentelemetry-demo/pull/1495" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition to contributing to the OpenTelemetry demo application, I've also updated the respective sections of the New Relic documentation to reflect these improvements in log management. This update ensures that the strategies and technical details we've discussed are not only tested but also officially integrated into our guidance, making it easier for you to implement and benefit from these changes. You can view these updates (soon) to enhance your understanding and application of these practices, ensuring you get the most out of your New Relic tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Congratulations on configuring your Docker environment for optimal log management! But the journey doesn’t stop here. Dive deeper into the possibilities:&lt;/p&gt;

&lt;p&gt;Experiment and refine: Adjust the logging levels and parsing rules based on the specific needs of your environment. Each application may have unique insights to offer.&lt;br&gt;
Monitor the impact: Keep an eye on how these changes enhance your monitoring capabilities. Look for improvements in troubleshooting and system performance.&lt;br&gt;
Share your insights: Got a handle on things? Don’t keep it to yourself. Share your success stories and challenges in the comments below or on social media. Your experiences could shine a light for fellow developers navigating similar challenges.&lt;br&gt;
Engage with the community: Join discussions on the New Relic Explorers Hub to connect with other users and exchange tips and tricks. Your feedback not only contributes to community growth but also helps us improve and evolve our solutions.&lt;/p&gt;

&lt;p&gt;Ready to elevate &lt;a href="https://newrelic.com/signup?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy25-q1-devtoupdates" rel="noopener noreferrer"&gt;your log management game&lt;/a&gt;? Start tweaking, sharing, and engaging today. Let’s harness the full potential of precise log data together!&lt;/p&gt;

</description>
      <category>observability</category>
      <category>logs</category>
      <category>docker</category>
    </item>
    <item>
      <title>New Instant Observability integrations for monitoring API, network, application, and streaming performance</title>
      <dc:creator>Louis Leung</dc:creator>
      <pubDate>Sun, 31 Mar 2024 22:01:59 +0000</pubDate>
      <link>https://forem.com/newrelic/new-instant-observability-integrations-for-monitoring-api-network-application-and-streaming-performance-3jh2</link>
      <guid>https://forem.com/newrelic/new-instant-observability-integrations-for-monitoring-api-network-application-and-streaming-performance-3jh2</guid>
      <description>&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/nerdlog/integrations-api-network-streaming-apm?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy23-q4-blog"&gt;click here&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;




&lt;p&gt;Engineers rely on many tools to monitor the health of their systems, making it difficult to gain end-to-end observability without having to toggle between multiple solutions. To help combat this issue of tool sprawl and data silos, we partner with leading technology companies to build integrations to make it easy to visualize, monitor, and act on all your data in a single observability platform. &lt;/p&gt;

&lt;p&gt;You can find all of our partner integrations in New Relic Instant Observability (I/O), an open ecosystem of more than 450 free, prebuilt quickstarts that help you start monitoring your system in minutes. These quickstarts bundle necessary building blocks for instrumenting, monitoring, and acting on signals from your telemetry data, wherever it comes from.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  New partner integrations
&lt;/h2&gt;

&lt;p&gt;The latest cohort of partners contributing to New Relic Instant Observability span across customer experience monitoring, web performance, and API management.&lt;/p&gt;

&lt;p&gt;This month, we’re announcing new integrations and quickstarts with the following partners:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Datazoom&lt;/li&gt;
&lt;li&gt;Glassbox&lt;/li&gt;
&lt;li&gt;Cloudflare&lt;/li&gt;
&lt;li&gt;Netlify&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read on to learn what you can do with these new quickstarts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloudflare Network Logs
&lt;/h2&gt;

&lt;p&gt;Cloudflare is an industry-leading global network designed to make everything you connect to the Internet secure, private, fast, and reliable. Use Cloudflare to protect and accelerate external, public-facing web properties, secure your internal operations on one global network, and build new applications on Cloudflare's serverless platform. Internet properties powered by Cloudflare have all web traffic routed through Cloudflare's intelligent global network.&lt;/p&gt;

&lt;p&gt;The new Cloudflare Logpush integration sends Cloudflare data directly into New Relic, resulting in faster log delivery and eliminating cloud storage middleware costs. With the Cloudflare Network Logs quickstart, you can monitor and analyze web traffic metrics from Cloudflare Logpush on a New Relic dashboard. You get an overview of important logs and metrics from your websites and applications.&lt;/p&gt;

&lt;p&gt;Learn more about how to send log insights faster and cheaper through the Cloudflare integration.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Netlify Logs
&lt;/h2&gt;

&lt;p&gt;Platform developers love Netlify for building high-performance, dynamic web sites, e-commerce stores, and applications. As a pioneer of the Jamstack movement, Netlify brings together modern web frameworks, serverless functions, and edge computing into one platform to deliver unmatched experiences for your application users. &lt;/p&gt;

&lt;p&gt;With the Netlify Logs quickstart, you can explore and visualize data from traffic and function logs provided by Netlify log drains. It allows you to parse, view, and filter traffic logs and function logs generated by your Netlify workloads for in-depth analysis, performance monitoring, troubleshooting, and alerting within New Relic.&lt;/p&gt;

&lt;p&gt;Learn more about exporting traffic and function logs from Netlify to New Relic by reading the Better monitoring for your Netlify sites blog post, or watch this tutorial:&lt;/p&gt;

&lt;h2&gt;
  
  
  Postman
&lt;/h2&gt;

&lt;p&gt;Postman helps more than 17 million developers collaborate and create better APIs. The Postman quickstart provides Postman monitoring data to New Relic, so that DevOps, APIOps, and ITOps engineers can get instant observability into critical metrics such as latency, request counts, and error rates to collaborate better. The integration also ingests data from New Relic into Postman to bring observability data to API producers, testers, and consumers.&lt;/p&gt;

&lt;p&gt;Learn how to send real-time API metrics from Postman to New Relic in the API monitoring with Postman integration blog post, or watch this tutorial:&lt;/p&gt;

&lt;h2&gt;
  
  
  Datazoom
&lt;/h2&gt;

&lt;p&gt;Datazoom is an enterprise video data platform. The software solution captures, standardizes, enriches, and routes data from various points across an end-to-end video workflow. Through a variety of real-time data collection and routing services, Datazoom’s platform provides flexibility and transparency in data collection so that teams can make operations, engineering, product and business decisions with confidence. Companies can drive revenue with streaming video by using Datazoom to democratize insight, increase efficiencies, and deliver captivating end-user experiences.&lt;/p&gt;

&lt;p&gt;The Datazoom quickstart provides a fast and easy launching point into video metrics built on top of New Relic dashboards, so you can gain insights about your viewers, content, ads, and your platform's performance. You can customize the dashboard to use only metrics that fit your goals, edit metric calculations, and tailor them to your needs.&lt;/p&gt;

&lt;p&gt;Learn more about the Datazoom integration at Get real-time visibility into your streaming video architecture and performance.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Glassbox
&lt;/h2&gt;

&lt;p&gt;Glassbox empowers organizations to create frictionless digital journeys for their users. The Glassbox digital experience analytics and session replay platform work in real time across mobile apps and websites to increase user loyalty and accelerate growth. Through AI-driven visualization and analytics tools, Glassbox helps teams to prioritize customer experience and digital product enhancements from a single collaborative system.&lt;/p&gt;

&lt;p&gt;The Glassbox quickstart helps you understand the impact of application performance on your users’ digital experience. Gain deeper contextual insights by combining the data capture and session replay capabilities of Glassbox with New Relic. Get a view of behavioral insights and KPIs inside a pre-built New Relic dashboard, which links directly to a session replay in Glassbox, so you can find the root cause of the digital issue and fix performance issues faster.&lt;/p&gt;

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




&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/nerdlog/integrations-api-network-streaming-apm?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy23-q4-blog"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Get your insights in minutes</title>
      <dc:creator>Louis Leung</dc:creator>
      <pubDate>Sun, 31 Mar 2024 21:40:18 +0000</pubDate>
      <link>https://forem.com/newrelic/get-your-insights-in-minutes-47mp</link>
      <guid>https://forem.com/newrelic/get-your-insights-in-minutes-47mp</guid>
      <description>&lt;p&gt;&lt;em&gt;To read this full New Relic blog, click &lt;a href="https://newrelic.com/blog/nerdlog/instant-observability-quickstarts?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy23-q4-blog"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;At New Relic, we are committed to making observability a daily best practice for every engineer by investing heavily in the global open source community. In the last 12 months alone, we open sourced more than 10 years of R&amp;amp;D around agents, we standardized on OpenTelemetry, and we contributed Pixie to the Cloud Native Computing Foundation. New Relic I/O is a continuation of this strategy to dramatically reduce the barrier for engineers to embrace observability. Anyone can contribute data sources and share alert and dashboard configurations. Ultimately, we created New Relic I/O to make it easier for engineers to leverage community expertise to get more value out of their data, instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The democratization of observability
&lt;/h2&gt;

&lt;p&gt;How do you know that you are properly monitoring your LAMP stack, getting the right visibility into the performance of Gatsby sites, or debugging Kafka clusters with proven best practices? Today’s distributed environments are complex, and most engineers aren’t observability experts. Unless you’ve done it before, it’s difficult and time consuming to figure out how to instrument your distributed tech stack, capture the right data points with the right detail, and build dashboards from scratch to monitor your telemetry data. &lt;/p&gt;

&lt;p&gt;According to New Relic’s 2021 Observability Forecast, while most IT decision makers are familiar with observability, there’s a huge gap in the practice: only 26% of respondents have a mature observability practice, and the most commonly cited barriers to observability success are lack of resources (38%) and skill gaps (29%). &lt;/p&gt;

&lt;p&gt;What if there was an easier way to share these observability superpowers with all software engineers? And to get started quickly?&lt;/p&gt;

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

&lt;h2&gt;
  
  
  A single ecosystem for integrations, applications, and quickstarts
&lt;/h2&gt;

&lt;p&gt;Enter New Relic I/O, an ever-expanding, open knowledge base of configurations and resources that taps into the collective experience of the world’s observability experts to help you unlock the value of your data faster. You can choose from hundreds of quickstarts (including LAMP, Gatsby, and Kafka) that bundle the necessary building blocks for instrumenting, monitoring, and acting on signals from your technology stack—and install them in a click. We’ve also built quickstarts for hundreds of end-to-end integrations for popular cloud services, tools, and open standards that include guided installation experiences as well as relevant dashboards and alerts. No matter which technologies you rely on, you can get observability coverage in minutes instead of days—or weeks.&lt;/p&gt;

&lt;p&gt;Within New Relic Instant Observability, current New Relic One users can extend the platform with publicly available apps or any custom apps your team builds.&lt;/p&gt;

&lt;p&gt;If you haven't used New Relic before, you can browse the catalog of available quickstarts in our public New Relic I/O catalog and get started with a free account in minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to install your first quickstart
&lt;/h2&gt;

&lt;p&gt;Getting started with observability has never been easier. Before you begin, if you haven't used New Relic before, sign up for a free New Relic account (or log in to your existing account).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In New Relic One, to see the catalog, click Instant Observability in the top navigation. You can search, filter by contents, or select a category, such as Kubernetes or APM.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Then select a quickstart to learn more about it:&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;After you select a quickstart, you can see what’s included in the quickstart details. See a description of the pack, screenshots, and information on the included resources. Click Install this quickstart to get started.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Follow the instructions and install the necessary instrumentation to get the data used in the quickstart:&lt;/li&gt;
&lt;/ol&gt;

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

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

&lt;ol&gt;
&lt;li&gt;After you complete the installation process, click See your data:&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Enjoy the dashboards, alerts, and insights:&lt;/li&gt;
&lt;/ol&gt;

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

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

&lt;p&gt;Voila! You’re on the path to becoming an observability expert. Yes, it’s really as simple as that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partners in instant observability
&lt;/h2&gt;

&lt;p&gt;We are proud to launch New Relic Instant Observability with pre-built quickstarts from six leading enterprise software partners. We have partnered closely with them to create quickstarts that help you extend your New Relic One experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Kentik is the network observability company. The Kentik quickstarts help network and development teams quickly identify and troubleshoot application performance issues correlated with network traffic performance and health data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fastly is an edge cloud platform that enables its customers to create great digital experiences quickly, securely, and reliably. With the Fastly CDN quickstart, you can monitor key metrics from Fastly’s content delivery network to improve service reliability and ensure great online experiences for end users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lacework is a data-driven security platform for the cloud that can collect, analyze, and accurately correlate data across an organization’s Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform, and Kubernetes environments, and narrow it down to the handful of security events that matter. The Lacework quickstart bridges the gap between observability and security teams, and integrates with New Relic’s database to surface security events and alerts directly in New Relic One.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cribl is the observability pipeline company that lets customers parse and route any type of data. The Cribl quickstart allows you to get immediate visibility into your entire environment right from New Relic One without the need to create your own dashboards and alerts—simplifying your workflows and reducing time to value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trend Micro is a global cyber security leader. The Trend Micro Cloud One quickstart ingests cloud security posture management (CSPM) data from Conformity into New Relic One to contextualize and correlate it with workload telemetry data, delivering AI-powered visualizations and quick insights. This allows security and cloud teams to immediately take action in improving their security and compliance postures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gigamon is a hybrid-cloud visibility and analytics platform that provides access to—and extracts intelligence from—all network traffic. The Gigamon quickstart delivers advanced security capabilities that offer network detection and response to advanced threats, including shadow IT activities, crypto-mining and torrent activities, SSL cipher versions, and expiration dates across both managed and unmanaged hosts, such as IoT/OT and containers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;To read this full New Relic blog, click &lt;a href="https://newrelic.com/blog/nerdlog/instant-observability-quickstarts?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy23-q4-blog"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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