<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ntcsteve</title>
    <description>The latest articles on DEV Community by ntcsteve (@ntcsteve).</description>
    <link>https://dev.to/ntcsteve</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1086849%2Feee0ebf0-dbfb-4d7d-b726-ae3c648089d8.jpeg</url>
      <title>DEV Community: ntcsteve</title>
      <link>https://dev.to/ntcsteve</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ntcsteve"/>
    <language>en</language>
    <item>
      <title>Automate your configuration with observability as code</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Sat, 11 Nov 2023 22:32:19 +0000</pubDate>
      <link>https://dev.to/newrelic/automate-your-configuration-with-observability-as-code-1f4e</link>
      <guid>https://dev.to/newrelic/automate-your-configuration-with-observability-as-code-1f4e</guid>
      <description>&lt;p&gt;&lt;em&gt;Follow along with dashboards as code examples using New Relic and Terraform. To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-one?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-terraform"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/new-relic-solutions/observability-maturity/operational-efficiency/observability-as-code-guide/"&gt;Observability as code&lt;/a&gt; (also known as o11y as code) is the process of automating the configuration of observability tools. You manage your infrastructure with code, so why not manage your observability the same way—and your dashboards as well? &lt;/p&gt;

&lt;p&gt;This three-part blog series is your guide to o11y as code, providing tips, examples, and guidance. In this series, we'll walk through examples of how you can automate the configuration of your observability tools, starting with dashboards here in part one. Part one covers the basics of Terraform, how to provision a sample app, and how to create dashboards as code.&lt;/p&gt;

&lt;p&gt;By the end of the series, you'll have worked with a total of five examples of observability as code using New Relic and Hashicorp's Terraform: dashboards as code, alerts as code, synthetic monitoring as code, tags as code, and workloads as code. You'll be working with data from the &lt;a href="https://github.com/NewRelicUniversity/foodme"&gt;sample FoodMe restaurant ordering app&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did we get here? Infrastructure as code
&lt;/h2&gt;

&lt;p&gt;Since infrastructure as code (also known as IaC) appeared on the scene more than a decade ago, it’s become a core requirement in the modern cloud era. The terminology “as code” means treating infrastructure configuration just like we treat code, pushing configuration into source control, then carefully pushing out changes again to the infrastructure layer.&lt;/p&gt;

&lt;p&gt;With the rise of modern distributed systems, we also see more outages, and finding the root cause of the issue can be challenging when something goes wrong. Observability fits into the new paradigm because we need to determine the internal states of our systems from their outputs. Observability uses different system outputs such as tracing, logs, and metrics to understand the internal state of the distributed components, diagnose where the problems are, and get to the root cause.&lt;/p&gt;

&lt;p&gt;Unfortunately, the operational practices we rely on didn’t change much, and developers and operations engineers might find they still look at hundreds of alerts or dashboards. This approach leads to non-repeatable, non-standardized dashboard configurations or adjusting alerts dynamically to avoid signals fatigue and drifting from organizational best practices. &lt;/p&gt;

&lt;p&gt;But we can use what we know about infrastructure as code to automate observability. Meet the new approach: observability as code, which treats observability configurations as code. As explained in &lt;a href="https://newrelic.com/blog/best-practices/automate-observability"&gt;Observability as code simplifies your life&lt;/a&gt;, observability as code represents a shift of intention to an auditable code-managed solution that reduces the work needed to maintain and develop a configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand the basics of Terraform
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.hashicorp.com/terraform/intro"&gt;Terraform by Hashicorp&lt;/a&gt; is an infrastructure as code tool that you can use to define and manage infrastructure resources in configuration files that are easily readable by humans. You can declaratively manage services and automate your changes to those services.&lt;/p&gt;

&lt;p&gt;In most examples, a Terraform module is a set of Terraform configuration files in one directory. When you run Terraform commands directly from that single directory, it is considered the root module. Here's what it looks like, &lt;a href="https://developer.hashicorp.com/terraform/tutorials/modules/module#what-is-a-terraform-module"&gt;as shown in the Terraform docs&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;.
├── LICENSE
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Terraform files used in this blog series
&lt;/h2&gt;

&lt;p&gt;The examples in the tutorial exercises in this blog series focus on two important files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;main.tf&lt;/code&gt; file contains the main set of configurations for your module. You can also create other configuration files and organize them in a way that makes sense for your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;variables.tf&lt;/code&gt; file contains the variable definitions for your module. If you want others to use your module, configure the variables as arguments in the module block.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example of a New Relic Terraform provider
&lt;/h2&gt;

&lt;p&gt;Here’s an example of a New Relic provider in Terraform from &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/guides/provider_configuration"&gt;Configuring the New Relic Terraform Provider&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;# get the New Relic terraform provider
terraform {
  required_version = "~&amp;gt; 1.0"
  required_providers {
    newrelic = {
      source  = "newrelic/newrelic"
    }
  }
}

# configure the New Relic provider
provider "newrelic" {
  account_id = &amp;lt;Your Account ID&amp;gt;
  api_key = &amp;lt;Your User API Key&amp;gt;    # usually prefixed with 'NRAK'
  region = "US"                    # Valid regions are US and EU
}

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

&lt;/div&gt;



&lt;p&gt;You can also use &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/guides/provider_configuration#configuration-via-environment-variables"&gt;environment variables&lt;/a&gt; to configure the &lt;code&gt;provider&lt;/code&gt;, which can simplify your provider block. Each provider has key schema attribute, such as &lt;code&gt;account_id&lt;/code&gt;, &lt;code&gt;api_key&lt;/code&gt;, and &lt;code&gt;region&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform commands to remember
&lt;/h2&gt;

&lt;p&gt;To initialize and run Terraform effectively, remember these four commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;terraform init&lt;/code&gt; command performs initialization steps to prepare the current working directory for use with Terraform. This command is safe to run multiple times, to update the working directory with configuration changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;terraform plan&lt;/code&gt; command creates an execution plan, which lets you preview the changes that Terraform will make to your infrastructure. You can use this command to check whether the proposed changes match what you expect before you apply the changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;terraform apply&lt;/code&gt; command automatically creates an execution plan, prompting you to approve that plan, and then takes the indicated actions. Follow the prompts, and answer yes to apply the changes. Terraform will then provision the resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;terraform destroy&lt;/code&gt; command is a convenient way to remove all the remote objects managed by a particular Terraform configuration. Follow the prompts, and Terraform will delete all the resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information on Terraform commands, &lt;a href="https://developer.hashicorp.com/terraform/cli/run"&gt;see Provisioning infrastructure with Terraform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The examples in the next sections show key concepts in Terraform such as providers, data sources, and resources. You'll be automating configuration of New Relic dashboards to view data from the &lt;a href="https://github.com/NewRelicUniversity/foodme"&gt;sample FoodMe restaurant app&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This blog post demo uses the &lt;code&gt;newrelic_one_dashboard&lt;/code&gt; resource. As an alternative, if you want to use the &lt;code&gt;newrelic_one_dashboard_json&lt;/code&gt; resource, see the &lt;a href="https://newrelic.com/blog/how-to-relic/create-nr-dashboards-with-terraform-part-1"&gt;Creating dashboards with Terraform and JSON templates tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you begin provisioning your first Terraform module
&lt;/h2&gt;

&lt;p&gt;For this tutorial, we’re going to provision a sample app. But before you provision your first Terraform module, you’ll need to get an account ID, your user key, and point to the correct data center: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/accounts/accounts-billing/account-structure/account-id/"&gt;Getting your unique account ID (account_id)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/#overview-keys"&gt;Getting your user key (api_key)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/accounts/accounts-billing/account-setup/choose-your-data-center/"&gt;Pointing to the right data center (region)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This video walkthrough covers prerequisite work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-one?wvideo=8kbd4hw451"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OFJCs2GT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/2b907946ed1130e369f45d1b43434c87.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-one?wvideo=8kbd4hw451"&gt;Automate Configuration with Observability as Code | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Provision the sample app
&lt;/h2&gt;

&lt;p&gt;Before we work on implementing observability as code, let’s start by provisioning our sample app! &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Generate your unique URL for the FoodMe example app with this Glitch link: glitch.com/edit/#!/remix/nr-devrel-o11yascode&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the environment variables. Go to &lt;code&gt;.env&lt;/code&gt; and insert these values:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;LICENSE_KEY&lt;/code&gt;: Insert your New Relic ingest API keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;APP_NAME&lt;/code&gt;: Insert your name or initials to the name of the app &lt;code&gt;FoodMe-XXX&lt;/code&gt; (for example, &lt;code&gt;FoodMe-Jan&lt;/code&gt;).&lt;/p&gt;&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%2Flyonwhna29h8oenj2xl6.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%2Flyonwhna29h8oenj2xl6.png" alt="Image description" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Preview your URI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Go to &lt;strong&gt;Tools&lt;/strong&gt; (bottom of the panel), and select &lt;strong&gt;Preview in a new window&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%2Fkb7o9alevfrdylsmhlk6.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%2Fkb7o9alevfrdylsmhlk6.png" alt="Image description" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Record your URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note your newly generated URL. You’ll use this later on in &lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-two"&gt;part two&lt;/a&gt; of the series for synthetic monitoring as code.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Generate some workloads. Now that you’re in the sample app, enter an example name, delivery address, and select &lt;strong&gt;Find Restaurants&lt;/strong&gt;! After you are on the main page, click around to generate some workloads for the sample app. We'll need some data to look at in the dashboards.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create dashboards as code
&lt;/h2&gt;

&lt;p&gt;Now we're ready for our first observability as code example: dashboards as code. With New Relic custom dashboards, you can collect and visualize the specific data that you want to see and display in New Relic. You'll learn how to automate configuring dashboards in New Relic using Terraform.&lt;/p&gt;

&lt;p&gt;There are three main steps. To see everything we are covering in this section, watch this video. For more details, go to &lt;a href="https://docs.newrelic.com/docs/more-integrations/terraform/terraform-intro/"&gt;Getting started with New Relic and Terraform&lt;/a&gt;. You can also work along with these steps with &lt;a href="https://github.com/ntcsteve/O11yAsCodeWithNR"&gt;code samples in GitHub&lt;/a&gt; and the &lt;a href="https://play.instruqt.com/newrelic/invite/wcxyo2ld0b3g"&gt;hands-on workshop in Instruqt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-one?wvideo=mha8rpl72d"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EdJXY2fJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/2766754e6698cad24572d1c1ab71868e.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-one?wvideo=mha8rpl72d"&gt;Automate Configuration with Observability as Code | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Terraform, each resource block describes one or more observability objects, such as dashboards, alerts, notification workflows, or workloads. We'll use examples from &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/resources/one_dashboard"&gt;Resource: newrelic_one_dashboard&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a resource block  and declare a type (&lt;code&gt;newrelic_one_dashboard&lt;/code&gt;) with a given name (&lt;code&gt;exampledash&lt;/code&gt;). The type and the name of the resource are the identifier for the resource, so they must be unique within a module. Here's a simple example for deploying dashboards as code in New Relic, based on &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/resources/one_dashboard"&gt;Resource: newrelic_one_dashboard&lt;/a&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# New Relic One Dashboard
resource "newrelic_one_dashboard" "exampledash" {
    # The title of the dashboard.
  name = "New Relic Terraform Example"

    # A nested block that describes a page
  page {
        # The name of the page.
    name = "New Relic Terraform Example"

        # A nested block that describes a Billboard widget
    widget_billboard {
      title = "Requests per minute"
      row = 1
      column = 1
      width = 6
      height = 3

            # A nested block that describes a NRQL Query
      nrql_query {
        query = "FROM Transaction SELECT rate(count(*), 1 minute)"
      }
    }
  }
}

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

