github.com/newrelic/go-agent@v3.26.0+incompatible/config.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package newrelic
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"net/http"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/newrelic/go-agent/internal"
    14  )
    15  
    16  // Config contains Application and Transaction behavior settings.
    17  // Use NewConfig to create a Config with proper defaults.
    18  type Config struct {
    19  	// AppName is used by New Relic to link data across servers.
    20  	//
    21  	// https://docs.newrelic.com/docs/apm/new-relic-apm/installation-configuration/naming-your-application
    22  	AppName string
    23  
    24  	// License is your New Relic license key.
    25  	//
    26  	// https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/license-key
    27  	License string
    28  
    29  	// Logger controls go-agent logging.  For info level logging to stdout:
    30  	//
    31  	//	cfg.Logger = newrelic.NewLogger(os.Stdout)
    32  	//
    33  	// For debug level logging to stdout:
    34  	//
    35  	//	cfg.Logger = newrelic.NewDebugLogger(os.Stdout)
    36  	//
    37  	// See https://github.com/newrelic/go-agent/blob/master/GUIDE.md#logging
    38  	// for more examples and logging integrations.
    39  	Logger Logger
    40  
    41  	// Enabled controls whether the agent will communicate with the New Relic
    42  	// servers and spawn goroutines.  Setting this to be false is useful in
    43  	// testing and staging situations.
    44  	Enabled bool
    45  
    46  	// Labels are key value pairs used to roll up applications into specific
    47  	// categories.
    48  	//
    49  	// https://docs.newrelic.com/docs/using-new-relic/user-interface-functions/organize-your-data/labels-categories-organize-apps-monitors
    50  	Labels map[string]string
    51  
    52  	// HighSecurity guarantees that certain agent settings can not be made
    53  	// more permissive.  This setting must match the corresponding account
    54  	// setting in the New Relic UI.
    55  	//
    56  	// https://docs.newrelic.com/docs/agents/manage-apm-agents/configuration/high-security-mode
    57  	HighSecurity bool
    58  
    59  	// SecurityPoliciesToken enables security policies if set to a non-empty
    60  	// string.  Only set this if security policies have been enabled on your
    61  	// account.  This cannot be used in conjunction with HighSecurity.
    62  	//
    63  	// https://docs.newrelic.com/docs/agents/manage-apm-agents/configuration/enable-configurable-security-policies
    64  	SecurityPoliciesToken string
    65  
    66  	// CustomInsightsEvents controls the behavior of
    67  	// Application.RecordCustomEvent.
    68  	//
    69  	// https://docs.newrelic.com/docs/insights/new-relic-insights/adding-querying-data/inserting-custom-events-new-relic-apm-agents
    70  	CustomInsightsEvents struct {
    71  		// Enabled controls whether RecordCustomEvent will collect
    72  		// custom analytics events.  High security mode overrides this
    73  		// setting.
    74  		Enabled bool
    75  	}
    76  
    77  	// TransactionEvents controls the behavior of transaction analytics
    78  	// events.
    79  	TransactionEvents struct {
    80  		// Enabled controls whether transaction events are captured.
    81  		Enabled bool
    82  		// Attributes controls the attributes included with transaction
    83  		// events.
    84  		Attributes AttributeDestinationConfig
    85  		// MaxSamplesStored allows you to limit the number of Transaction
    86  		// Events stored/reported in a given 60-second period
    87  		MaxSamplesStored int
    88  	}
    89  
    90  	// ErrorCollector controls the capture of errors.
    91  	ErrorCollector struct {
    92  		// Enabled controls whether errors are captured.  This setting
    93  		// affects both traced errors and error analytics events.
    94  		Enabled bool
    95  		// CaptureEvents controls whether error analytics events are
    96  		// captured.
    97  		CaptureEvents bool
    98  		// IgnoreStatusCodes controls which http response codes are
    99  		// automatically turned into errors.  By default, response codes
   100  		// greater than or equal to 400, with the exception of 404, are
   101  		// turned into errors.
   102  		IgnoreStatusCodes []int
   103  		// Attributes controls the attributes included with errors.
   104  		Attributes AttributeDestinationConfig
   105  	}
   106  
   107  	// TransactionTracer controls the capture of transaction traces.
   108  	TransactionTracer struct {
   109  		// Enabled controls whether transaction traces are captured.
   110  		Enabled bool
   111  		// Threshold controls whether a transaction trace will be
   112  		// considered for capture.  Of the traces exceeding the
   113  		// threshold, the slowest trace every minute is captured.
   114  		Threshold struct {
   115  			// If IsApdexFailing is true then the trace threshold is
   116  			// four times the apdex threshold.
   117  			IsApdexFailing bool
   118  			// If IsApdexFailing is false then this field is the
   119  			// threshold, otherwise it is ignored.
   120  			Duration time.Duration
   121  		}
   122  		// SegmentThreshold is the threshold at which segments will be
   123  		// added to the trace.  Lowering this setting may increase
   124  		// overhead.  Decrease this duration if your Transaction Traces are
   125  		// missing segments.
   126  		SegmentThreshold time.Duration
   127  		// StackTraceThreshold is the threshold at which segments will
   128  		// be given a stack trace in the transaction trace.  Lowering
   129  		// this setting will increase overhead.
   130  		StackTraceThreshold time.Duration
   131  		// Attributes controls the attributes included with transaction
   132  		// traces.
   133  		Attributes AttributeDestinationConfig
   134  		// Segments.Attributes controls the attributes included with
   135  		// each trace segment.
   136  		Segments struct {
   137  			Attributes AttributeDestinationConfig
   138  		}
   139  	}
   140  
   141  	// BrowserMonitoring contains settings which control the behavior of
   142  	// Transaction.BrowserTimingHeader.
   143  	BrowserMonitoring struct {
   144  		// Enabled controls whether or not the Browser monitoring feature is
   145  		// enabled.
   146  		Enabled bool
   147  		// Attributes controls the attributes included with Browser monitoring.
   148  		// BrowserMonitoring.Attributes.Enabled is false by default, to include
   149  		// attributes in the Browser timing Javascript:
   150  		//
   151  		//	cfg.BrowserMonitoring.Attributes.Enabled = true
   152  		Attributes AttributeDestinationConfig
   153  	}
   154  
   155  	// HostDisplayName gives this server a recognizable name in the New
   156  	// Relic UI.  This is an optional setting.
   157  	HostDisplayName string
   158  
   159  	// Transport customizes communication with the New Relic servers.  This may
   160  	// be used to configure a proxy.
   161  	Transport http.RoundTripper
   162  
   163  	// Utilization controls the detection and gathering of system
   164  	// information.
   165  	Utilization struct {
   166  		// DetectAWS controls whether the Application attempts to detect
   167  		// AWS.
   168  		DetectAWS bool
   169  		// DetectAzure controls whether the Application attempts to detect
   170  		// Azure.
   171  		DetectAzure bool
   172  		// DetectPCF controls whether the Application attempts to detect
   173  		// PCF.
   174  		DetectPCF bool
   175  		// DetectGCP controls whether the Application attempts to detect
   176  		// GCP.
   177  		DetectGCP bool
   178  		// DetectDocker controls whether the Application attempts to
   179  		// detect Docker.
   180  		DetectDocker bool
   181  		// DetectKubernetes controls whether the Application attempts to
   182  		// detect Kubernetes.
   183  		DetectKubernetes bool
   184  
   185  		// These settings provide system information when custom values
   186  		// are required.
   187  		LogicalProcessors int
   188  		TotalRAMMIB       int
   189  		BillingHostname   string
   190  	}
   191  
   192  	// CrossApplicationTracer controls behaviour relating to cross application
   193  	// tracing (CAT), available since Go Agent v0.11.  The
   194  	// CrossApplicationTracer and the DistributedTracer cannot be
   195  	// simultaneously enabled.
   196  	//
   197  	// https://docs.newrelic.com/docs/apm/transactions/cross-application-traces/introduction-cross-application-traces
   198  	CrossApplicationTracer struct {
   199  		Enabled bool
   200  	}
   201  
   202  	// DistributedTracer controls behaviour relating to Distributed Tracing,
   203  	// available since Go Agent v2.1. The DistributedTracer and the
   204  	// CrossApplicationTracer cannot be simultaneously enabled.
   205  	//
   206  	// https://docs.newrelic.com/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing
   207  	DistributedTracer struct {
   208  		Enabled bool
   209  	}
   210  
   211  	// SpanEvents controls behavior relating to Span Events.  Span Events
   212  	// require that DistributedTracer is enabled.
   213  	SpanEvents struct {
   214  		Enabled    bool
   215  		Attributes AttributeDestinationConfig
   216  	}
   217  
   218  	// DatastoreTracer controls behavior relating to datastore segments.
   219  	DatastoreTracer struct {
   220  		// InstanceReporting controls whether the host and port are collected
   221  		// for datastore segments.
   222  		InstanceReporting struct {
   223  			Enabled bool
   224  		}
   225  		// DatabaseNameReporting controls whether the database name is
   226  		// collected for datastore segments.
   227  		DatabaseNameReporting struct {
   228  			Enabled bool
   229  		}
   230  		QueryParameters struct {
   231  			Enabled bool
   232  		}
   233  		// SlowQuery controls the capture of slow query traces.  Slow
   234  		// query traces show you instances of your slowest datastore
   235  		// segments.
   236  		SlowQuery struct {
   237  			Enabled   bool
   238  			Threshold time.Duration
   239  		}
   240  	}
   241  
   242  	// Attributes controls which attributes are enabled and disabled globally.
   243  	// This setting affects all attribute destinations: Transaction Events,
   244  	// Error Events, Transaction Traces and segments, Traced Errors, Span
   245  	// Events, and Browser timing header.
   246  	Attributes AttributeDestinationConfig
   247  
   248  	// RuntimeSampler controls the collection of runtime statistics like
   249  	// CPU/Memory usage, goroutine count, and GC pauses.
   250  	RuntimeSampler struct {
   251  		// Enabled controls whether runtime statistics are captured.
   252  		Enabled bool
   253  	}
   254  
   255  	// ServerlessMode contains fields which control behavior when running in
   256  	// AWS Lambda.
   257  	//
   258  	// https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/introduction-new-relic-monitoring-aws-lambda
   259  	ServerlessMode struct {
   260  		// Enabling ServerlessMode will print each transaction's data to
   261  		// stdout.  No agent goroutines will be spawned in serverless mode, and
   262  		// no data will be sent directly to the New Relic backend.
   263  		// nrlambda.NewConfig sets Enabled to true.
   264  		Enabled bool
   265  		// ApdexThreshold sets the Apdex threshold when in ServerlessMode.  The
   266  		// default is 500 milliseconds.  nrlambda.NewConfig populates this
   267  		// field using the NEW_RELIC_APDEX_T environment variable.
   268  		//
   269  		// https://docs.newrelic.com/docs/apm/new-relic-apm/apdex/apdex-measure-user-satisfaction
   270  		ApdexThreshold time.Duration
   271  		// AccountID, TrustedAccountKey, and PrimaryAppID are used for
   272  		// distributed tracing in ServerlessMode.  AccountID and
   273  		// TrustedAccountKey must be populated for distributed tracing to be
   274  		// enabled. nrlambda.NewConfig populates these fields using the
   275  		// NEW_RELIC_ACCOUNT_ID, NEW_RELIC_TRUSTED_ACCOUNT_KEY, and
   276  		// NEW_RELIC_PRIMARY_APPLICATION_ID environment variables.
   277  		AccountID         string
   278  		TrustedAccountKey string
   279  		PrimaryAppID      string
   280  	}
   281  }
   282  
   283  // AttributeDestinationConfig controls the attributes sent to each destination.
   284  // For more information, see:
   285  // https://docs.newrelic.com/docs/agents/manage-apm-agents/agent-data/agent-attributes
   286  type AttributeDestinationConfig struct {
   287  	// Enabled controls whether or not this destination will get any
   288  	// attributes at all.  For example, to prevent any attributes from being
   289  	// added to errors, set:
   290  	//
   291  	//	cfg.ErrorCollector.Attributes.Enabled = false
   292  	//
   293  	Enabled bool
   294  	Include []string
   295  	// Exclude allows you to prevent the capture of certain attributes.  For
   296  	// example, to prevent the capture of the request URL attribute
   297  	// "request.uri", set:
   298  	//
   299  	//	cfg.Attributes.Exclude = append(cfg.Attributes.Exclude, newrelic.AttributeRequestURI)
   300  	//
   301  	// The '*' character acts as a wildcard.  For example, to prevent the
   302  	// capture of all request related attributes, set:
   303  	//
   304  	//	cfg.Attributes.Exclude = append(cfg.Attributes.Exclude, "request.*")
   305  	//
   306  	Exclude []string
   307  }
   308  
   309  // NewConfig creates a Config populated with default settings and the given
   310  // appname and license.
   311  func NewConfig(appname, license string) Config {
   312  	c := Config{}
   313  
   314  	c.AppName = appname
   315  	c.License = license
   316  	c.Enabled = true
   317  	c.Labels = make(map[string]string)
   318  	c.CustomInsightsEvents.Enabled = true
   319  	c.TransactionEvents.Enabled = true
   320  	c.TransactionEvents.Attributes.Enabled = true
   321  	c.TransactionEvents.MaxSamplesStored = internal.MaxTxnEvents
   322  	c.HighSecurity = false
   323  	c.ErrorCollector.Enabled = true
   324  	c.ErrorCollector.CaptureEvents = true
   325  	c.ErrorCollector.IgnoreStatusCodes = []int{
   326  		// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
   327  		0,                   // gRPC OK
   328  		5,                   // gRPC NOT_FOUND
   329  		http.StatusNotFound, // 404
   330  	}
   331  	c.ErrorCollector.Attributes.Enabled = true
   332  	c.Utilization.DetectAWS = true
   333  	c.Utilization.DetectAzure = true
   334  	c.Utilization.DetectPCF = true
   335  	c.Utilization.DetectGCP = true
   336  	c.Utilization.DetectDocker = true
   337  	c.Utilization.DetectKubernetes = true
   338  	c.Attributes.Enabled = true
   339  	c.RuntimeSampler.Enabled = true
   340  
   341  	c.TransactionTracer.Enabled = true
   342  	c.TransactionTracer.Threshold.IsApdexFailing = true
   343  	c.TransactionTracer.Threshold.Duration = 500 * time.Millisecond
   344  	c.TransactionTracer.SegmentThreshold = 2 * time.Millisecond
   345  	c.TransactionTracer.StackTraceThreshold = 500 * time.Millisecond
   346  	c.TransactionTracer.Attributes.Enabled = true
   347  	c.TransactionTracer.Segments.Attributes.Enabled = true
   348  
   349  	c.BrowserMonitoring.Enabled = true
   350  	// browser monitoring attributes are disabled by default
   351  	c.BrowserMonitoring.Attributes.Enabled = false
   352  
   353  	c.CrossApplicationTracer.Enabled = true
   354  	c.DistributedTracer.Enabled = false
   355  	c.SpanEvents.Enabled = true
   356  	c.SpanEvents.Attributes.Enabled = true
   357  
   358  	c.DatastoreTracer.InstanceReporting.Enabled = true
   359  	c.DatastoreTracer.DatabaseNameReporting.Enabled = true
   360  	c.DatastoreTracer.QueryParameters.Enabled = true
   361  	c.DatastoreTracer.SlowQuery.Enabled = true
   362  	c.DatastoreTracer.SlowQuery.Threshold = 10 * time.Millisecond
   363  
   364  	c.ServerlessMode.ApdexThreshold = 500 * time.Millisecond
   365  	c.ServerlessMode.Enabled = false
   366  
   367  	return c
   368  }
   369  
   370  const (
   371  	licenseLength = 40
   372  	appNameLimit  = 3
   373  )
   374  
   375  // The following errors will be returned if your Config fails to validate.
   376  var (
   377  	errLicenseLen                       = fmt.Errorf("license length is not %d", licenseLength)
   378  	errAppNameMissing                   = errors.New("string AppName required")
   379  	errAppNameLimit                     = fmt.Errorf("max of %d rollup application names", appNameLimit)
   380  	errHighSecurityWithSecurityPolicies = errors.New("SecurityPoliciesToken and HighSecurity are incompatible; please ensure HighSecurity is set to false if SecurityPoliciesToken is a non-empty string and a security policy has been set for your account")
   381  )
   382  
   383  // Validate checks the config for improper fields.  If the config is invalid,
   384  // newrelic.NewApplication returns an error.
   385  func (c Config) Validate() error {
   386  	if c.Enabled && !c.ServerlessMode.Enabled {
   387  		if len(c.License) != licenseLength {
   388  			return errLicenseLen
   389  		}
   390  	} else {
   391  		// The License may be empty when the agent is not enabled.
   392  		if len(c.License) != licenseLength && len(c.License) != 0 {
   393  			return errLicenseLen
   394  		}
   395  	}
   396  	if "" == c.AppName && c.Enabled && !c.ServerlessMode.Enabled {
   397  		return errAppNameMissing
   398  	}
   399  	if c.HighSecurity && "" != c.SecurityPoliciesToken {
   400  		return errHighSecurityWithSecurityPolicies
   401  	}
   402  	if strings.Count(c.AppName, ";") >= appNameLimit {
   403  		return errAppNameLimit
   404  	}
   405  	return nil
   406  }
   407  
   408  // MaxTxnEvents returns the configured maximum number of Transaction Events if it has been configured
   409  // and is less than the default maximum; otherwise it returns the default max.
   410  func (c Config) MaxTxnEvents() int {
   411  	configured := c.TransactionEvents.MaxSamplesStored
   412  	if configured < 0 || configured > internal.MaxTxnEvents {
   413  		return internal.MaxTxnEvents
   414  	}
   415  	return configured
   416  }