&lt;/div&gt;



&lt;p&gt;For more details on attribute reference, see &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/resources/one_dashboard#attribute-reference"&gt;the attribute reference for the newrelic provider in Terraform&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;For more details on New Relic Query Language (NRQL), see &lt;a href="https://docs.newrelic.com/docs/query-your-data/nrql-new-relic-query-language/get-started/nrql-syntax-clauses-functions/"&gt;syntax, clauses, and functions&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Next, you'll include a &lt;code&gt;variables.tf&lt;/code&gt; file in Terraform. You can customize Terraform modules with &lt;a href="https://developer.hashicorp.com/terraform/language/values/variables"&gt;input variables&lt;/a&gt; instead of modifying the source code of the module. Then it's easy to share and reuse modules across other configurations in Terraform. At the end of this section, you'll see an example &lt;code&gt;variables.tf&lt;/code&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, you'll combine what we covered about &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs"&gt;the New Relic provider&lt;/a&gt;, the &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/resources/one_dashboard"&gt;resources&lt;/a&gt;, the &lt;code&gt;main.tf&lt;/code&gt; file, and the corresponding &lt;code&gt;variariables.tf&lt;/code&gt; file to deploy dashboards as code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next two example &lt;code&gt;main.tf&lt;/code&gt; and &lt;code&gt;variariables.tf&lt;/code&gt; files use concepts described in &lt;a href="https://sre.google/sre-book/monitoring-distributed-systems/#xref_monitoring_golden-signals"&gt;Google Site Reliability Engineering, The Four Golden Signals&lt;/a&gt;: latency, traffic, errors, and throughput. These examples are based on code samples in the &lt;a href="https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/guides/getting_started"&gt;Getting Started with the New Relic Provider&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example main.tf file complete code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# get the New Relic terraform provider
terraform {
  required_version = "~&amp;gt; 1.0"
  required_providers {
    newrelic = {
      source  = "newrelic/newrelic"
    }
  }
}

# configure the New Relic provider
provider "newrelic" {
  account_id = (var.nr_account_id)
  api_key = (var.nr_api_key)    # usually prefixed with 'NRAK'
  region = (var.nr_region)      # Valid regions are US and EU
}

# resource to create, update, and delete dashboards in New Relic
resource "newrelic_one_dashboard" "dashboard_name" {
  name = "O11y_asCode-FoodMe-Dashboards-TF"

  # determines who can see the dashboard in an account
  permissions = "public_read_only"

  page {
    name = "Dashboards as Code"

    widget_markdown {
      title = "Golden Signals - Latency"
      row = 1
      column = 1
      width = 4
      height = 3

      text = "## The Four Golden Signals - Latency\n---\n#### The time it takes to service a request. It’s important to distinguish between the latency of successful requests and the latency of failed requests. \n\n#### For example, an HTTP 500 error triggered due to loss of connection to a database or other critical backend might be served very quickly; however, as an HTTP 500 error indicates a failed request, factoring 500s into your overall latency might result in misleading calculations. \n\n#### On the other hand, a slow error is even worse than a fast error! Therefore, it’s important to track error latency, as opposed to just filtering out errors."
    }

    widget_line {
      title = "Golden Signals - Latency - FoodMe - Line"
      row = 1
      column = 5
      width = 4
      height = 3

      nrql_query {
        query = "SELECT average(apm.service.overview.web) * 1000 as 'Latency' FROM Metric WHERE appName like '%FoodMe%' since 30 minutes ago TIMESERIES AUTO"
      }
    }

    widget_stacked_bar {
      title = "Golden Signals - Latency - FoodMe - Stacked Bar"
      row = 1
      column = 9
      width = 4
      height = 3

      nrql_query {
        query = "SELECT average(apm.service.overview.web) * 1000 as 'Latency' FROM Metric WHERE appName like '%FoodMe%' since 30 minutes ago TIMESERIES AUTO"
      }
    }

    widget_markdown {
      title = "Golden Signals - Errors"
      row = 4
      column = 1
      width = 4
      height = 3

      text = "## The Four Golden Signals - Errors\n---\n\n#### The rate of requests that fail, either explicitly (e.g., HTTP 500s), implicitly (for example, an HTTP 200 success response, but coupled with the wrong content), or by policy (for example, \"If you committed to one-second response times, any request over one second is an error\").\n \n#### Where protocol response codes are insufficient to express all failure conditions, secondary (internal) protocols may be necessary to track partial failure modes. \n\n#### Monitoring these cases can be drastically different: catching HTTP 500s at your load balancer can do a decent job of catching all completely failed requests, while only end-to-end system tests can detect that you’re serving the wrong content."
    }

    widget_area {
      title = "Golden Signals - Errors - FoodMe - Area"
      row = 4
      column = 5
      width = 4
      height = 3

      nrql_query {
        query = "SELECT (count(apm.service.error.count) / count(apm.service.transaction.duration))*100 as 'Errors' FROM Metric WHERE (appName like '%FoodMe%') AND (transactionType = 'Web') SINCE 30 minutes ago TIMESERIES AUTO"
      }
    }

    widget_billboard {
      title = "Golden Signals - Errors - FoodMe - Billboard Compare With"
      row = 4
      column = 9
      width = 4
      height = 3

      nrql_query {
        query = "SELECT (count(apm.service.error.count) / count(apm.service.transaction.duration))*100 as 'Errors' FROM Metric WHERE (appName like '%FoodMe%') AND (transactionType = 'Web') SINCE 30 minutes ago COMPARE WITH 30 minutes ago"
      }
    }

    widget_markdown {
      title = "Golden Signals - Traffic"
      row = 7
      column = 1
      width = 4
      height = 3

      text = "## The Four Golden Signals - Traffic\n---\n\n#### A measure of how much demand is being placed on your system, measured in a high-level system-specific metric. \n\n#### For a web service, this measurement is usually HTTP requests per second, perhaps broken out by the nature of the requests (e.g., static versus dynamic content). \n\n#### For an audio streaming system, this measurement might focus on network I/O rate or concurrent sessions. \n\n#### For a key-value storage system, this measurement might be transactions and retrievals per second."
    }

    widget_table {
      title = "Golden Signals - Traffic - FoodMe - Table"
      row = 7
      column = 5
      width = 4
      height = 3

      nrql_query {
        query = "SELECT rate(count(apm.service.transaction.duration), 1 minute) as 'Traffic' FROM Metric WHERE (appName LIKE '%FoodMe%') AND (transactionType = 'Web') FACET path SINCE 30 minutes ago"
      }
    }

    widget_pie {
      title = "Golden Signals - Traffic - FoodMe - Pie"
      row = 7
      column = 9
      width = 4
      height = 3

      nrql_query {
        query = "SELECT rate(count(apm.service.transaction.duration), 1 minute) as 'Traffic' FROM Metric WHERE (appName LIKE '%FoodMe%') AND (transactionType = 'Web') FACET path SINCE 30 minutes ago"
      }
    }

    widget_markdown {
      title = "Golden Signals - Saturation"
      row = 10
      column = 1
      width = 4
      height = 3

      text = "## The Four Golden Signals - Saturation\n---\n\n#### How \"full\" your service is. A measure of your system fraction, emphasizing the resources that are most constrained (e.g., in a memory-constrained system, show memory; in an I/O-constrained system, show I/O). Note that many systems degrade in performance before they achieve 100% utilization, so having a utilization target is essential.\n\n#### In complex systems, saturation can be supplemented with higher-level load measurement: can your service properly handle double the traffic, handle only 10% more traffic, or handle even less traffic than it currently receives? For very simple services that have no parameters that alter the complexity of the request (e.g., \"Give me a nonce\" or \"I need a globally unique monotonic integer\") that rarely change configuration, a static value from a load test might be adequate. \n\n#### As discussed in the previous paragraph, however, most services need to use indirect signals like CPU utilization or network bandwidth that have a known upper bound. Latency increases are often a leading indicator of saturation. Measuring your 99th percentile response time over some small window (e.g., one minute) can give a very early signal of saturation.\n\n#### Finally, saturation is also concerned with predictions of impending saturation, such as \"It looks like your database will fill its hard drive in 4 hours.\""
    }

    widget_line {
      title = "Golden Signals - Saturation - CPU &amp;amp; Memory - Multi-Queries"
      row = 10
      column = 5
      width = 4
      height = 3

      nrql_query {
        query = "SELECT rate(sum(apm.service.cpu.usertime.utilization), 1 second) * 100 as 'cpuUsed' FROM Metric WHERE appName LIKE '%FoodMe%' SINCE 30 minutes ago TIMESERIES AUTO"
      }

      nrql_query {
        query = "SELECT average(apm.service.memory.physical) * rate(count(apm.service.instance.count), 1 minute) / 1000 as 'memoryUsed %' FROM Metric WHERE appName LIKE '%FoodMe%' SINCE 30 minutes ago TIMESERIES AUTO"
      }
    }

    widget_line {
      title = "Golden Signals - Saturation - Memory - Line Compare With"
      row = 10
      column = 9
      width = 4
      height = 3

      nrql_query {
        query = "SELECT average(apm.service.memory.physical) * rate(count(apm.service.instance.count), 1 minute) / 1000 as 'memoryUsed %' FROM Metric WHERE appName LIKE '%FoodMe%' SINCE 30 minutes ago COMPARE WITH 20 minutes ago TIMESERIES AUTO"
      }
    }
  }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example variables.tf file complete code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# your unique New Relic account ID
variable "nr_account_id" {
  default = "XXXXX"
}
# your User API key
variable "nr_api_key" {
  default = "XXXXX"
}

# valid regions are US and EU
variable "nr_region" {
  default = "US"
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  What the final result looks like
&lt;/h2&gt;

&lt;p&gt;Now that you have deployed dashboards as code, your final result should look like this in 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%2Fs6yvd6c32riauik40ask.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%2Fs6yvd6c32riauik40ask.png" alt="Image description" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Follow along with dashboards as code examples using New Relic and Terraform. To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/examples-observability-as-code-part-one?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-terraform"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>tutorial</category>
      <category>monitoring</category>
      <category>developer</category>
    </item>
    <item>
      <title>Top 10 tips for instrumenting Golang with New Relic, part 5</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Sat, 11 Nov 2023 21:17:37 +0000</pubDate>
      <link>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-5-f03</link>
      <guid>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-5-f03</guid>
      <description>&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-5?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Are you building modern apps in Golang? This multi-part blog series will help you instrument Golang faster by providing tips, guidance, and best practices with New Relic.&lt;/p&gt;

&lt;p&gt;Typically, the content in this blog would be presented in a workshop, but we've made it a blog series so anyone can follow along "hands on," using sample code, Instruqt, this blog, and videos. For the best experience:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR"&gt;See and run the full code that I'll be walking through in this multi-part series.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Review previous guides - &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 1&lt;/a&gt;, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 2&lt;/a&gt;, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 3&lt;/a&gt; and &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 4&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go Instrumentation Checklist
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 1&lt;/a&gt;, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 2&lt;/a&gt;, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 3&lt;/a&gt; and &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Part 4&lt;/a&gt; we provided extensive coverage and tips for better instrumentation of Golang in New Relic. The Golang agent differs from others in that it does not offer out-of-the-box auto instrumentation. Because Golang is a compiled language, it does not allow for dynamic runtime or method replacement like dynamic languages such as Java, .NET, Node.js, and PHP.&lt;/p&gt;

&lt;p&gt;While Golang has unique language advantages, &lt;strong&gt;code modification is required&lt;/strong&gt; to monitor Go applications. On the positive side, you have &lt;strong&gt;complete control&lt;/strong&gt; over what to instrument and can highly customize it to your needs. In the last part of this series, we will summarize everything we have covered so far with a production checklist to use before onboarding your Go apps into production.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Using appropriate API key
&lt;/h2&gt;

&lt;p&gt;License keys are used to report almost all data, with the exception of browser and mobile monitoring data, which have their own keys. Each key is unique to an account, allowing for tracking and monitoring of multiple sources of data. This flexibility ensures comprehensive and accurate reporting. Please ensure you have the &lt;a href="https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/#overview-keys"&gt;right&lt;/a&gt; license type before starting your Golang instrumentation. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Leverage best practices
&lt;/h2&gt;

&lt;p&gt;As we've previously discussed, when working with compiled languages such as Go, manual instrumentation is essential. It's not only important to have a solid grasp of how to use the platform itself, but also to understand how to effectively utilize New Relic within your specific environment. By doing so, you can maximize the benefits of New Relic and ensure optimal performance of your Go applications. Here is the best practice &lt;a href="https://docs.newrelic.com/docs/new-relic-solutions/best-practices-guides/full-stack-observability/apm-best-practices-guide/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;guide&lt;/a&gt; from New Relic, including the basics such as tags.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Time to run the app
&lt;/h2&gt;

&lt;p&gt;If you are instrumenting a small sample or a short-lived application in your development environment, it is important to include the following &lt;a href="https://github.com/newrelic/go-agent/blob/master/v3/examples/short-lived-process/main.go"&gt;code&lt;/a&gt; segment. This is because the harvest cycle in the New Relic Go agent is set to 5 seconds, which means that data is collected and sent to New Relic every 5 seconds. By including this code segment, you ensure that the data from your app is accurately captured and monitored during development.&lt;/p&gt;

&lt;p&gt;However, for production deployment, you can safely omit this code segment if your application runs for longer than 5 seconds. In production, the New Relic Go agent automatically adjusts the harvest cycle based on the needs and duration of your application. This ensures that your app's performance is effectively monitored without the need for manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Distributed Tracing
&lt;/h2&gt;

&lt;p&gt;Starting from version 3.16.0, the Go agent has introduced a significant enhancement - the automatic enabling of &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/configuration/go-agent-configuration/#distributed-tracing?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Distributed Tracing&lt;/a&gt;. This means that the agent now proactively adds distributed tracing headers to outbound requests and intelligently scans incoming requests for distributed tracing headers. By default, this feature is enabled to provide seamless tracing capabilities.&lt;/p&gt;

&lt;p&gt;Distributed Tracing is a powerful technique that allows you to trace the path of a single request as it traverses through various services and components of your application. It provides invaluable insights into the performance and behavior of your distributed systems, helping you identify bottlenecks, latency issues, and dependencies.&lt;/p&gt;

&lt;p&gt;With the Go agent's automatic distributed tracing, you no longer need to manually configure tracing headers or worry about missing out on important tracing data. The agent takes care of all the necessary tracing operations behind the scenes, ensuring that your distributed systems are effectively monitored and traced.&lt;/p&gt;

&lt;p&gt;However, if for any reason you want to disable distributed tracing, the Go agent provides a simple configuration option. By setting the value to false, you can turn off distributed tracing and revert to the default behavior. This gives you the flexibility to control the tracing capabilities of your application according to your specific requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Capture contextual data
&lt;/h2&gt;

&lt;p&gt;When utilizing New Relic, it can be highly beneficial to leverage &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/api-guides/guide-using-go-agent-api/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;custom attributes&lt;/a&gt; in order to enhance your events with additional metadata. By using the AddAttribute() code, you can easily incorporate your own contextual data into your transactions, allowing for a more comprehensive and meaningful understanding of your application's performance.&lt;/p&gt;

&lt;p&gt;Custom attributes provide an opportunity to decorate your transactions with relevant information that goes beyond the default metrics and data captured by New Relic. This can include details specific to your application, such as user-specific information, product details, pricing data, or any other relevant metadata. By customizing your events with these attributes, you gain deeper insights into the factors that impact your application's performance and user experience.&lt;/p&gt;

&lt;p&gt;With the ability to capture and analyze this additional contextual data, you can better understand the root causes of any performance issues or anomalies. This, in turn, enables you to make data-driven decisions and optimizations to improve the overall performance and user satisfaction of your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;txn.AddAttribute("product", "widget")
txn.AddAttribute("price", 19.99)
txn.AddAttribute("importantCustomer", true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Instrumentation at scale
&lt;/h2&gt;

&lt;p&gt;To improve the instrumentation at scale throughout your environment, it is recommended to examine the Gin Framework as a starting example. By following this approach, you can effectively instrument your middleware layer and gain valuable insights into its performance. Here is an example of how you can implement it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router := gin.Default()
// Add the nrgin middleware before other middlewares or routes:
router.Use(nrgin.Middleware(app))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This package provides a Gin middleware that can be used to instrument all requests. To use it, call &lt;code&gt;nrgin.Middleware&lt;/code&gt; to get a &lt;code&gt;gin.HandlerFunc&lt;/code&gt;. Then, add the handler to your application as a middleware to instrument inbound requests handled by a &lt;code&gt;gin.Engine&lt;/code&gt;. Implementing this approach allows you to gain deep insights into the behavior and performance of your middleware layer, facilitating effective troubleshooting and optimization. It enhances your ability to identify bottlenecks, track custom metrics, and make data-driven decisions to improve the overall performance of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Production rollout
&lt;/h2&gt;

&lt;p&gt;Once you have determined how to incorporate these instrumentations at scale across your environment, it is essential to have a discussion with your team or engineering lead regarding the optimal approach for deploying them through your deployment pipeline. This step is crucial as it allows you to gather input and insights from your colleagues, ensuring that the deployment process is efficient, effective, and aligned with your team's goals and strategies.&lt;/p&gt;

&lt;p&gt;Engaging in this discussion allows you to leverage the collective expertise and experience of your team members, enabling the identification of any potential challenges or considerations that need to be addressed. This collaborative approach fosters a sense of ownership and accountability among team members, as everyone has the opportunity to contribute their ideas and suggestions. Additionally, involving your engineering lead in this discussion has the added benefit of gaining their guidance and leadership. Their experience and knowledge can offer valuable insights into best practices and industry standards, enabling you to make informed decisions and avoid potential pitfalls. Here are the common operations you need to perform on the Go agent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/installation/install-new-relic-go/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;install&lt;/a&gt; the Go agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/configuration/go-agent-configuration/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;configure&lt;/a&gt; the Go agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/installation/update-go-agent/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;update&lt;/a&gt; the Go agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/installation/uninstall-go-agent/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;uninstall&lt;/a&gt; the Go agent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Apdex for Production
&lt;/h2&gt;

&lt;p&gt;In this informative &lt;a href="https://www.youtube.com/watch?v=RoLIBfEpYZg"&gt;video&lt;/a&gt;, you will learn how to accurately calculate Apdex and identify the ideal threshold for your applications. The video provides a comprehensive guide that takes you through the process step by step, ensuring that you have a clear understanding of how to determine the correct threshold for your specific use case. Additionally, the video offers a simple and effective NRQL query that allows you to easily find the best thresholds for your app. By following the instructions provided in this video, you will be able to optimize the performance of your applications and ensure an exceptional user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Alerts and Dashboards
&lt;/h2&gt;

&lt;p&gt;To improve visibility and control over your application's performance, you can utilize the powerful features of New Relic through configuring alerts and dashboards. By setting up alerts, you will receive timely notifications whenever there are fluctuations in key performance metrics across your entire stack. These alerts can be tailored to meet your specific needs, allowing you to monitor and track important aspects of your application.&lt;/p&gt;

&lt;p&gt;In addition, New Relic's dashboards provide a comprehensive overview of your application's performance data, enabling you to visualize and analyze the most relevant metrics. With the ability to gather and chart specific data from different sources, the dashboards offer a flexible and customizable experience, allowing you to monitor your application's performance from anywhere within the New Relic platform.&lt;/p&gt;

&lt;p&gt;By utilizing both alerts and dashboards, you can proactively monitor your application's performance, identify potential issues or bottlenecks, and take appropriate actions to ensure optimal performance and user experience. Whether it involves detecting sudden increases in response time, monitoring server health and resource utilization, or tracking the success rate of specific transactions, New Relic's alerts and dashboards provide you with the necessary tools and insights to effectively manage your application's performance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Introduction to &lt;a href="https://docs.newrelic.com/docs/alerts-applied-intelligence/overview/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Alerts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduction to &lt;a href="https://docs.newrelic.com/docs/query-your-data/explore-query-data/dashboards/introduction-dashboards/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Dashboards&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Analyze Deployments
&lt;/h2&gt;

&lt;p&gt;New Relic Change Tracking allows you to capture and record deployments and other changes in your system, providing valuable context to performance data. This feature enables you to easily view and analyze the impact of changes on system performance and quality. The change analysis UIs provide detailed insights, including faceted errors, log attribute trends, related issues and anomalies, and calculated impacts on key Golang signals. By utilizing change tracking metadata, such as commit SHAs, changelogs, and deep links, you can quickly identify and resolve issues. This powerful capability enhances your understanding of how changes affect your system and helps optimize development velocity.&lt;/p&gt;

&lt;p&gt;There are several options available for you to begin recording changes (including deployments) to different parts of your system. These options provide both automated and manual ways to track changes effectively. Here are the available methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/change-tracking/change-tracking-graphql/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;NerdGraph (GraphQL) API&lt;/a&gt;: By utilizing the NerdGraph API, you can take advantage of GraphQL mutations to designate the specific changes you want to track. This powerful API allows you to run queries and retrieve detailed information about the changes you are monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/change-tracking/change-tracking-cli/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;New Relic CLI&lt;/a&gt;: Our command line interface, known as the New Relic CLI, offers a convenient way to designate and track changes. With just a few commands, you can easily specify the changes you want to monitor within your system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/change-tracking/ci-cd/change-tracking-jenkins/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;Jenkins&lt;/a&gt;: If you are using Jenkins as your CI/CD tool, we have developed a dedicated plugin that simplifies the process of tracking changes. By integrating this plugin into your Jenkins pipeline, you can effortlessly monitor and capture changes made to your system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/change-tracking/ci-cd/change-tracking-github-actions/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;GitHub Actions&lt;/a&gt;: For those utilizing GitHub Actions in their CI/CD workflow, we provide comprehensive guidance on how to configure and leverage GitHub Actions for change tracking. This integration allows you to seamlessly track and manage changes directly within your CI/CD pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These flexible and versatile options empower you to choose the most suitable method for your specific requirements. Whether you prefer using APIs, command line interfaces, or integrating with popular CI/CD tools like Jenkins or GitHub Actions, New Relic has you covered when it comes to effectively tracking changes in your system.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-5?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>coding</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Top 10 tips for instrumenting Golang with New Relic, part 4</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Sat, 11 Nov 2023 20:38:47 +0000</pubDate>
      <link>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-4-4hgh</link>
      <guid>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-4-4hgh</guid>
      <description>&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Are you building modern apps in Golang? This multi-part blog series will help you instrument Golang faster by providing tips, guidance, and best practices with New Relic.&lt;/p&gt;

&lt;p&gt;Typically, the content in this blog would be presented in a workshop, but we've made it a blog series so anyone can follow along "hands on," using sample code, Instruqt, this blog, and videos. For the best experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR" rel="noopener noreferrer"&gt;See and run the full code that I'll be walking through in this multi-part series.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://play.instruqt.com/newrelic/invite/s5kyxbycvqqp" rel="noopener noreferrer"&gt;Follow the hands-on lab in Instruqt.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read along with this blog and follow the videos below.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following two videos will give an overview of Instruqt and some instructions about how to use it if you haven't done that before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Instruqt
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=lxcbgogplq" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2F09f86dc2005bc12241f3de6c69b3d3a6.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=lxcbgogplq" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 4 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instruqt UI navigation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=rhe9wxh4il" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2F194f2db4c52d0848b593944cd6ed2030.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=rhe9wxh4il" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 4 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you're set up, let's learn a little more about the instrumentation of Golang.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 9: Tracing is your Friend
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=d7qmgqszu1" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2F0483ec37abd09d7f42b17bfb93338785.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=d7qmgqszu1" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 4 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Go programming language is increasingly popular for building distributed systems and microservices. However, this approach presents some challenges, as a single problematic service along the path can negatively impact the overall response time for that request, potentially driving customers away or creating issues.&lt;/p&gt;

&lt;p&gt;Hence, tracing has emerged as a valuable technique to address this issue. It collects data as requests travel from one service to another by recording each segment of the journey as a span. These spans contain essential details about each request segment, such as the time it took to process and the HTTP status code returned. Eventually, these spans are combined into one trace, which gives you a complete picture of the entire request. Distributed Tracing is a specialized form designed to work in complex architectures using monoliths and microservices. It benefits software teams working in modern environments, where complex architectures are becoming increasingly common.&lt;/p&gt;

&lt;p&gt;Distributed Tracing in New Relic is designed to give these software teams an easy way to capture, visualize, and analyze traces, enabling them to understand better how their applications are performing and quickly identify any issues that might arise. Distributed Tracing is enabled by default in Go agent versions 3.16.0 and higher. This means that the agent will automatically add distributed tracing headers to outbound requests and scan incoming requests for distributed tracing headers.&lt;/p&gt;

&lt;p&gt;In some cases, auto-instrumentation may not be available for distributed tracing, but manual instrumentation is still possible. One simple way to create an external segment for an outbound HTTP request is to use the newrelic.NewRoundTripper method.&lt;/p&gt;

&lt;p&gt;Here is an example of making a request to &lt;a href="http://api.example.com" rel="noopener noreferrer"&gt;http://api.example.com&lt;/a&gt; that includes the distributed tracing headers as described in the documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func useNewRoundTripper(txn *newrelic.Transaction) (*http.Response, error) {
    client := &amp;amp;http.Client{}
    client.Transport = newrelic.NewRoundTripper(client.Transport)
    request, _ := http.NewRequest("GET", "http://example.com", nil)
    request = newrelic.RequestWithTransactionContext(request, txn)
    return client.Do(request)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an example where we can see Distributed Tracing with gRPC in Golang.&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%2Fudvehmu5jldtxd1r2zjt.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%2Fudvehmu5jldtxd1r2zjt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

&lt;p&gt;Infinite Tracing is a great option to consider if you have a large amount of data to analyze and want to find the most relevant traces. With this feature, you can send your trace data to our cloud-based service and rely on Infinite Tracing to make sampling decisions. This ensures you're keeping the trace data you need to see.&lt;/p&gt;

&lt;p&gt;Unlike our standard distributed tracing options, Infinite Tracing can process more trace data. It uses tail-based sampling, a superior method of sampling data after it's collected. Unlike head-based sampling, which our standard tracing feature uses, tail-based sampling reduces the chance of missing important data.&lt;/p&gt;

&lt;p&gt;Infinite Tracing is highly configurable, and you can set it up in various ways to ensure that it keeps the trace data you need to see. This way, you can be sure you're getting the most relevant traces for analysis. So, if you're dealing with data and want to ensure you get all vital information, Infinite Tracing is an excellent solution. You explore further with the &lt;a href="https://docs.newrelic.com/docs/distributed-tracing/infinite-tracing/introduction-infinite-tracing/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;introduction&lt;/a&gt; and &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/configuration/distributed-tracing-go-agent/#infinite-tracing?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;setting up&lt;/a&gt; Infinite Tracing for more details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 10: Tracking Performance Changes
&lt;/h2&gt;

&lt;p&gt;Deploying an application can be risky, especially when the app breaks or doesn't perform as expected. Many factors can contribute to a bad deployment, including code changes, environment configuration, and infrastructure issues. This is why it's crucial to have visibility into your app's performance before, during, and after deployment. New Relic Change Tracking allow you to track deployments and correlate them with changes in your app's performance. Using these markers, you can monitor how your app responds to changes made during deployment and detect any issues that may arise in Golang.&lt;/p&gt;

&lt;p&gt;Markers are created automatically by New Relic whenever you deploy a new app version. These markers appear in APM charts and dashboards, allowing you to quickly see the impact of deployments on your app's performance. You can also view change tracking in context with your app's logs, metrics, and traces, making it easier to understand the root cause of any issues.&lt;/p&gt;

&lt;p&gt;By using markers in New Relic, you can reduce the risk of bad deployments and ensure that your app always performs at its best. With better visibility into your app's performance, you can make more informed decisions about when and how to deploy new changes. To document a change, such as a deployment, it is necessary to include the mandatory fields, and then decide whether to include any optional fields related to Golang. The following GraphQL mutations provide examples of different ways to create deployment markers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation {
  changeTrackingCreateDeployment(
    deployment: { version: "0.0.1", entityGuid: "INSERT_YOUR_GUID" }
  ) {
    deploymentId
    entityGuid
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've completed the steps for recording a deployment, you are ready to see its performance in the UI. For more information, you can explore track changes using &lt;a href="https://docs.newrelic.com/docs/change-tracking/change-tracking-graphql/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;NerdGraph&lt;/a&gt; (GraphQL).&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%2Fxr5tqxfssitliob04irb.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%2Fxr5tqxfssitliob04irb.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Bonus Tip 11: Logs in Context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=1dhxovdaq0" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2Fa87f03a1f4bb688fab14f0f9c181f1f2.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-4?wvideo=1dhxovdaq0" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 4 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software developers rely on log data to troubleshoot issues, making it an invaluable source of information. However, in today's world, developers face a new challenge of dealing with an overwhelming amount of log data from various sources. As the volume of log data increases, it becomes more challenging to collect, manage, and analyze this data.&lt;/p&gt;

&lt;p&gt;New Relic logs in context is designed to address this challenge. It correlates your log data with data collected from our APM and infrastructure agents and services instrumented with OpenTelemetry. This means you can see log data or links to log data in other UI experiences, such as APM, Distributed Tracing, and Errors Inbox.&lt;/p&gt;

&lt;p&gt;With the Go language APM agent, you can also get logs in context and see your app logs in the context of your other New Relic data. There are two ways to get logs into New Relic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: using native APM agent to collect logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the majority of users, the best solution for log forwarding is the automatic feature built into the Go agent. It is simple to set up and works well for most use cases. This feature is now turned on by default in versions v3.20.0+ of the Go agent, but it is still possible to modify its configuration to enable application log forwarding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app, err := newrelic.NewApplication(
  newrelic.ConfigAppLogForwardingEnabled(true),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After configuring your agent to send logs to New Relic, you can instrument your logging library using the Logs in Context plugin. This can be done by using supported plugins such as Zerolog, Logrus, or the Standard Library Log from the Golang ecosystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Create a logWriter, then pass it to the log.Logger
    writer := logWriter.New(os.Stdout, app)
    logger := log.New(&amp;amp;writer, "Background:  ", log.Default().Flags())

    logger.Print("Hello world!")

    txnName := "logsInContext Sample Transaction"
    txn := app.StartTransaction("logsInContext")

    // Always create a new log object in order to avoid changing the context of the logger for
    // other threads that may be logging outside of this transaction
    txnLogger := log.New(writer.WithTransaction(txn), "Transaction: ", log.Default().Flags())
    txnLogger.Printf("In transaction %s.", txnName)

    // Random sleep to simulate delays
    randomDelay := rand.Intn(300)
    time.Sleep(time.Duration(randomDelay) * time.Millisecond)

    txnLogger.Printf("Ending transaction %s.", txnName)
    txn.End()

    logger.Print("Goodbye!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F2cp5b0vwfu8229d8l1n1.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%2F2cp5b0vwfu8229d8l1n1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: using a log forwarder to collect logs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our infrastructure monitoring agent enables you to forward your logs to New Relic, which consolidates all of your logging data in one location. This provides you with deeper visibility into both your application and platform performance.&lt;/p&gt;

&lt;p&gt;By forwarding your logs to New Relic, you can enhance your log management capabilities by collecting, processing, exploring, querying, and setting alerts on your log data from the client side.&lt;/p&gt;

&lt;p&gt;To forward your logs through the New Relic infrastructure monitoring agent, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a New Relic account if you haven't already. It's free, forever.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check the system requirements to ensure your configuration is correct.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the infrastructure agent (version 1.11.4 or higher).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a logging.yml configuration file in the infrastructure agent's logging.d directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure your log sources and other parameters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate some traffic and wait a few minutes, then check your account for data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explore your log data in the Logs UI and benefit from the log attributes automatically inserted by the infrastructure agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fhhwk8f77wgf9vlg8phkq.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%2Fhhwk8f77wgf9vlg8phkq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;For more information, don't forget to visit &lt;a href="https://pkg.go.dev/github.com/newrelic/go-agent" rel="noopener noreferrer"&gt;the official page for the New Relic Go agent&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/how-to-relic/top-tips-golang-4?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>development</category>
      <category>devops</category>
      <category>datascience</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Top 10 tips for instrumenting Golang with New Relic, part 3</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Wed, 01 Nov 2023 17:48:30 +0000</pubDate>
      <link>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-3-bc4</link>
      <guid>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-3-bc4</guid>
      <description>&lt;p&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;click here&lt;/a&gt;. &lt;/p&gt;




&lt;p&gt;Are you building modern apps in Golang? This multi-part blog series will help you instrument Golang faster by providing tips, guidance, and best practices with New Relic.&lt;/p&gt;

&lt;p&gt;Typically, the content in this blog would be presented in a workshop, but we've made it a blog series so anyone can follow along "hands on," using sample code, Instruqt, this blog, and videos. For the best experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR" rel="noopener noreferrer"&gt;See and run the full code that I'll be walking through in this multi-part series.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.instruqt.com/newrelic/invite/s5kyxbycvqqp" rel="noopener noreferrer"&gt;Follow the hands-on lab in Instruqt.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read along with this blog and follow the videos below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following two videos will give an overview of Instruqt and some instructions about how to use it if you haven't done that before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Instruqt
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=lxcbgogplq" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2F09f86dc2005bc12241f3de6c69b3d3a6.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=lxcbgogplq" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 3 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instruqt UI navigation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=rhe9wxh4il" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2F194f2db4c52d0848b593944cd6ed2030.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=rhe9wxh4il" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 3 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you're set up, let's learn a little more about the instrumentation of Golang.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 7: It MUST be the database layer!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=rmungpwukl" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2Fc3b9ee46ca81c74c64b125f6a3da1034.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=rmungpwukl" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 3 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At some point during software development, it's not uncommon to experience issues that may seem to stem from the database layer. However, blaming the database layer is not always the best approach. It's possible to instrument and provide more context for database requests in Go, thanks to the use of segments.&lt;/p&gt;

&lt;p&gt;By using segments, you can instrument your Go application's datastore calls. These datastore segments will appear in the APM Transactions breakdown table and Databases tab of the Transactions page in New Relic, providing a comprehensive overview of your database performance.&lt;/p&gt;

&lt;p&gt;If you're using a MySQL, PostgreSQL, or SQLite database driver, using a pre-built integration package is the easiest way to add datastore segments. This also applies to MongoDB, so you can easily instrument your database calls without writing any custom code. For MySQL Database, here is the package driver, as seen in our &lt;a href="https://pkg.go.dev/github.com/newrelic/go-agent/v3/integrations/nrmysql" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. You can go to this &lt;a href="https://github.com/newrelic/go-agent/blob/master/v3/integrations/nrmysql/example/main.go" rel="noopener noreferrer"&gt;link&lt;/a&gt; for a full code sample with MySQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    _ "github.com/newrelic/go-agent/v3/integrations/nrmysql"
)

func main() {
    db, err := sql.Open("nrmysql", "user@unix(/path/to/socket)/dbname")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To provide a context containing a newrelic.Transaction to all Exec and Query methods on sql.DB, sql.Conn, sql.Tx, and sql.Stmt, you need to use the context methods ExecContext, QueryContext, and QueryRowContext in place of Exec, Query, and QueryRow, respectively. This will ensure proper database transaction monitoring with New Relic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;txn := app.StartTransaction("mysqlQuery")
ctx := newrelic.NewContext(context.Background(), txn)
row := db.QueryRowContext(ctx, "SELECT count(*) from tables")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using a MongoDB database, you can simplify the process of creating Datastore Segments by using this package to instrument your MongoDB calls. To do this, simply set the monitor in the connect options using &lt;code&gt;SetMonitor&lt;/code&gt;, as outlined in our documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "github.com/newrelic/go-agent/v3/integrations/nrmongo"

nrMon := nrmongo.NewCommandMonitor(nil)
client, err := mongo.Connect(ctx, options.Client().SetMonitor(nrMon))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the &lt;code&gt;nrmongo&lt;/code&gt; monitor must be set last to prevent it from being overwritten. If you need to use more than one &lt;code&gt;event.CommandMonitor&lt;/code&gt;, you can pass the original monitor to the &lt;code&gt;nrmongo.NewCommandMonitor&lt;/code&gt; function, as demonstrated in the documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origMon := &amp;amp;event.CommandMonitor{
    Started:   origStarted,
    Succeeded: origSucceeded,
    Failed:    origFailed,
}
nrMon := nrmongo.NewCommandMonitor(origMon)
client, err := mongo.Connect(ctx, options.Client().SetMonitor(nrMon))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the current transaction to the context used in any MongoDB call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ctx = newrelic.NewContext(context.Background(), txn)
resp, err := collection.InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can manually create Datastore segments for each database call. Like basic segments, datastore segments start when the StartTime field is populated and end when the End method is called.&lt;/p&gt;

&lt;p&gt;To monitor a datastore segment, you should add the following code snippet to the beginning of the function you want to monitor, as shown in the linked example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;s := newrelic.DatastoreSegment{
    StartTime: txn.StartSegmentNow(),
    Product: newrelic.DatastoreMySQL,
    Collection: "users",
    Operation: "INSERT",
    ParameterizedQuery: "INSERT INTO users (name, age) VALUES ($1, $2)",
    QueryParameters: map[string]interface{}{
        "name": "Dracula",
        "age": 439,
    },
    Host: "mysql-server-1",
    PortPathOrID: "3306",
    DatabaseName: "my_database",
}
defer s.End()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the full sample code of Golang instrumenting a Database function,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func addAlbum(alb Album) (int64, error) {
    result, err := db.Exec("INSERT INTO album (title, artist, price) VALUES (?, ?, ?)", alb.Title, alb.Artist, alb.Price)

    // Provide a context containing a newrelic. Transaction to all exec
    // and query methods on sql.DB, sql.Conn, sql.Tx, and sql.Stmt.
    txn := nrApp.StartTransaction("mysqlQuery")
    ctx := newrelic.NewContext(context.Background(), txn)
    row := db.QueryRowContext(ctx, "INSERT INTO album (title, artist, price) VALUES (?, ?, ?)")
    row.Scan()

    // Random sleep to simulate delays
    randomDelay := rand.Intn(200)
    time.Sleep(time.Duration(randomDelay) * time.Millisecond)

    // End the DB transaction.
    txn.End()

    if err != nil {
        return 0, fmt.Errorf("addAlbum: %v", err)
    }
    id, err := result.LastInsertId()
    if err != nil {
        return 0, fmt.Errorf("addAlbum: %v", err)
    }
    return id, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fwmdar8ob6jgf20d54xsd.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%2Fwmdar8ob6jgf20d54xsd.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

&lt;h2&gt;
  
  
  Tip 8: What about Goroutines?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=kklk6djnth" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2Fc7a87fa37bd1d19af52c83b7965c3a31.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?wvideo=kklk6djnth" rel="noopener noreferrer"&gt;Top 10 tips for instrumenting Golang with New Relic, part 3 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Goroutines are a key feature in Go programming language that allows functions to run concurrently with other functions or methods. Goroutines are a lightweight alternative to traditional threads, making them an attractive option for concurrent programming in Go.&lt;/p&gt;

&lt;p&gt;However, to effectively monitor and instrument a goroutine, you need to use the Transaction.NewGoroutine() transaction method. This method allows you to create a new reference to the transaction, which must be called any time you pass the transaction to another goroutine that makes segments.&lt;/p&gt;

&lt;p&gt;To gain valuable insights into how your application is performing, it's important to track the performance of your concurrent code by instrumenting your goroutines. This is especially important for larger applications where concurrency can cause performance bottlenecks and other issues. You can see more details &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/features/trace-asynchronous-applications/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;here&lt;/a&gt; on instrumenting Goroutines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go func(txn *newrelic.Transaction) {
    defer txn.StartSegment("goroutines").End()
    time.Sleep(100 * time.Millisecond)
}(txn.NewGoroutine())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One more important suggestion for instrumenting your Golang code is to use a &lt;code&gt;WaitGroup&lt;/code&gt;, which is a valuable tool for managing concurrency. The WaitGroup waits for a collection of goroutines to finish before proceeding. The main goroutine calls Add to set the number of goroutines to wait for. Then, each of the goroutines runs and calls Done when finished. Finally, Wait can be used to block until all goroutines have finished. By using a WaitGroup, you can ensure that all of your goroutines have completed their tasks before moving on.&lt;/p&gt;

&lt;p&gt;Here is an example where WaitGroup is used to wait for all the goroutines launched here to finish. Note that if a WaitGroup is explicitly passed into functions, it should be done by a pointer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int) {
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    var wg sync.WaitGroup
    for i := 1; i &amp;lt;= 5; i++ {
        wg.Add(1)
        i := i

                // Goroutines
        go func() {
            defer wg.Done()
            worker(i)
        }()
    }
    wg.Wait()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example on how to instrument Goroutines with New Relic,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func async(w http.ResponseWriter, r *http.Request) {
    // To access the transaction in your handler, use the newrelic.FromContext API.
    txn := newrelic.FromContext(r.Context())

    // This WaitGroup is used to wait for all the goroutines to finish.
    wg := &amp;amp;sync.WaitGroup{}
    println("goRoutines created!")

    for i := 1; i &amp;lt; 9; i++ {
        wg.Add(1)
        i := i

        // The Transaction.NewGoroutine() allows transactions to create segments 
        // in multiple goroutines.
            defer wg.Done()
            defer txn.StartSegment("goroutine" + strconv.Itoa(i)).End()
            println("goRoutine " + strconv.Itoa(i))

            randomDelay := rand.Intn(500)
            time.Sleep(time.Duration(randomDelay) * time.Millisecond)
        }(txn.NewGoroutine())
    }

    // Ensure the WaitGroup is done
    segment := txn.StartSegment("WaitGroup")
    wg.Wait()
    segment.End()
    w.Write([]byte("goRoutines success!"))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F404dpgyf0s1o7ximezal.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%2F404dpgyf0s1o7ximezal.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information, don't forget to visit &lt;a href="https://pkg.go.dev/github.com/newrelic/go-agent" rel="noopener noreferrer"&gt;the official page for the New Relic Go agent.&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-3?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-golong" rel="noopener noreferrer"&gt;click here&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>development</category>
      <category>devops</category>
      <category>database</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Top 10 tips for instrumenting Golang with New Relic, part 2</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Tue, 31 Oct 2023 18:49:19 +0000</pubDate>
      <link>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-2-2ff5</link>
      <guid>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-2-2ff5</guid>
      <description>&lt;p&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Are you building modern apps in Golang? This multi-part blog series will help you instrument Golang faster by providing tips, guidance, and best practices with New Relic.&lt;/p&gt;

&lt;p&gt;Typically, the content in this blog would be presented in a workshop, but we've made it a blog series so anyone can follow along "hands on," using sample code, Instruqt, this blog, and videos. For the best experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR"&gt;See and run the full code that I'll be walking through in this multi-part series.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.instruqt.com/newrelic/invite/s5kyxbycvqqp"&gt;Follow the hands-on lab in Instruqt.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read along with this blog and follow the videos below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following two videos will give an overview of Instruqt and some instructions about how to use it if you haven't done that before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview of Instruqt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=lxcbgogplq"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HFkSdOcR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/09f86dc2005bc12241f3de6c69b3d3a6.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=lxcbgogplq"&gt;Top 10 tips for instrumenting Golang with New Relic, part 2 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instruqt UI navigation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=rhe9wxh4il"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WDmb6V70--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/194f2db4c52d0848b593944cd6ed2030.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=rhe9wxh4il"&gt;Top 10 tips for instrumenting Golang with New Relic, part 2 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you're set up, let's learn a little more about the instrumentation of Golang.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 4: Transactions and segments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=hhgx69sgw5"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SCjCqXcw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/4ed80355f6e21f6fc5ae0303ece6115d.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=hhgx69sgw5"&gt;Top 10 tips for instrumenting Golang with New Relic, part 2 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The New Relic Go instrumentation revolves around two fundamental concepts: Transactions and segments. These concepts are essential to understanding Go integrations and examples.&lt;/p&gt;

&lt;p&gt;Transactions are a crucial aspect of Go instrumentation. It refers to a logical unit of work in a software application comprising function calls and method calls executed during a specific time frame. A transaction usually represents a key transaction encompassing the activity from when the application receives a request to when it sends the response.&lt;/p&gt;

&lt;p&gt;Transactions are crucial because they help developers identify the slowest parts of the code. By tracking these transactions, developers can identify bottlenecks and optimize the performance of the application. This information can then be used to optimize the user experience and improve customer satisfaction.&lt;/p&gt;

&lt;p&gt;Here's an example of monitoring a web transaction as seen in our &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-transactions/#go-txn?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;docs&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;// Begin a new transaction with a specified name and defer its ending.
txn := app.StartTransaction("transaction_name")
defer txn.End()

// req variable of type *http.Request to mark the transaction as a web transaction.
txn.SetWebRequestHTTP(req)

// writer is a http.ResponseWriter, use the returned writer in place of the original.
writer = txn.SetWebResponse(writer)
writer.WriteHeader(500)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In software applications, a transaction may consist of multiple segments representing a specific part of the process. For instance, a transaction in an ecommerce platform may involve adding items to a shopping cart, processing payment, and updating inventory levels.&lt;/p&gt;

&lt;p&gt;To gain insights into these transactions' performance, measuring the time taken by each segment is essential. By instrumenting segments, you can track the time taken by functions and code blocks that make up the segments, such as external calls, datastore calls, adding messages to queues, and background tasks. This information is powerful for gaining insights into the time taken by specific functions and code blocks.&lt;/p&gt;

&lt;p&gt;Here's an example of a segment as seen in our &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-segments/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;docs&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;segment := newrelic.Segment{}
segment.Name = "yourSegmentName"
segment.StartTime = txn.StartSegmentNow()
// insert your code logic here
segment.End()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To effectively instrument Go, it is important to understand the three types of segments. Choosing the appropriate segment is essential to ensure that they appear correctly in the UI. Properly ending each transaction or segment is mandatory, as failure to do so will result in the instrumented function not appearing in New Relic.&lt;/p&gt;

&lt;p&gt;Function segments: Instrumenting a function as a segment is equivalent to instrumenting any other block of code as a segment. This means that the process of measuring the execution time of a function or any arbitrary code block is essentially the same.&lt;/p&gt;

&lt;p&gt;Here's an example of a function segment as seen in our &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-segments/#segment-function?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;docs&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;segment := txn.StartSegment("yourSegmentName")
// insert your code logic here
segment.End()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Datastore Segments: If you want to improve the performance of your datastore calls, you can use a datastore segment to instrument them. By doing so, you'll be able to gather more detailed insights into how your datastore is performing and identify any areas that may be causing issues. A datastore segment allows you to see the resulting datastore segments in the transactions breakdown table and Databases tab of the transactions page within New Relic. This gives you access to more granular data about the performance of your datastore, which can help you make more informed decisions about optimizing it for your specific needs.&lt;/p&gt;

&lt;p&gt;Here's an example of a datastore segment as seen in our &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-segments/#go-datastore-segments?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;docs&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;s := newrelic.DatastoreSegment{
    Product: newrelic.DatastoreMySQL,
    Collection: "users",
    Operation: "INSERT",
    ParameterizedQuery: "INSERT INTO users (name, age) VALUES ($1, $2)",
    QueryParameters: map[string]interface{}{
        "name": "Dracula",
        "age": 439,
    },
    Host: "mysql-server-1",
    PortPathOrID: "3306",
    DatabaseName: "my_database",
}
s.StartTime = txn.StartSegmentNow()
// insert your code logic here
s.End()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;External segments: For your Go application's external service calls, such as web services, cloud resources, and other network requests, you can instrument them with external segments. This allows the resulting external segments to be displayed in the transactions breakdown table and external services page within New Relic.&lt;/p&gt;

&lt;p&gt;Here's an example of a external segment as seen in our &lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-segments/#go-external-segments?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;docs&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;func external(txn *newrelic.Transaction, req *http.Request) (*http.Response, error) {
    s := newrelic.StartExternalSegment(txn, req)
    response, err := http.DefaultClient.Do(req)
    s.Response = response
    s.End()
    return response, err
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, here's a sample code of how everything fits together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func randomFormat() string {

    //Monitor a transaction
    nrTxnTracer := nrApp.StartTransaction("randomFormat")
    defer nrTxnTracer.End()

    // Random sleep to simulate delays
    randomDelayOuter := rand.Intn(40)
    time.Sleep(time.Duration(randomDelayOuter) * time.Microsecond)

    // Create a segment
    nrSegment := nrTxnTracer.StartSegment("Formats")

    // Random sleep to simulate delays
    randomDelayInner := rand.Intn(80)
    time.Sleep(time.Duration(randomDelayInner) * time.Microsecond)

    // A slice of message formats.
    formats := []string{
        "Hi, %v. Welcome!",
        "Great to see you, %v!",
        "Good day, %v! Well met!",
        "%v! Hi there!",
        "Greetings %v!",
        "Hello there, %v!",
    }

    // End a segment
    nrSegment.End()

    // Return a randomly selected message format by specifying
    // a random index for the slice of formats.
    return formats[rand.Intn(len(formats))]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TXR9uc_F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2ep4hxj7gb1nketco6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TXR9uc_F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2ep4hxj7gb1nketco6c.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J5ObCCns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3al6kzop8so2drpevwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J5ObCCns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3al6kzop8so2drpevwk.png" alt="Image description" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HU0xO38p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urxruw3ilwuxir7qkaid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HU0xO38p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urxruw3ilwuxir7qkaid.png" alt="Image description" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR/blob/main/2.goGreet/answers.go"&gt;See full sample code on transactions and segments.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 5: Custom attributes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Utilizing custom attributes can be highly beneficial when using a New Relic such as APM, browser, mobile, infrastructure, and synthetics. This enhancement allows for the addition of personalized metadata to existing events. Custom attributes provide essential business and operational context to existing events, consisting of key-value pairs that offer metadata related to the associated events. This provides the ability to improve custom charts and queries to analyze the data, as discussed in &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1#toc-tip-one-learn-why-you-should-instrument?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;Tip 1: Learn why you should instrument&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Various types of business context can be added as custom attributes, including customer ID, customer market segment, customer value classification, or transaction identifiers. Operational context can also be added as custom attributes, including feature flags that were utilized, datastore used, infrastructure accessed, or errors detected and ignored.&lt;/p&gt;

&lt;p&gt;Here's an example of &lt;code&gt;AddAttribute()&lt;/code&gt; to add metadata to your transactions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;txn.AddAttribute("product", "shoes")
txn.AddAttribute("price", 69.90)
txn.AddAttribute("onSale", true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/api-guides/guide-using-go-agent-api/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;See additional details using the Go agent API, including AddAttribute().&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's an example of capturing a custom attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func Hello(name string) (string, error) {

    // Monitor a transaction
    nrTxnTracer := nrApp.StartTransaction("Hello")
    defer nrTxnTracer.End()

    // If no name was given, return an error with a message.
    if name == "" {
        return name, errors.New("empty name")
    }

    // Create a message using a random format.
    message := fmt.Sprintf(randomFormat(), name)

    // Custom attributes by using this method in a transaction
    nrTxnTracer.AddAttribute("message", message)
    return message, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o-YEPXrg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/napavyyt3goto0quipln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o-YEPXrg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/napavyyt3goto0quipln.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR/blob/main/2.goGreet/answers.go"&gt;See full sample code on transactions and segments, including custom attributes.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 6: Modularize your instrumentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=kklk6djnth"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DkGr9Q5h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/c7a87fa37bd1d19af52c83b7965c3a31.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?wvideo=kklk6djnth"&gt;Top 10 tips for instrumenting Golang with New Relic, part 2 | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At some point, you will need to attach instrumentation at scale throughout your environment. This may seem daunting, but it' a critical step in ensuring your application performs optimally. Consider discussing with your team or engineering lead to determine the best strategic location for instrumenting all of your request calls.&lt;/p&gt;

&lt;p&gt;This could include examining the architecture of your application to identify potential chokepoints and considering the types of metrics you want to collect. You may also want to consider any potential tradeoffs between the depth and breadth of instrumentation. Ultimately, the key is to approach this process thoughtfully and systematically, ensuring that your instrumentation strategy aligns with your broader goals and objectives.&lt;/p&gt;

&lt;p&gt;We recommend instrumenting the middleware layer with a wrapper, as demonstrated in this example using the Gin framework. This package, nrgin, instruments &lt;a href="https://github.com/gin-gonic/gin"&gt;https://github.com/gin-gonic/gin&lt;/a&gt; applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router := gin.Default()
// add the nrgin middleware as the first middleware or route in your application.
router.Use(nrgin.Middleware(app))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The middleware creates a Gin middleware that instrument all requests. Use this package to instrument inbound requests handled by a gin.Engine. Call nrgin.Middleware to get a gin.HandlerFunc, which can be added to your application as a middleware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router := gin.Default()

// Package nrgin instruments https://github.com/gin-gonic/gin applications.
router.Use(nrgin.Middleware(nrApp))

router.GET("/games", getgames)
router.GET("/games/:id", getgameByID)
router.POST("/games", postgames)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nKzE_eZV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp2nwwmqcx89r2vttirb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nKzE_eZV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp2nwwmqcx89r2vttirb.png" alt="Image description" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note these two pieces of helpful documentation: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://pkg.go.dev/github.com/newrelic/go-agent/v3/integrations/nrgin"&gt;Instrumenting Gin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/newrelic/go-agent/blob/master/v3/integrations/nrgin/example/main.go"&gt;See full code sample with Gin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/newrelic/go-agent/tree/master/v3/integrations"&gt;More integration examples to explore with New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For more information, don't forget to visit &lt;a href="https://pkg.go.dev/github.com/newrelic/go-agent"&gt;the official page for the New Relic Go agent.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-2?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Golang"&gt;click here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>monitoring</category>
      <category>observability</category>
    </item>
    <item>
      <title>Top 10 tips for instrumenting Golang with New Relic, part 1</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Tue, 31 Oct 2023 17:47:40 +0000</pubDate>
      <link>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-1-579e</link>
      <guid>https://dev.to/newrelic/top-10-tips-for-instrumenting-golang-with-new-relic-part-1-579e</guid>
      <description>&lt;p&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Top-10-tips-for-golang"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Are you building modern apps in Golang? This multi-part blog series will help you instrument Golang faster by providing tips, guidance, and best practices with New Relic.&lt;/p&gt;

&lt;p&gt;Typically, the content in this blog would be presented in a workshop, but we've made it a blog series so anyone can follow along "hands-on," using sample code, Instruqt, this blog, and videos. For the best experience:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ntcsteve/instrumentGolangWithNR"&gt;See and run the full code that I'll be walking through in this multi-part series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://play.instruqt.com/newrelic/invite/s5kyxbycvqqp"&gt;Follow the hands-on lab in Instruqt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read along with this blog and follow the videos below&lt;/p&gt;

&lt;p&gt;The following two videos will give an overview of Instruqt and some instructions about how to use it if you haven't done that before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview of Instruqt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?wvideo=lxcbgogplq"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HFkSdOcR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/09f86dc2005bc12241f3de6c69b3d3a6.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?wvideo=lxcbgogplq"&gt;Top Tips for Instrumenting Golang | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instruqt UI navigation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?wvideo=rhe9wxh4il"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WDmb6V70--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/194f2db4c52d0848b593944cd6ed2030.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?wvideo=rhe9wxh4il"&gt;Top Tips for Instrumenting Golang | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you're set up, let's learn a little more about instrumentation of Golang.&lt;/p&gt;

&lt;h2&gt;
  
  
  An introduction to Golang instrumentation
&lt;/h2&gt;

&lt;p&gt;Golang is increasingly becoming popular and loved by many developers when building modern cloud-native services. Golang, also known as Go, is a compiled, high-performance language meant to be simple, easy to learn, and effective to use. Since its inception back in 2009, Go has continued to grow significantly, as seen by the latest Stack Overflow 2022 survey.&lt;/p&gt;

&lt;p&gt;While developers continue to build more services in Go, finding effective ways to instrument better for Go can be confusing and frustrating. Interpreter languages like PHP, Ruby, Python, and JavaScript, don’t require a pre-runtime translation of code, meaning you can automatically instrument your applications. But, Go, like C and Rust, is a compiled language, meaning it relies on translators that generate machine code from source code. So you can't use a dynamic and automatic instrumentation technique like bytecode injection.&lt;/p&gt;

&lt;p&gt;Manual instrumentation is required to get better visibility to find the root cause of an issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 1: Learn why you should instrument&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer is simple: you’ll want to quickly identify issues when there’s a production incident or an outage. It would be great if finding a root cause of an outage was easy and could be followed quickly with a fix and a plan for an effective remediation path. But, the reality is engineers often firefight among an abundance of noise and staggering amounts of information. They traverse multiple tools just to find an answer.&lt;/p&gt;

&lt;p&gt;Often, you might rely on infrastructure metrics or troll through endless messy logs to understand and triage a problem. But it can be hard to understand what’s happening inside the application. Without the additional help from software engineers to instrument their Go apps, Ops engineers often resort to guesswork or intuition when an incident or outage occurs.&lt;/p&gt;

&lt;p&gt;So, before you start your instrumentation effort, start with a simple rule: Ask yourself, "What is the minimal viable instrumentation (or MVI) that I can instrument to help my fellow Ops engineers quickly identify issues?"&lt;/p&gt;

&lt;p&gt;Admittedly, most of the time engineers are only interested in identifiers. For example, if there is a failed transaction, an engineer wants to know which &lt;code&gt;userID&lt;/code&gt;, &lt;code&gt;transactionID&lt;/code&gt;, or some form of contextual information can pinpoint exactly the affected request for a remediation path. But relying on status codes such as 404 or 500 isn’t going to be sufficient anymore. You'll need additional contextual metadata to work effectively as your environment starts to get complex.&lt;/p&gt;

&lt;p&gt;Here are the four key identifiers you should consider as part of your instrumentation.&lt;/p&gt;

&lt;p&gt;Request Identifier: correlation ID between requests (such as &lt;code&gt;accountID&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;State Identifier: current operations or status (such as completed)&lt;/p&gt;

&lt;p&gt;Environment Identifier: operating domain metadata (such as software version)&lt;/p&gt;

&lt;p&gt;Parameters Identifier: variables used to pass information (such as total or account)&lt;/p&gt;

&lt;p&gt;These identifiers are the &lt;strong&gt;building blocks&lt;/strong&gt; to improve observability.&lt;/p&gt;

&lt;p&gt;After you've decided on your identifiers, plan ahead with your top five most important software functions that you should expose with telemetry, using the New Relic Go agent, and add more as you need over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 2: Start the flow of data into New Relic using StartTransaction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following video will step through tips two and three, followed by further explanation about this process in this blog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?wvideo=4qy3uuy932"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JBcJWpHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://embed-ssl.wistia.com/deliveries/03edb1666d165b770d15641476a31b89.jpg%3Fimage_play_button_size%3D2x%26image_crop_resized%3D960x540%26image_play_button%3D1%26image_play_button_color%3D2be68be0" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?wvideo=4qy3uuy932"&gt;Top Tips for Instrumenting Golang | New Relic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you start using the New Relic Go agent for the first time, there’s a high possibility you won’t see any data, which is different than interpreted languages such as PHP, Ruby, Python, and JavaScript.&lt;/p&gt;

&lt;p&gt;For interpreted languages, the New Relic SDK begins instrumenting supported framework functions, methods, or classes. But for Go, you need to start instrumentation by writing a &lt;code&gt;StartTransaction&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;txn := app.StartTransaction("transaction_name")
defer txn.End()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note these two pieces of helpful documentation: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/instrumentation/instrument-go-transactions/"&gt;Instrument and monitor Go transactions&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.newrelic.com/docs/apm/agents/go-agent/installation/install-new-relic-go/"&gt;Install New Relic for Go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app statement refers to the variable assigned during the New Relic configuration process, while the defer statement defers the segment ending until the function closes. This means that setting up New Relic for your Golang app requires you to add New Relic methods to your source code manually. Here is a simple instrumentation of a popular function: &lt;code&gt;print()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
   app, err := newrelic.NewApplication(
       newrelic.ConfigAppName("Short Lived App"),
       newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
       newrelic.ConfigDebugLogger(os.Stdout),
   )
   if nil != err {
       fmt.Println(err)
       os.Exit(1)
   }

   // Wait for the application to connect.
   if err := app.WaitForConnection(5 * time.Second); nil != err {
       fmt.Println(err)
   }

   // Do the tasks at hand.  Perhaps record them using transactions and/or
   // custom events.
   tasks := []string{"white", "black", "red", "blue", "green", "yellow"}
   for _, task := range tasks {
       txn := app.StartTransaction("task")
       time.Sleep(10 * time.Millisecond)
       txn.End()
       app.RecordCustomEvent("task", map[string]interface{}{
           "color": task,
       })
   }

   // Shut down the application to flush data to New Relic.
   app.Shutdown(5 * time.Second)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the additional code segment - &lt;code&gt;app.WaitForConnection&lt;/code&gt; and &lt;code&gt;app.Shutdown&lt;/code&gt;, where we wait for the application to connect and shut down for five seconds. You need to do this initially because the harvest cycle in the New Relic Go agent is five seconds. This is only required if you are instrumenting a small sample app or a short-lived app in your development environment. For production deployment, you won’t need to use this code segment if your app runs longer than five seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zxno6l9y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlpk79sppsr9pk6npzxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zxno6l9y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hlpk79sppsr9pk6npzxq.png" alt="Image description" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a full code sample in one file, see &lt;a href="https://github.com/newrelic/go-agent/blob/master/v3/examples/short-lived-process/main.go"&gt;this repository on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 3: Embed observability practices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you start instrumenting more with your Go apps, take some time to discuss and review incidents with your team or engineering leads. Conduct a post-mortem or retrospective to understand what additional metadata engineers need from the app to triage issues more effectively.&lt;/p&gt;

&lt;p&gt;Observability is about better understanding the inner workings of a system through exposed external outputs—getting one step closer to the why. Observability is also a scientific engineering approach to refine, experiment, learn, and add observations over time, so you can gain more confidence in your system.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, this is a great opportunity to embed observability practices as part of your instrumentation and development cycle. Observability is not about monitoring metrics or using an existing operations approach to look at hundreds or thousands of dashboards or alerts.&lt;/p&gt;

&lt;p&gt;Often engineers will debate whether metrics, tracing, or logs are the best, but each telemetry type has its own pros and cons. Ultimately observability is all about encouraging deep collaboration between Dev and Ops, separating noise and signals. You gain more confidence over time in your systems by exposing contextual information either through better usage of metrics, tracing, or logs.&lt;/p&gt;

&lt;p&gt;Unlike automatic instrumentation, the good news about manual instrumentation for Go is that there are no hidden, weird, or sudden surprises. Starting fresh allows you to embed observability concepts, knowing exactly what the instrumentation is doing, and you have absolute control over what you instrument in your app. The package from New Relic is stable, open, and available so you can understand what the agent is doing underneath the hood.&lt;/p&gt;

&lt;p&gt;For more information, don't forget to visit &lt;a href="https://pkg.go.dev/github.com/newrelic/go-agent"&gt;the official page for the New Relic Go agent&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/top-tips-golang-1?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=global-fy24-q3-Top-10-tips-for-golang"&gt;click here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>development</category>
      <category>tutorial</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>How to obfuscate logs using Fluent Bit in New Relic</title>
      <dc:creator>ntcsteve</dc:creator>
      <pubDate>Tue, 23 May 2023 23:06:02 +0000</pubDate>
      <link>https://dev.to/newrelic/how-to-obfuscate-logs-using-fluent-bit-in-new-relic-b69</link>
      <guid>https://dev.to/newrelic/how-to-obfuscate-logs-using-fluent-bit-in-new-relic-b69</guid>
      <description>&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/obfuscate-logs-fluentbit?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you need to protect sensitive information and follow data privacy regulations, it's critical to obfuscate your log data, which means obscuring personally identifiable information (PII). But effectively concealing PII in logs might take time to implement, can increase compute resources, and might not work well with all types of logs. &lt;/p&gt;

&lt;p&gt;It's vital to &lt;a href="https://newrelic.com/blog/nerdlog/log-obfuscation?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;obfuscate&lt;/a&gt; PII and other sensitive data in your &lt;a href="https://newrelic.com/blog/how-to-relic/what-is-log-management?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;logs&lt;/a&gt; because you can ensure confidentiality and integrity of the data, while continuing to use logs to analyze system behavior and troubleshoot issues. You can mitigate the risk of data breaches and unauthorized access and still get your ongoing debugging work done.&lt;/p&gt;

&lt;p&gt;This blog post shares helpful tips and code samples for obfuscating logs through client-side Fluent Bit with New Relic infrastructure monitoring. Whether you’re evaluating New Relic with other platforms, or you’re already using New Relic and seeking to safeguard sensitive information, read on to explore advanced configuration options in New Relic. You’ll gain advice on logs obfuscation, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The importance of log obfuscation and a few popular approaches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using Fluent Bit in New Relic infrastructure monitoring&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to obfuscate your logs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to remove sensitive data from your logs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Log obfuscation is both important and difficult
&lt;/h2&gt;

&lt;p&gt;Log obfuscation is a critical security measure that helps protect computer systems against data breaches and unauthorized access to sensitive information. You might need to remove or obfuscate attributes from your logs to protect sensitive data like email addresses or credit card numbers from customer accounts, so they’re not visible in the logs. Removing or obfuscating these attributes can prevent unauthorized access to sensitive data in case of log leakages or malicious users. &lt;/p&gt;

&lt;p&gt;An added bonus of eliminating unnecessary attributes is reducing log sizes, making them easier to manage and analyze. This can boost overall system performance and reduce costs for storing and processing large log files.&lt;/p&gt;

&lt;p&gt;Implementing obfuscation for logs is especially challenging. It’s tricky to ensure that the obfuscated logs provide enough information for effective troubleshooting and analysis, the reason you need logs in the first place. This challenge is even more significant when dealing with large, complex systems that generate huge amounts of log data.&lt;/p&gt;

&lt;p&gt;A few log obfuscation approaches&lt;br&gt;
To overcome this challenge, engineering teams use various techniques such as redaction, hashing, and encryption to obfuscate sensitive data while maintaining the overall integrity of the log files. &lt;/p&gt;

&lt;p&gt;One popular technique involves creating custom rules using &lt;a href="https://docs.newrelic.com/docs/logs/ui-data/built-log-parsing-rules/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;Grok patterns&lt;/a&gt; or Lua scripts to mask or remove sensitive information from log data. &lt;/p&gt;

&lt;p&gt;The process begins by identifying the types of sensitive data that need to be obfuscated. For example, you know that you have IP addresses, credit card numbers, and usernames for your customers. &lt;br&gt;
Then you define custom rules in Grok patterns or Lua scripts to match the sensitive data patterns and specify how they should be masked or removed. &lt;br&gt;
The next step is to test the custom rules against sample log data to ensure they correctly match the intended data patterns and apply the appropriate obfuscation. &lt;br&gt;
After the rules have been tested, you can integrate them into the log processing pipeline with a log management tool like Logstash, &lt;a href="https://docs.newrelic.com/docs/logs/forward-logs/fluent-bit-plugin-log-forwarding/?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;Fluent Bit&lt;/a&gt;, or FluentD. You can use all of these log management tools to forward the processed logs to New Relic for further analysis.&lt;/p&gt;
&lt;h2&gt;
  
  
  Finding the right balance between security and usability in your logs
&lt;/h2&gt;

&lt;p&gt;To make sure the logs remain a valuable tool for monitoring system performance and troubleshooting, it’s crucial to balance the level of obfuscation with how useful they are for troubleshooting and analysis. Effective log obfuscation requires careful consideration of the trade-offs between security and usability. &lt;/p&gt;

&lt;p&gt;Grok patterns are a helpful pattern-matching tool for parsing data from unstructured log files, and Lua scripts offer more flexibility and control over the log processing pipeline but may require more development effort. The choice between Grok patterns and Lua scripts will depend on the needs and maturity of the log processing pipeline. &lt;/p&gt;
&lt;h2&gt;
  
  
  How Fluent Bit works with New Relic infrastructure monitoring
&lt;/h2&gt;

&lt;p&gt;Other techniques such as Grok patterns or Lua scripts are available to modify logs, but using Fluent Bit in New Relic infrastructure monitoring is a more straightforward approach to protect sensitive information in logs.&lt;/p&gt;

&lt;p&gt;Fluent Bit is an open-source data collector for a unified logging layer, designed to collect, filter, and forward logs and metrics data to various destinations. Embedded as part of New Relic infrastructure monitoring, Fluent Bit is deployed as a client-side agent by default. This means you can accomplish advanced configurations to collect logs and metrics data from multiple sources and send them to New Relic for analysis.  The next diagram shows how &lt;a href="https://docs.newrelic.com/docs/logs/forward-logs/enable-log-management-new-relic?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;log forwarding works in New Relic&lt;/a&gt;: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PUv-XCzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnrfb9un31w8altz30sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PUv-XCzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnrfb9un31w8altz30sd.png" alt="Image description" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the &lt;a href="https://docs.newrelic.com/docs/logs/forward-logs/forward-your-logs-using-infrastructure-agent/#fluentbit?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;New Relic infrastructure agent runs&lt;/a&gt;, it processes configuration files in the logging.d directory. As a result, it generates a run-time Fluent Bit configuration file with the necessary [INPUT], [FILTER], and [OUTPUT] sections. If you provided an external Fluent Bit configuration file via the fluentbit option, the agent also declares an &lt;a class="mentioned-user" href="https://dev.to/include"&gt;@include&lt;/a&gt; in the generated configuration file.&lt;/p&gt;

&lt;p&gt;By default, the runtime file uses the default Fluent Bit configuration values because it doesn’t define a [SERVICE] section. But you can customize the configuration settings by creating your own [SERVICE] section in an external Fluent Bit configuration file and including it with the fluentbit option. To use the advanced configuration in Fluent Bit, such as logs obfuscation, you must generate separate configuration and parsers files externally and use them with the fluentbit, config_file, and parsers_file options in the agent.&lt;/p&gt;

&lt;p&gt;Here’s an example of using Fluent Bit's additional configuration to forward obfuscated logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logs:
  - name: external-fluentbit-config-and-parsers-file
    fluentbit:
      config_file: /etc/newrelic-infra/logging.d/fluent-bit.conf
      parsers_file: /etc/newrelic-infra/logging.d/parsers.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The config_file option refers to the path of an existing Fluent Bit configuration file that you can use to customize your Fluent Bit configuration settings. This file includes the necessary [INPUT], [FILTER], and [OUTPUT] sections, among others. &lt;/p&gt;

&lt;p&gt;The parsers_file option refers to the path of an existing Fluent Bit parsers file. This file defines custom parsing rules that Fluent Bit can use to extract information from incoming logs. Using parsers, you can transform raw log data into structured data, making it easier to analyze and understand.&lt;/p&gt;

&lt;p&gt;Important: To forward logs for common use cases, the infrastructure agent provides simple log forwarding configurations in the logging.d/ directory's YAML files. These files are automatically translated into Fluent Bit configuration files with the correct format and configuration defaults.&lt;/p&gt;

&lt;h2&gt;
  
  
  Obfuscate your logs using Fluent Bit in New Relic
&lt;/h2&gt;

&lt;p&gt;To start using Fluent Bit in New Relic, you need two files in place: the parsers_file for parsing files and the config_file for modifying records. Follow these steps, using advanced settings with Fluent Bit in New Relic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Disable existing New Relic Logs Configuration
&lt;/h2&gt;

&lt;p&gt;Before using Fluent Bit, you must disable any existing New Relic logs configurations. You'll either need to remove or comment out the following configuration in your YAML file. In this example, the configuration is commented out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# logs:
#   - name: nginx
#     file: /var/log/nginx.log
#     attributes:
#       logtype: nginx
#       environment: workshop
#       engineer: yourname
#       country: yourcountry
#     pattern: 500|404|400
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create the fluentbit.yml file
&lt;/h2&gt;

&lt;p&gt;Create or rename your file to fluentbit.yml, and include this path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logs:
  - name: external-fluentbit-config-and-parsers-file
    fluentbit:
      config_file: /etc/newrelic-infra/logging.d/fluent-bit.conf
      parsers_file: /etc/newrelic-infra/logging.d/parsers.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s an example of the file structure to use with Fluent Bit in New Relic infrastructure monitoring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lN_-vGUH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/174fkmobn934foccm0ra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lN_-vGUH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/174fkmobn934foccm0ra.png" alt="Image description" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create a parsers_file
&lt;/h2&gt;

&lt;p&gt;Create a file called parsers.conf, and include your Fluent Bit parser configuration. You can use the power of the parser filter plugin in Fluent Bit to parse fields in event records. You can extract specific information from your logs and transform it into structured data that’s easier to analyze and understand. You can test these custom rules against sample log data to ensure they match the intended data patterns and apply the appropriate obfuscation.&lt;/p&gt;

&lt;p&gt;Here’s the default sample parser provided by Fluent Bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[PARSER]
    Name dummy_test
    Format regex
    Regex ^(?&amp;lt;INT&amp;gt;[^ ]+) (?&amp;lt;FLOAT&amp;gt;[^ ]+) (?&amp;lt;BOOL&amp;gt;[^ ]+) (?&amp;lt;STRING&amp;gt;.+)$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an NGINX parser in a regular expression (regex) example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[PARSER]
    Name   nginx
    Format regex
    Regex ^(?&amp;lt;source&amp;gt;[^ ]*) (?&amp;lt;host&amp;gt;[^ ]*) (?&amp;lt;user&amp;gt;[^ ]*) \\[(?&amp;lt;time&amp;gt;[^\\]]*)\\] "(?&amp;lt;method&amp;gt;\\S+)(?: +(?&amp;lt;path&amp;gt;[^\\"]*?)(?: +\\S*)?)?" (?&amp;lt;code&amp;gt;[^ ]*) (?&amp;lt;size&amp;gt;[^ ]*)(?: "(?&amp;lt;referer&amp;gt;[^\\"]*)" "(?&amp;lt;agent&amp;gt;[^\\"]*)")
    Time_Key time
    Time_Format %d/%b/%Y:%H:%M:%S %z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a regular expression pattern, this code defines a custom parser for NGINX access logs. The regular expression captures fields such as the client's IP address, time of the request, HTTP method, URL path, status code, and user agent. The Time_Key directive specifies the time field, and Time_Format defines the time format in the log line. This configuration enables log processing tools to parse NGINX access logs and extract relevant fields for analysis and visualization. For more examples, you can explore parsers provided by Fluent Bit, New Relic, or open source communities.&lt;/p&gt;

&lt;p&gt;In the next example, you’ll use  for obfuscating and removing logs attributes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Create a config_file
&lt;/h2&gt;

&lt;p&gt;Create a file called fluent-bit.conf file and include a modify configuration where you’ll use one of the most valuable features of Fluent Bit, the Modify Filter plugin. Use this plugin to modify records using rules and conditions. You can change the content of log records based on specific criteria or requirements. This makes it easier to analyze and troubleshoot issues in your system.&lt;/p&gt;

&lt;p&gt;Here’s the default sample from Fluent Bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INPUT]
    Name mem
    Tag  mem.local

[OUTPUT]
    Name  stdout
    Match *

[FILTER]
    Name modify
    Match *
    Add Service1 SOMEVALUE
    Add Service3 SOMEVALUE3
    Add Mem.total2 TOTALMEM2
    Rename Mem.free MEMFREE
    Rename Mem.used MEMUSED
    Rename Swap.total SWAPTOTAL
    Add Mem.total TOTALMEM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s an example configuration file to use to obfuscate attributes in your logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INPUT]
    Name              tail
    Tag               nginx
    Path              /var/log/nginx.log
    DB                /var/log/nginx_error.db
    Path_Key          filename
    Parser            nginx
    Mem_Buf_Limit     8MB
    Skip_Long_Lines   On
    Refresh_Interval  30

[FILTER]
    Name record_modifier
    Match *
    Record logtype nginx
    Record hostname ${HOSTNAME}
    Record service_name Coming_From_FluentBit

[FILTER]
    Name modify
    Match *
    Set source XXXXX

[OUTPUT]
    Name newrelic
    Match *
    apiKey INGEST KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After applying the configuration file to obfuscate logs through Fluent Bit, your end result will look something like this example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EIvQVfUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tk87mb05gy2a51zc7ss9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EIvQVfUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tk87mb05gy2a51zc7ss9.png" alt="Image description" width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Restart the agent
&lt;/h2&gt;

&lt;p&gt;To use configurations from Fluent Bit, restart the New Relic infrastructure agent. Before restarting, ensure that both your files (fluent-bit.conf and parsers.conf) are correctly referenced in the fluentbit.yml file, as shown back in step 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logs:
  - name: external-fluentbit-config-and-parsers-file
    fluentbit:
      config_file: /etc/newrelic-infra/logging.d/fluent-bit.conf
      parsers_file: /etc/newrelic-infra/logging.d/parsers.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the command to restart the New Relic infrastructure agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart newrelic-infra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Remove sensitive data from logs
&lt;/h2&gt;

&lt;p&gt;In the previous example in Step 4, you learned how to obfuscate a log using Set. Another alternative is to use the Remove operation, a powerful tool for modifying logs. Use it to easily remove unnecessary or sensitive data from a record. Delete a key-value pair from a record, if it exists, using the Record Modifier plugin.&lt;/p&gt;

&lt;p&gt;Here’s an example configuration file to remove attributes in your logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INPUT]
    Name              tail
    Tag               nginx
    Path              /var/log/nginx.log
    DB                /var/log/nginx_error.db
    Path_Key          filename
    Parser            nginx
    Mem_Buf_Limit     8MB
    Skip_Long_Lines   On
    Refresh_Interval  30

[FILTER]
    Name record_modifier
    Match *
    Record logtype nginx
    Record hostname ${HOSTNAME}
    Record service_name Coming_From_FluentBit
    Remove_key source

[OUTPUT]
    Name newrelic
    Match *
    apiKey INGEST KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After applying the configuration file to remove log data using Fluent Bit, your final result should look something like this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5r1uKLv2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flouikiuiqku85anm3oc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5r1uKLv2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flouikiuiqku85anm3oc.png" alt="Image description" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Important: Restarting the New Relic infrastructure agent after applying a new configuration is a crucial step to ensure the changes take effect. This step is particularly important because it guarantees that the new configuration settings are loaded and used by the agent. Make sure to restart the agent after applying new configurations, the same as shown in Step 5.&lt;/p&gt;

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

&lt;p&gt;You've reviewed examples of straightforward ways to ensure confidentiality and integrity of log data using Fluent Bit in New Relic infrastructure monitoring.&lt;/p&gt;

&lt;p&gt;Specifically, you've learned how to protect sensitive information in logs by obfuscating data with Fluent Bit log configurations. For example, after a key value  is identified, you can easily use the Modify filter plugin to obfuscate it or the Record Modifier filter plugin to remove log attributes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;To read this full New Relic blog, &lt;a href="https://newrelic.com/blog/how-to-relic/obfuscate-logs-fluentbit?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-Fluent-Bit-in-New-Relic"&gt;click here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not an existing New Relic user? &lt;a href="https://newrelic.com/signup?utm_source=devto&amp;amp;utm_medium=community&amp;amp;utm_campaign=amer-fy-24-q1-devto_updates"&gt;Sign up for a free account&lt;/a&gt; to get started!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
