diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9780de023..f7972bb14 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,14 +15,12 @@ jobs: matrix: include: # Core Tests on 3 most recent major Go versions - - go-version: 1.20.14 + - go-version: 1.21.13 dirs: v3/newrelic,v3/internal,v3/examples - - go-version: 1.21 + - go-version: 1.22.7 dirs: v3/newrelic,v3/internal,v3/examples - go-version: latest dirs: v3/newrelic,v3/internal,v3/examples - - go-version: 1.23rc2 - dirs: v3/newrelic,v3/internal,v3/examples # Integration Tests on highest Supported Go Version - dirs: v3/integrations/nramqp @@ -109,9 +107,9 @@ jobs: matrix: include: # Core Tests on 3 most recent major Go versions - - go-version: 1.20.14 + - go-version: 1.21.13 dirs: v3/newrelic,v3/internal,v3/examples - - go-version: 1.21 + - go-version: 1.22.7 dirs: v3/newrelic,v3/internal,v3/examples - go-version: latest dirs: v3/newrelic,v3/internal,v3/examples diff --git a/CHANGELOG.md b/CHANGELOG.md index 8920e6e0a..1acd31dd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +## 3.35.0 +### Added + - Enhanced security features (adds support for secure cookie even reporting) + - Enables sharing of response headers with the csec-security-agent. + - Now uses `error.Error()` value for log attributes + - Thanks to @ejsolberg for the [PR](https://github.com/newrelic/go-agent/pull/947) + - nramqp integration cloud services entity relationship changes + - Enhances url support for amqp server connections + +### Fixed + - nrawssdk-v2 integration examples of `AppendMiddlewares` corrected. + - Thanks to @Meroje for the [PR](https://github.com/newrelic/go-agent/pull/599) + - Zerolog integration correction to example program `import` statement. + - Fixes issue [#950](https://github.com/newrelic/go-agent/issues/950) + - Zerolog integration JSON parser bug caused a runtime panic in some circumstances. + - Fixes issue [#955](https://github.com/newrelic/go-agent/issues/955) + - Fixed handling of `panic(nil)`. This was made necessary by changes introducted to Go as of 1.21. + - A race condition was possible due to code level metrics accesses to a contended memory address. + - Fixes issue [#949](https://github.com/newrelic/go-agent/issues/949) + - Fixes issue [#957](https://github.com/newrelic/go-agent/issues/957) + - Integer size issues flagged when converting unsigned to signed values. + - Workflow corrections for CI processes in github. + - Fixes issue [#946](https://github.com/newrelic/go-agent/issues/946) + - Updated to use latest grpc and protobuf versions. + - Fixes memory stat collection for `GOOS=js`. + - Thanks @hslatman for the [PR](https://github.com/newrelic/go-agent/pull/967) + +### Support statement +We use the latest version of the Go language. At minimum, you should be using no version of Go older than what is supported by the Go team themselves. +See the [Go agent EOL Policy](/docs/apm/agents/go-agent/get-started/go-agent-eol-policy) for details about supported versions of the Go agent and third-party components. + ## 3.34.0 ### Added - logcontext-v2/nrlogrus can now collect user attributes diff --git a/v3/go.mod b/v3/go.mod index 50c4379ff..3a673a907 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -1,13 +1,15 @@ module github.com/newrelic/go-agent/v3 -go 1.20 +go 1.21 require ( - google.golang.org/protobuf v1.5.3 - google.golang.org/grpc v1.56.3 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 ) retract v3.22.0 // release process error corrected in v3.22.1 retract v3.25.0 // release process error corrected in v3.25.1 + +retract v3.34.0 // this release erronously referred to and invalid protobuf dependency diff --git a/v3/integrations/logcontext-v2/logWriter/go.mod b/v3/integrations/logcontext-v2/logWriter/go.mod index cadf5f5cc..23918979c 100644 --- a/v3/integrations/logcontext-v2/logWriter/go.mod +++ b/v3/integrations/logcontext-v2/logWriter/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 ) diff --git a/v3/integrations/logcontext-v2/nrlogrus/go.mod b/v3/integrations/logcontext-v2/nrlogrus/go.mod index c31af8d84..2a3725f4a 100644 --- a/v3/integrations/logcontext-v2/nrlogrus/go.mod +++ b/v3/integrations/logcontext-v2/nrlogrus/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrlogrus -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/sirupsen/logrus v1.8.1 ) diff --git a/v3/integrations/logcontext-v2/nrslog/go.mod b/v3/integrations/logcontext-v2/nrslog/go.mod index 763031b83..9469f90b7 100644 --- a/v3/integrations/logcontext-v2/nrslog/go.mod +++ b/v3/integrations/logcontext-v2/nrslog/go.mod @@ -1,8 +1,8 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog -go 1.20 +go 1.21 -require github.com/newrelic/go-agent/v3 v3.33.1 +require github.com/newrelic/go-agent/v3 v3.35.0 replace github.com/newrelic/go-agent/v3 => ../../.. diff --git a/v3/integrations/logcontext-v2/nrwriter/go.mod b/v3/integrations/logcontext-v2/nrwriter/go.mod index ed2a0e9c2..dba650407 100644 --- a/v3/integrations/logcontext-v2/nrwriter/go.mod +++ b/v3/integrations/logcontext-v2/nrwriter/go.mod @@ -1,8 +1,8 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter -go 1.20 +go 1.21 -require github.com/newrelic/go-agent/v3 v3.33.1 +require github.com/newrelic/go-agent/v3 v3.35.0 replace github.com/newrelic/go-agent/v3 => ../../.. diff --git a/v3/integrations/logcontext-v2/nrzap/go.mod b/v3/integrations/logcontext-v2/nrzap/go.mod index a813c150e..8d59be20c 100644 --- a/v3/integrations/logcontext-v2/nrzap/go.mod +++ b/v3/integrations/logcontext-v2/nrzap/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzap -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 go.uber.org/zap v1.24.0 ) diff --git a/v3/integrations/logcontext-v2/nrzerolog/go.mod b/v3/integrations/logcontext-v2/nrzerolog/go.mod index fb4593a92..9f54d885d 100644 --- a/v3/integrations/logcontext-v2/nrzerolog/go.mod +++ b/v3/integrations/logcontext-v2/nrzerolog/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzerolog -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/rs/zerolog v1.26.1 ) diff --git a/v3/integrations/logcontext-v2/zerologWriter/go.mod b/v3/integrations/logcontext-v2/zerologWriter/go.mod index 0087200af..6cd22edfa 100644 --- a/v3/integrations/logcontext-v2/zerologWriter/go.mod +++ b/v3/integrations/logcontext-v2/zerologWriter/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/zerologWriter -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 github.com/rs/zerolog v1.27.0 ) diff --git a/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer.go b/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer.go index 7d94ed141..beae3e551 100644 --- a/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer.go +++ b/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer.go @@ -1,6 +1,7 @@ package zerologWriter import ( + "bytes" "context" "io" "strings" @@ -55,15 +56,23 @@ func parseJSONLogData(log []byte) newrelic.LogData { data.Message = string(log) data.Timestamp = time.Now().UnixMilli() - for i := 0; i < len(log)-1; { + i := skipPastSpaces(log, 0) + if i < 0 || i >= len(log) || log[i] != '{' { + return data + } + i++ + for i < len(log)-1 { // get key; always a string field key, valStart := getKey(log, i) + if valStart < 0 { + return data + } var next int // NOTE: depending on the key, the type of field the value is can differ switch key { case zerolog.LevelFieldName: - data.Severity, next = getStringValue(log, valStart+1) + data.Severity, next = getStringValue(log, valStart) case zerolog.ErrorStackFieldName: _, next = getStackTrace(log, valStart) default: @@ -72,7 +81,7 @@ func parseJSONLogData(log []byte) newrelic.LogData { } // TODO: once we update the logging spec to support custom attributes, capture these if isStringValue(log, valStart) { - _, next = getStringValue(log, valStart+1) + _, next = getStringValue(log, valStart) } else if isNumberValue(log, valStart) { _, next = getNumberValue(log, valStart) } else { @@ -90,54 +99,131 @@ func parseJSONLogData(log []byte) newrelic.LogData { } func isStringValue(p []byte, indx int) bool { + if indx = skipPastSpaces(p, indx); indx < 0 { + return false + } return p[indx] == '"' } func isNumberValue(p []byte, indx int) bool { - return unicode.IsDigit(rune(p[indx])) + if indx = skipPastSpaces(p, indx); indx < 0 { + return false + } + // unicode.IsDigit isn't sufficient here because JSON numbers can start with a sign too + return unicode.IsDigit(rune(p[indx])) || p[indx] == '-' } // zerolog keys are always JSON strings func getKey(p []byte, indx int) (string, int) { value := strings.Builder{} - i := indx - - // find start of string field - for ; i < len(p); i++ { - if p[i] == '"' { - i += 1 - break - } + i := skipPastSpaces(p, indx) + if i < 0 || i >= len(p) || p[i] != '"' { + return "", -1 } // parse value of string field - for ; i < len(p); i++ { - if p[i] == '"' && i+1 < len(p) && p[i+1] == ':' { - return value.String(), i + 2 + literalNext := false + for i++; i < len(p); i++ { + if literalNext { + value.WriteByte(p[i]) + literalNext = false + continue + } + + if p[i] == '\\' { + value.WriteByte(p[i]) + literalNext = true + continue + } + + if p[i] == '"' { + // found end of key. Now look for the colon separator + for i++; i < len(p); i++ { + if p[i] == ':' && i+1 < len(p) { + return value.String(), i + 1 + } + if p[i] != ' ' && p[i] != '\t' { + break + } + } + // Oh oh. if we got here, there wasn't a colon, or there wasn't a value after it, or + // something showed up between the end of the key and the colon that wasn't a space. + // In any of those cases, we didn't find the key of a key/value pair. + return "", -1 } else { value.WriteByte(p[i]) } } - return "", -1 } +/* func isEOL(p []byte, i int) bool { - return p[i] == '}' && i+2 == len(p) + for ; i < len(p); i++ { + if p[i] == ' ' || p[i] == '\t' { + continue + } + if p[i] == '}' { + // nothing but space to the end from here? + for i++; i < len(p); i++ { + if p[i] != ' ' && p[i] != '\t' && p[i] != '\r' && p[i] != '\n' { + return false // nope, that wasn't the end of the string + } + } + return true + } + } + return false +} +*/ + +func skipPastSpaces(p []byte, i int) int { + for ; i < len(p); i++ { + if p[i] != ' ' && p[i] != '\t' && p[i] != '\r' && p[i] != '\n' { + return i + } + } + return -1 } func getStringValue(p []byte, indx int) (string, int) { value := strings.Builder{} + // skip to start of string + i := skipPastSpaces(p, indx) + if i < 0 || i >= len(p) || p[i] != '"' { + return "", -1 + } + // parse value of string field - for i := indx; i < len(p); i++ { - if p[i] == '"' && i+1 < len(p) { - if p[i+1] == ',' && i+2 < len(p) && p[i+2] == '"' { - return value.String(), i + 2 - } else if isEOL(p, i+1) { + literalNext := false + for i++; i < len(p); i++ { + if literalNext { + value.WriteByte(p[i]) + literalNext = false + continue + } + + if p[i] == '\\' { + value.WriteByte(p[i]) + literalNext = true + continue + } + + if p[i] == '"' { + // end of string. search past the comma so we can find the following key (if any) later. + if i = skipPastSpaces(p, i+1); i < 0 || i >= len(p) { + return value.String(), -1 + } + if p[i] == ',' { + if i+1 < len(p) { + return value.String(), i + 1 + } return value.String(), -1 } + return value.String(), -1 } + value.WriteByte(p[i]) } @@ -148,35 +234,43 @@ func getNumberValue(p []byte, indx int) (string, int) { value := strings.Builder{} // parse value of string field - for i := indx; i < len(p); i++ { - if p[i] == ',' && i+1 < len(p) && p[i+1] == '"' { - return value.String(), i + 1 - } else if isEOL(p, i) { - return value.String(), -1 - } else { - value.WriteByte(p[i]) - } + i := skipPastSpaces(p, indx) + if i < 0 { + return "", -1 + } + // JSON numeric values contain digits, '.', '-', 'e' + for ; i < len(p) && bytes.IndexByte([]byte("0123456789-+eE."), p[i]) >= 0; i++ { + value.WriteByte(p[i]) } - return "", -1 + i = skipPastSpaces(p, i) + if i > 0 && i+1 < len(p) && p[i] == ',' { + return value.String(), i + 1 + } + return value.String(), -1 } func getStackTrace(p []byte, indx int) (string, int) { value := strings.Builder{} - // parse value of string field - for i := indx; i < len(p); i++ { + i := skipPastSpaces(p, indx) + if i < 0 || i >= len(p) || p[i] != '[' { + return "", -1 + } + // the stack trace is everything from '[' to the next ']'. + // TODO: this is a little naïve and we may need to consider parsing + // the data inbetween more carefully. To date, we haven't seen a case + // where that is necessary, and prefer not to impact performance of the + // system by doing the extra processing, but we can revisit that later + // if necessary. + for ; i < len(p); i++ { if p[i] == ']' { value.WriteByte(p[i]) - - if i+1 < len(p) { - if isEOL(p, i+1) { - return value.String(), -1 - } - if p[i+1] == ',' && i+2 < len(p) && p[i+2] == '"' { - return value.String(), i + 2 - } + i = skipPastSpaces(p, i) + if i > 0 && i+1 < len(p) && p[i] == ',' { + return value.String(), i + 1 } + return value.String(), -1 } else { value.WriteByte(p[i]) } diff --git a/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer_test.go b/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer_test.go index ab0a2f974..cc831185c 100644 --- a/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer_test.go +++ b/v3/integrations/logcontext-v2/zerologWriter/zerolog-writer_test.go @@ -116,13 +116,31 @@ func TestParseLogData(t *testing.T) { }, }, { - `{"Scale":"833 cents","Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere","level":"debug"}` + "\n", + `{"Scale":"833 cents" , "Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere","level":"debug"}` + "\n", "level", newrelic.LogData{ - Message: `{"Scale":"833 cents","Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere","level":"debug"}` + "\n", + Message: `{"Scale":"833 cents" , "Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere","level":"debug"}` + "\n", Severity: "debug", }, }, + /* regression test case from issue 955 by MarioCarrion */ + { + `{"level":"info","message":"\"value\","}` + "\n", + "level", + newrelic.LogData{ + Message: `{"level":"info","message":"\"value\","}` + "\n", + Severity: "info", + }, + }, + { + `{"level":"info","message":","}` + "\n", + "level", + newrelic.LogData{ + Message: `{"level":"info","message":","}` + "\n", + Severity: "info", + }, + }, + /* end of issue 955 test case */ } for _, test := range tests { if test.levelKey != "" { diff --git a/v3/integrations/logcontext/nrlogrusplugin/go.mod b/v3/integrations/logcontext/nrlogrusplugin/go.mod index 15529e817..795ead899 100644 --- a/v3/integrations/logcontext/nrlogrusplugin/go.mod +++ b/v3/integrations/logcontext/nrlogrusplugin/go.mod @@ -2,10 +2,10 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin // As of Dec 2019, the logrus go.mod file uses 1.13: // https://github.com/sirupsen/logrus/blob/master/go.mod -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 // v1.4.0 is required for for the log.WithContext. github.com/sirupsen/logrus v1.4.0 ) diff --git a/v3/integrations/nramqp/examples/consumer/main.go b/v3/integrations/nramqp/examples/consumer/main.go index 5cfc92ec4..ae44c4b85 100644 --- a/v3/integrations/nramqp/examples/consumer/main.go +++ b/v3/integrations/nramqp/examples/consumer/main.go @@ -32,7 +32,8 @@ func main() { nrApp.WaitForConnection(time.Second * 5) - conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") + amqpURL := "amqp://guest:guest@localhost:5672/" + conn, err := amqp.Dial(amqpURL) failOnError(err, "Failed to connect to RabbitMQ") defer conn.Close() diff --git a/v3/integrations/nramqp/examples/publisher/main.go b/v3/integrations/nramqp/examples/publisher/main.go index 445947a08..295071b82 100644 --- a/v3/integrations/nramqp/examples/publisher/main.go +++ b/v3/integrations/nramqp/examples/publisher/main.go @@ -40,13 +40,15 @@ type amqpServer struct { ch *amqp.Channel exchange string routingKey string + url string } -func NewServer(channel *amqp.Channel, exchangeName, routingKeyName string) *amqpServer { +func NewServer(channel *amqp.Channel, exchangeName, routingKeyName string, url string) *amqpServer { return &amqpServer{ channel, exchangeName, routingKeyName, + url, } } @@ -65,6 +67,7 @@ func (serv *amqpServer) publishPlainTxtMessage(w http.ResponseWriter, r *http.Re ctx, serv.exchange, // exchange serv.routingKey, // routing key + serv.url, // url false, // mandatory false, // immediate amqp.Publishing{ @@ -94,7 +97,8 @@ func main() { nrApp.WaitForConnection(time.Second * 5) - conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") + amqpURL := "amqp://guest:guest@localhost:5672/" + conn, err := amqp.Dial(amqpURL) failOnError(err, "Failed to connect to RabbitMQ") defer conn.Close() @@ -112,7 +116,7 @@ func main() { ) failOnError(err, "Failed to declare a queue") - server := NewServer(ch, "", q.Name) + server := NewServer(ch, "", q.Name, amqpURL) http.HandleFunc(newrelic.WrapHandleFunc(nrApp, "/", server.index)) http.HandleFunc(newrelic.WrapHandleFunc(nrApp, "/message", server.publishPlainTxtMessage)) diff --git a/v3/integrations/nramqp/go.mod b/v3/integrations/nramqp/go.mod index 3dcafdde2..8975d5a50 100644 --- a/v3/integrations/nramqp/go.mod +++ b/v3/integrations/nramqp/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/nramqp -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/rabbitmq/amqp091-go v1.9.0 ) replace github.com/newrelic/go-agent/v3 => ../.. diff --git a/v3/integrations/nramqp/nramqp.go b/v3/integrations/nramqp/nramqp.go index 2be8e7634..8e2094dbe 100644 --- a/v3/integrations/nramqp/nramqp.go +++ b/v3/integrations/nramqp/nramqp.go @@ -2,6 +2,7 @@ package nramqp import ( "context" + "strings" amqp "github.com/rabbitmq/amqp091-go" @@ -16,7 +17,7 @@ const ( func init() { internal.TrackUsage("integration", "messagebroker", "nramqp") } -func creatProducerSegment(exchange, key string) *newrelic.MessageProducerSegment { +func createProducerSegment(exchange, key string) *newrelic.MessageProducerSegment { s := newrelic.MessageProducerSegment{ Library: RabbitMQLibrary, DestinationName: "Default", @@ -33,13 +34,34 @@ func creatProducerSegment(exchange, key string) *newrelic.MessageProducerSegment return &s } +func GetHostAndPortFromURL(url string) (string, string) { + // url is of format amqp://user:password@host:port or amqp://host:port + var hostPortPart string + + // extract the part after "@" symbol, if present + if parts := strings.Split(url, "@"); len(parts) == 2 { + hostPortPart = parts[1] + } else { + // assume the whole url after "amqp://" is the host:port part + hostPortPart = strings.TrimPrefix(url, "amqp://") + } + + // split the host:port part + strippedURL := strings.Split(hostPortPart, ":") + if len(strippedURL) != 2 { + return "", "" + } + return strippedURL[0], strippedURL[1] +} + // PublishedWithContext looks for a newrelic transaction in the context object, and if found, creates a message producer segment. // It will also inject distributed tracing headers into the message. -func PublishWithContext(ch *amqp.Channel, ctx context.Context, exchange, key string, mandatory, immediate bool, msg amqp.Publishing) error { +func PublishWithContext(ch *amqp.Channel, ctx context.Context, exchange, key, url string, mandatory, immediate bool, msg amqp.Publishing) error { + host, port := GetHostAndPortFromURL(url) txn := newrelic.FromContext(ctx) if txn != nil { // generate message broker segment - s := creatProducerSegment(exchange, key) + s := createProducerSegment(exchange, key) // capture telemetry for AMQP producer if msg.Headers != nil && len(msg.Headers) > 0 { @@ -49,15 +71,18 @@ func PublishWithContext(ch *amqp.Channel, ctx context.Context, exchange, key str } integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageHeaders, hdrStr) } + s.StartTime = txn.StartSegmentNow() + // inject DT headers into headers object + msg.Headers = injectDtHeaders(txn, msg.Headers) + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeSpanKind, "producer") + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeServerAddress, host) + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeServerPort, port) + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageDestinationName, exchange) integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageRoutingKey, key) integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageCorrelationID, msg.CorrelationId) integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageReplyTo, msg.ReplyTo) - // inject DT headers into headers object - msg.Headers = injectDtHeaders(txn, msg.Headers) - - s.StartTime = txn.StartSegmentNow() err := ch.PublishWithContext(ctx, exchange, key, mandatory, immediate, msg) s.End() return err @@ -91,8 +116,10 @@ func Consume(app *newrelic.Application, ch *amqp.Channel, queue, consumer string integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessageHeaders, hdrStr, nil) } } - + integrationsupport.AddAgentAttribute(txn, newrelic.AttributeSpanKind, "consumer", nil) integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessageQueueName, queue, nil) + integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessageDestinationName, queue, nil) + integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessagingDestinationPublishName, delivery.Exchange, nil) integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessageRoutingKey, delivery.RoutingKey, nil) integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessageCorrelationID, delivery.CorrelationId, nil) integrationsupport.AddAgentAttribute(txn, newrelic.AttributeMessageReplyTo, delivery.ReplyTo, nil) diff --git a/v3/integrations/nramqp/nramqp_test.go b/v3/integrations/nramqp/nramqp_test.go index 3db9e4ce9..213a4cc5c 100644 --- a/v3/integrations/nramqp/nramqp_test.go +++ b/v3/integrations/nramqp/nramqp_test.go @@ -15,7 +15,7 @@ func BenchmarkCreateProducerSegment(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - creatProducerSegment("exchange", "key") + createProducerSegment("exchange", "key") } } @@ -66,7 +66,7 @@ func TestCreateProducerSegment(t *testing.T) { } for _, test := range tests { - s := creatProducerSegment(test.exchange, test.key) + s := createProducerSegment(test.exchange, test.key) if s.DestinationName != test.expect.DestinationName { t.Errorf("expected destination name %s, got %s", test.expect.DestinationName, s.DestinationName) } @@ -76,3 +76,55 @@ func TestCreateProducerSegment(t *testing.T) { } } + +func TestHostAndPortParsing(t *testing.T) { + app := createTestApp() + txn := app.StartTransaction("test") + defer txn.End() + + type testObject struct { + url string + expectHost string + expectPort string + } + + tests := []testObject{ + { + "amqp://user:password@host:port", + "host", + "port", + }, + { + "amqp://host:port", + "host", + "port", + }, + { + "aaa://host:port", + "", + "", + }, + + { + "amqp://user:password@host", + "", + "", + }, + { + "amqp://user:password@host:port:extra", + "", + "", + }, + } + + for _, test := range tests { + host, port := GetHostAndPortFromURL(test.url) + if host != test.expectHost { + t.Errorf("expected host %s, got %s", test.expectHost, host) + } + if port != test.expectPort { + t.Errorf("expected port %s, got %s", test.expectPort, port) + } + } + +} diff --git a/v3/integrations/nrawsbedrock/go.mod b/v3/integrations/nrawsbedrock/go.mod index 72edb5c9e..95fb67d97 100644 --- a/v3/integrations/nrawsbedrock/go.mod +++ b/v3/integrations/nrawsbedrock/go.mod @@ -1,6 +1,6 @@ module github.com/newrelic/go-agent/v3/integrations/nrawsbedrock -go 1.20 +go 1.21 require ( github.com/aws/aws-sdk-go-v2 v1.26.0 @@ -8,7 +8,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/bedrock v1.7.3 github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.7.1 github.com/google/uuid v1.3.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrawssdk-v1/go.mod b/v3/integrations/nrawssdk-v1/go.mod index b41c39600..b6b2b12f4 100644 --- a/v3/integrations/nrawssdk-v1/go.mod +++ b/v3/integrations/nrawssdk-v1/go.mod @@ -3,12 +3,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrawssdk-v1 // As of Dec 2019, aws-sdk-go's go.mod does not specify a Go version. 1.6 is // the earliest version of Go tested by aws-sdk-go's CI: // https://github.com/aws/aws-sdk-go/blob/master/.travis.yml -go 1.20 +go 1.21 require ( // v1.15.0 is the first aws-sdk-go version with module support. github.com/aws/aws-sdk-go v1.34.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrawssdk-v2/example/main.go b/v3/integrations/nrawssdk-v2/example/main.go index 3f740302e..204cad03b 100644 --- a/v3/integrations/nrawssdk-v2/example/main.go +++ b/v3/integrations/nrawssdk-v2/example/main.go @@ -10,7 +10,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" - nraws "github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2" + "github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2" "github.com/newrelic/go-agent/v3/newrelic" ) @@ -39,14 +39,15 @@ func main() { txn := app.StartTransaction("My sample transaction") ctx := context.Background() - awsConfig, err := config.LoadDefaultConfig(ctx) + awsConfig, err := config.LoadDefaultConfig(ctx, func(awsConfig *config.LoadOptions) error { + // Instrument all new AWS clients with New Relic + nrawssdk.AppendMiddlewares(&awsConfig.APIOptions, nil) + return nil + }) if err != nil { log.Fatal(err) } - // Instrument all new AWS clients with New Relic - nraws.AppendMiddlewares(&awsConfig.APIOptions, nil) - s3Client := s3.NewFromConfig(awsConfig) output, err := s3Client.ListBuckets(ctx, nil) if err != nil { diff --git a/v3/integrations/nrawssdk-v2/go.mod b/v3/integrations/nrawssdk-v2/go.mod index 2a81df60a..81be27b79 100644 --- a/v3/integrations/nrawssdk-v2/go.mod +++ b/v3/integrations/nrawssdk-v2/go.mod @@ -2,16 +2,19 @@ module github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2 // As of May 2021, the aws-sdk-go-v2 go.mod file uses 1.15: // https://github.com/aws/aws-sdk-go-v2/blob/master/go.mod -go 1.20 +go 1.21 + +toolchain go1.21.0 require ( - github.com/aws/aws-sdk-go-v2 v1.16.15 - github.com/aws/aws-sdk-go-v2/config v1.17.6 - github.com/aws/aws-sdk-go-v2/service/dynamodb v1.17.0 - github.com/aws/aws-sdk-go-v2/service/lambda v1.24.5 - github.com/aws/aws-sdk-go-v2/service/s3 v1.27.10 - github.com/aws/smithy-go v1.13.3 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/aws/aws-sdk-go-v2 v1.30.4 + github.com/aws/aws-sdk-go-v2/config v1.27.31 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.6 + github.com/aws/aws-sdk-go-v2/service/lambda v1.58.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.61.0 + github.com/aws/aws-sdk-go-v2/service/sqs v1.34.6 + github.com/aws/smithy-go v1.20.4 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrawssdk-v2/nrawssdk.go b/v3/integrations/nrawssdk-v2/nrawssdk.go index 8ff3a8ab6..21ae60461 100644 --- a/v3/integrations/nrawssdk-v2/nrawssdk.go +++ b/v3/integrations/nrawssdk-v2/nrawssdk.go @@ -28,9 +28,14 @@ package nrawssdk import ( "context" + "net/url" "strconv" + "strings" + "github.com/aws/aws-sdk-go-v2/aws" awsmiddle "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/service/sqs" + "github.com/aws/smithy-go/middleware" smithymiddle "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "github.com/newrelic/go-agent/v3/internal/integrationsupport" @@ -41,6 +46,11 @@ type nrMiddleware struct { txn *newrelic.Transaction } +// Context key for SQS service queue +type contextKey string + +const queueURLKey contextKey = "QueueURL" + type endable interface{ End() } // See https://aws.github.io/aws-sdk-go-v2/docs/middleware/ for a description of @@ -88,6 +98,24 @@ func (m nrMiddleware) deserializeMiddleware(stack *smithymiddle.Stack) error { response, ok := out.RawResponse.(*smithyhttp.Response) if ok { + if serviceName == "sqs" || serviceName == "SQS" { + if queueURL, ok := ctx.Value(queueURLKey).(string); ok { + parsedURL, err := url.Parse(queueURL) + if err == nil { + // Example URL: https://sqs.{region}.amazonaws.com/{account.id}/{queue.name} + pathParts := strings.Split(parsedURL.Path, "/") + if len(pathParts) >= 3 { + accountID := pathParts[1] + queueName := pathParts[2] + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeCloudAccountID, accountID) + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeCloudRegion, region) + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageSystem, "aws_sqs") + integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeMessageDestinationName, queueName) + } + } + + } + } // Set additional span attributes integrationsupport.AddAgentSpanAttribute(txn, newrelic.AttributeResponseCode, strconv.Itoa(response.StatusCode)) @@ -107,6 +135,51 @@ func (m nrMiddleware) deserializeMiddleware(stack *smithymiddle.Stack) error { smithymiddle.Before) } +func (m nrMiddleware) serializeMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(middleware.InitializeMiddlewareFunc("NRSerializeMiddleware", func( + ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error) { + + serviceName := awsmiddle.GetServiceID(ctx) + if serviceName == "sqs" || serviceName == "SQS" { + QueueURL := "" + switch params := in.Parameters.(type) { + case *sqs.SendMessageInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.DeleteQueueInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.ReceiveMessageInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.DeleteMessageInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.ChangeMessageVisibilityInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.ChangeMessageVisibilityBatchInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.DeleteMessageBatchInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.SendMessageBatchInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.PurgeQueueInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.GetQueueAttributesInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.SetQueueAttributesInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.TagQueueInput: + QueueURL = aws.ToString(params.QueueUrl) + case *sqs.UntagQueueInput: + QueueURL = aws.ToString(params.QueueUrl) + default: + QueueURL = "" + } + // Store the QueueURL in the context + ctx = context.WithValue(ctx, queueURLKey, QueueURL) + } + return next.HandleInitialize(ctx, in) + }), middleware.After) +} + // AppendMiddlewares inserts New Relic middleware in the given `apiOptions` for // the AWS SDK V2 for Go. It must be called only once per AWS configuration. // @@ -120,25 +193,53 @@ func (m nrMiddleware) deserializeMiddleware(stack *smithymiddle.Stack) error { // To see segments and spans for all AWS invocations, call AppendMiddlewares // with the AWS Config `apiOptions` and provide nil for `txn`. For example: // -// awsConfig, err := config.LoadDefaultConfig(ctx) -// if err != nil { -// log.Fatal(err) -// } -// nraws.AppendMiddlewares(&awsConfig.APIOptions, nil) +// awsConfig, err := config.LoadDefaultConfig(ctx, func(o *config.LoadOptions) error { +// // Instrument all new AWS clients with New Relic +// nrawssdk.AppendMiddlewares(&o.APIOptions, nil) +// return nil +// }) +// if err != nil { +// log.Fatal(err) +// } // -// If do not want the transaction to be retrived from the context, you can +// If do not want the transaction to be retrieved from the context, you can // explicitly set `txn`. For example: // -// awsConfig, err := config.LoadDefaultConfig(ctx) -// if err != nil { -// log.Fatal(err) -// } +// txn := loadNewRelicTransaction() +// awsConfig, err := config.LoadDefaultConfig(ctx, func(o *config.LoadOptions) error { +// // Instrument all new AWS clients with New Relic +// nrawssdk.AppendMiddlewares(&o.APIOptions, txn) +// return nil +// }) +// if err != nil { +// log.Fatal(err) +// } +// +// The middleware can also be added later, per AWS service call using +// the `optFns` parameter. For example: +// +// awsConfig, err := config.LoadDefaultConfig(ctx) +// if err != nil { +// log.Fatal(err) +// } // -// ... +// ... // -// txn := loadNewRelicTransaction() -// nraws.AppendMiddlewares(&awsConfig.APIOptions, txn) +// s3Client := s3.NewFromConfig(awsConfig) +// +// ... +// +// txn := loadNewRelicTransaction() +// output, err := s3Client.ListBuckets(ctx, nil, func(o *s3.Options) error { +// nrawssdk.AppendMiddlewares(&o.APIOptions, txn) +// return nil +// }) +// if err != nil { +// log.Fatal(err) +// } func AppendMiddlewares(apiOptions *[]func(*smithymiddle.Stack) error, txn *newrelic.Transaction) { m := nrMiddleware{txn: txn} *apiOptions = append(*apiOptions, m.deserializeMiddleware) + *apiOptions = append(*apiOptions, m.serializeMiddleware) + } diff --git a/v3/integrations/nrawssdk-v2/nrawssdk_test.go b/v3/integrations/nrawssdk-v2/nrawssdk_test.go index 79b1f389a..0385559ec 100644 --- a/v3/integrations/nrawssdk-v2/nrawssdk_test.go +++ b/v3/integrations/nrawssdk-v2/nrawssdk_test.go @@ -17,9 +17,14 @@ import ( "github.com/aws/aws-sdk-go-v2/service/dynamodb" "github.com/aws/aws-sdk-go-v2/service/lambda" "github.com/aws/aws-sdk-go-v2/service/lambda/types" + + "github.com/aws/aws-sdk-go-v2/service/sqs" + "github.com/newrelic/go-agent/v3/internal" "github.com/newrelic/go-agent/v3/internal/integrationsupport" "github.com/newrelic/go-agent/v3/newrelic" + + sqstypes "github.com/aws/aws-sdk-go-v2/service/sqs/types" ) func testApp() integrationsupport.ExpectApp { @@ -60,15 +65,16 @@ var fakeCreds = func() interface{} { }() func newConfig(ctx context.Context, txn *newrelic.Transaction) aws.Config { - cfg, _ := config.LoadDefaultConfig(ctx) + cfg, _ := config.LoadDefaultConfig(ctx, func(o *config.LoadOptions) error { + AppendMiddlewares(&o.APIOptions, txn) + return nil + }) cfg.Credentials = fakeCreds.(aws.CredentialsProvider) cfg.Region = awsRegion cfg.HTTPClient = &http.Client{ Transport: &fakeTransport{}, } - AppendMiddlewares(&cfg.APIOptions, txn) - return cfg } @@ -139,6 +145,28 @@ var ( "http.statusCode": "200", }, } + SQSSpan = internal.WantEvent{ + Intrinsics: map[string]interface{}{ + "name": "External/sqs.us-west-2.amazonaws.com/http/POST", + "category": "http", + "parentId": internal.MatchAnything, + "component": "http", + "span.kind": "client", + "sampled": true, + }, + UserAttributes: map[string]interface{}{}, + AgentAttributes: map[string]interface{}{ + "message.destination.name": "MyQueue", + "cloud.account.id": "123456789012", + "cloud.region": "us-west-2", + "http.url": "https://sqs.us-west-2.amazonaws.com/", + "http.method": "POST", + "messaging.system": "aws_sqs", + "aws.requestId": "testing request id", + "http.statusCode": "200", + "aws.region": "us-west-2", + }, + } datastoreSpan = internal.WantEvent{ Intrinsics: map[string]interface{}{ "name": "Datastore/operation/DynamoDB/DescribeTable", @@ -257,6 +285,262 @@ func TestInstrumentRequestExternal(t *testing.T) { ) } +type sqsTestTableEntry struct { + Name string + BuildContext func(txn *newrelic.Transaction) context.Context + BuildConfig func(ctx context.Context, txn *newrelic.Transaction) aws.Config + Input interface{} +} + +func runSQSTestTable(t *testing.T, entries []*sqsTestTableEntry, testFunc func(t *testing.T, entry *sqsTestTableEntry)) { + for _, entry := range entries { + t.Run(entry.Name, func(t *testing.T) { + testFunc(t, entry) + }) + } +} + +func TestSQSMiddleware(t *testing.T) { + runSQSTestTable(t, + []*sqsTestTableEntry{ + { + Name: "DeleteQueueInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.DeleteQueueInput{QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue")}, + }, + { + Name: "ReceiveMessageInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.ReceiveMessageInput{QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue")}, + }, + { + Name: "SendMessageInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.SendMessageInput{QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), MessageBody: aws.String("Hello, world!")}, + }, + { + Name: "PurgeQueueInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.PurgeQueueInput{QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue")}, + }, + { + Name: "DeleteMessageInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.DeleteMessageInput{QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), ReceiptHandle: aws.String("receipt-handle")}, + }, + { + Name: "ChangeMessageVisibilityInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.ChangeMessageVisibilityInput{QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), ReceiptHandle: aws.String("receipt-handle"), VisibilityTimeout: 10}, + }, + + { + Name: "ChangeMessageVisibilityBatchInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.ChangeMessageVisibilityBatchInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + Entries: []sqstypes.ChangeMessageVisibilityBatchRequestEntry{ + { + Id: aws.String("id1"), + ReceiptHandle: aws.String("receipt-handle"), + VisibilityTimeout: 10, + }, + }, + }, + }, + { + Name: "DeleteMessageBatchInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.DeleteMessageBatchInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + Entries: []sqstypes.DeleteMessageBatchRequestEntry{ + { + Id: aws.String("id1"), + ReceiptHandle: aws.String("receipt-handle"), + }, + }, + }, + }, + { + Name: "SendMessageBatchInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.SendMessageBatchInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + Entries: []sqstypes.SendMessageBatchRequestEntry{ + { + Id: aws.String("id1"), + MessageBody: aws.String("Hello, world!"), + }, + }, + }, + }, + { + Name: "GetQueueAttributesInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.GetQueueAttributesInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + AttributeNames: []sqstypes.QueueAttributeName{ + "ApproximateNumberOfMessages", + }, + }, + }, + { + Name: "SetQueueAttributesInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.SetQueueAttributesInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + Attributes: map[string]string{ + "VisibilityTimeout": "10", + }, + }, + }, + { + Name: "TagQueueInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.TagQueueInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + Tags: map[string]string{ + "tag1": "value1", + }, + }, + }, + { + Name: "UntagQueueInput", + BuildContext: func(txn *newrelic.Transaction) context.Context { + return context.Background() + }, + BuildConfig: func(ctx context.Context, txn *newrelic.Transaction) aws.Config { + return newConfig(ctx, txn) + }, + Input: &sqs.UntagQueueInput{ + QueueUrl: aws.String("https://sqs.us-west-2.amazonaws.com/123456789012/MyQueue"), + TagKeys: []string{"tag1"}, + }, + }, + }, + + func(t *testing.T, entry *sqsTestTableEntry) { + app := testApp() + txn := app.StartTransaction(txnName) + ctx := entry.BuildContext(txn) + awsOp := "" + client := sqs.NewFromConfig(entry.BuildConfig(ctx, txn)) + switch input := entry.Input.(type) { + case *sqs.SendMessageInput: + client.SendMessage(ctx, input) + awsOp = "SendMessage" + case *sqs.DeleteQueueInput: + client.DeleteQueue(ctx, input) + awsOp = "DeleteQueue" + case *sqs.ReceiveMessageInput: + client.ReceiveMessage(ctx, input) + awsOp = "ReceiveMessage" + case *sqs.DeleteMessageInput: + client.DeleteMessage(ctx, input) + awsOp = "DeleteMessage" + case *sqs.ChangeMessageVisibilityInput: + client.ChangeMessageVisibility(ctx, input) + awsOp = "ChangeMessageVisibility" + case *sqs.ChangeMessageVisibilityBatchInput: + client.ChangeMessageVisibilityBatch(ctx, input) + awsOp = "ChangeMessageVisibilityBatch" + case *sqs.DeleteMessageBatchInput: + client.DeleteMessageBatch(ctx, input) + awsOp = "DeleteMessageBatch" + case *sqs.PurgeQueueInput: + client.PurgeQueue(ctx, input) + awsOp = "PurgeQueue" + case *sqs.GetQueueAttributesInput: + client.GetQueueAttributes(ctx, input) + awsOp = "GetQueueAttributes" + case *sqs.SetQueueAttributesInput: + client.SetQueueAttributes(ctx, input) + awsOp = "SetQueueAttributes" + case *sqs.TagQueueInput: + client.TagQueue(ctx, input) + awsOp = "TagQueue" + case *sqs.UntagQueueInput: + client.UntagQueue(ctx, input) + awsOp = "UntagQueue" + case *sqs.SendMessageBatchInput: + client.SendMessageBatch(ctx, input) + awsOp = "SendMessageBatch" + + default: + t.Errorf("unexpected input type: %T", input) + + } + + txn.End() + SQSSpanModified := SQSSpan + SQSSpanModified.AgentAttributes["aws.operation"] = awsOp + app.ExpectSpanEvents(t, []internal.WantEvent{ + SQSSpan, genericSpan}) + + }, + ) +} + func TestInstrumentRequestDatastore(t *testing.T) { runTestTable(t, []*testTableEntry{ diff --git a/v3/integrations/nrb3/go.mod b/v3/integrations/nrb3/go.mod index d69016b42..0a70b6f14 100644 --- a/v3/integrations/nrb3/go.mod +++ b/v3/integrations/nrb3/go.mod @@ -1,8 +1,8 @@ module github.com/newrelic/go-agent/v3/integrations/nrb3 -go 1.20 +go 1.21 -require github.com/newrelic/go-agent/v3 v3.33.1 +require github.com/newrelic/go-agent/v3 v3.35.0 replace github.com/newrelic/go-agent/v3 => ../.. diff --git a/v3/integrations/nrecho-v3/go.mod b/v3/integrations/nrecho-v3/go.mod index a8b06b82b..471de541b 100644 --- a/v3/integrations/nrecho-v3/go.mod +++ b/v3/integrations/nrecho-v3/go.mod @@ -2,13 +2,13 @@ module github.com/newrelic/go-agent/v3/integrations/nrecho-v3 // 1.7 is the earliest version of Go tested by v3.1.0: // https://github.com/labstack/echo/blob/v3.1.0/.travis.yml -go 1.20 +go 1.21 require ( // v3.1.0 is the earliest v3 version of Echo that works with modules due // to the github.com/rsc/letsencrypt import of v3.0.0. github.com/labstack/echo v3.1.0+incompatible - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrecho-v3/nrecho.go b/v3/integrations/nrecho-v3/nrecho.go index 05b8521a1..6a9b1c579 100644 --- a/v3/integrations/nrecho-v3/nrecho.go +++ b/v3/integrations/nrecho-v3/nrecho.go @@ -104,6 +104,9 @@ func Middleware(app *newrelic.Application) func(echo.HandlerFunc) echo.HandlerFu } else { txn.SetWebResponse(nil).WriteHeader(http.StatusInternalServerError) } + if newrelic.IsSecurityAgentPresent() { + newrelic.GetSecurityAgentInterface().SendEvent("RESPONSE_HEADER", c.Response().Header()) + } } return diff --git a/v3/integrations/nrecho-v4/go.mod b/v3/integrations/nrecho-v4/go.mod index a4ca9897e..0b34cc68a 100644 --- a/v3/integrations/nrecho-v4/go.mod +++ b/v3/integrations/nrecho-v4/go.mod @@ -2,11 +2,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrecho-v4 // As of Jun 2022, the echo go.mod file uses 1.17: // https://github.com/labstack/echo/blob/master/go.mod -go 1.20 +go 1.21 require ( github.com/labstack/echo/v4 v4.9.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrecho-v4/nrecho.go b/v3/integrations/nrecho-v4/nrecho.go index 130d04b29..c6fe94c98 100644 --- a/v3/integrations/nrecho-v4/nrecho.go +++ b/v3/integrations/nrecho-v4/nrecho.go @@ -127,6 +127,9 @@ func Middleware(app *newrelic.Application, opts ...ConfigOption) func(echo.Handl } else { txn.SetWebResponse(nil).WriteHeader(http.StatusInternalServerError) } + if newrelic.IsSecurityAgentPresent() { + newrelic.GetSecurityAgentInterface().SendEvent("RESPONSE_HEADER", c.Response().Header()) + } } return diff --git a/v3/integrations/nrelasticsearch-v7/go.mod b/v3/integrations/nrelasticsearch-v7/go.mod index d8466fb6c..7c665b72a 100644 --- a/v3/integrations/nrelasticsearch-v7/go.mod +++ b/v3/integrations/nrelasticsearch-v7/go.mod @@ -2,11 +2,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7 // As of Jan 2020, the v7 elasticsearch go.mod uses 1.11: // https://github.com/elastic/go-elasticsearch/blob/7.x/go.mod -go 1.20 +go 1.21 require ( github.com/elastic/go-elasticsearch/v7 v7.17.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod b/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod index a0d677eff..d48e28fba 100644 --- a/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod +++ b/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod @@ -1,9 +1,9 @@ module client-example -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrfasthttp v1.0.0 github.com/valyala/fasthttp v1.49.0 ) diff --git a/v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod b/v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod index 13278efc6..3eef72e99 100644 --- a/v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod +++ b/v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod @@ -1,9 +1,9 @@ module server-example -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrfasthttp v1.0.0 github.com/valyala/fasthttp v1.49.0 ) diff --git a/v3/integrations/nrfasthttp/go.mod b/v3/integrations/nrfasthttp/go.mod index f008cedb3..a1dd0773e 100644 --- a/v3/integrations/nrfasthttp/go.mod +++ b/v3/integrations/nrfasthttp/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/nrfasthttp -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/valyala/fasthttp v1.49.0 ) diff --git a/v3/integrations/nrfasthttp/instrumentation.go b/v3/integrations/nrfasthttp/instrumentation.go index ff07a84d9..166d171e0 100644 --- a/v3/integrations/nrfasthttp/instrumentation.go +++ b/v3/integrations/nrfasthttp/instrumentation.go @@ -76,7 +76,11 @@ func WrapHandle(app *newrelic.Application, pattern string, handler fasthttp.Requ handler(ctx) if newrelic.IsSecurityAgentPresent() { - newrelic.GetSecurityAgentInterface().SendEvent("INBOUND_WRITE", resp.Body(), resp.Header()) + header := resp.Header() + ctx.Response.Header.VisitAllCookie(func(key, value []byte) { + header.Add("Set-Cookie", string(value)) + }) + newrelic.GetSecurityAgentInterface().SendEvent("INBOUND_WRITE", resp.Body(), header) newrelic.GetSecurityAgentInterface().SendEvent("INBOUND_RESPONSE_CODE", ctx.Response.StatusCode()) } } diff --git a/v3/integrations/nrgin/go.mod b/v3/integrations/nrgin/go.mod index b2d9ee716..1d2223632 100644 --- a/v3/integrations/nrgin/go.mod +++ b/v3/integrations/nrgin/go.mod @@ -2,11 +2,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrgin // As of Dec 2019, the gin go.mod file uses 1.12: // https://github.com/gin-gonic/gin/blob/master/go.mod -go 1.20 +go 1.21 require ( github.com/gin-gonic/gin v1.9.1 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrgin/nrgin.go b/v3/integrations/nrgin/nrgin.go index 03bb266c0..f9021e215 100644 --- a/v3/integrations/nrgin/nrgin.go +++ b/v3/integrations/nrgin/nrgin.go @@ -187,5 +187,8 @@ func middleware(app *newrelic.Application, useNewNames bool) gin.HandlerFunc { c.Set(internal.GinTransactionContextKey, txn) } c.Next() + if newrelic.IsSecurityAgentPresent() { + newrelic.GetSecurityAgentInterface().SendEvent("RESPONSE_HEADER", c.Writer.Header()) + } } } diff --git a/v3/integrations/nrgorilla/go.mod b/v3/integrations/nrgorilla/go.mod index a8d1deef6..c98397fb6 100644 --- a/v3/integrations/nrgorilla/go.mod +++ b/v3/integrations/nrgorilla/go.mod @@ -2,12 +2,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrgorilla // As of Dec 2019, the gorilla/mux go.mod file uses 1.12: // https://github.com/gorilla/mux/blob/master/go.mod -go 1.20 +go 1.21 require ( // v1.7.0 is the earliest version of Gorilla using modules. github.com/gorilla/mux v1.7.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrgorilla/nrgorilla.go b/v3/integrations/nrgorilla/nrgorilla.go index 81a0e2184..bdcd56c27 100644 --- a/v3/integrations/nrgorilla/nrgorilla.go +++ b/v3/integrations/nrgorilla/nrgorilla.go @@ -123,6 +123,9 @@ func Middleware(app *newrelic.Application) mux.MiddlewareFunc { w = txn.SetWebResponse(w) r = newrelic.RequestWithTransactionContext(r, txn) next.ServeHTTP(w, r) + if newrelic.IsSecurityAgentPresent() { + newrelic.GetSecurityAgentInterface().SendEvent("RESPONSE_HEADER", w.Header()) + } }) } } diff --git a/v3/integrations/nrgraphgophers/go.mod b/v3/integrations/nrgraphgophers/go.mod index d2e57b713..8e9a24de6 100644 --- a/v3/integrations/nrgraphgophers/go.mod +++ b/v3/integrations/nrgraphgophers/go.mod @@ -2,12 +2,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrgraphgophers // As of Jan 2020, the graphql-go go.mod file uses 1.13: // https://github.com/graph-gophers/graphql-go/blob/master/go.mod -go 1.20 +go 1.21 require ( // graphql-go has no tagged releases as of Jan 2020. github.com/graph-gophers/graphql-go v1.3.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrgraphqlgo/example/go.mod b/v3/integrations/nrgraphqlgo/example/go.mod index bee83ed6a..7e09ca397 100644 --- a/v3/integrations/nrgraphqlgo/example/go.mod +++ b/v3/integrations/nrgraphqlgo/example/go.mod @@ -1,11 +1,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo/example -go 1.20 +go 1.21 require ( github.com/graphql-go/graphql v0.8.1 github.com/graphql-go/graphql-go-handler v0.2.3 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo v1.0.0 ) diff --git a/v3/integrations/nrgraphqlgo/go.mod b/v3/integrations/nrgraphqlgo/go.mod index 9f3a90a80..398e5bad1 100644 --- a/v3/integrations/nrgraphqlgo/go.mod +++ b/v3/integrations/nrgraphqlgo/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo -go 1.20 +go 1.21 require ( github.com/graphql-go/graphql v0.8.1 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrgrpc/go.mod b/v3/integrations/nrgrpc/go.mod index 2d76c537a..ad827aac2 100644 --- a/v3/integrations/nrgrpc/go.mod +++ b/v3/integrations/nrgrpc/go.mod @@ -1,12 +1,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrgrpc -go 1.20 +go 1.21 require ( // protobuf v1.3.0 is the earliest version using modules, we use v1.3.1 // because all dependencies were removed in this version. github.com/golang/protobuf v1.5.3 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrsecurityagent v1.1.0 // v1.15.0 is the earliest version of grpc using modules. google.golang.org/grpc v1.56.3 diff --git a/v3/integrations/nrhttprouter/go.mod b/v3/integrations/nrhttprouter/go.mod index 8a3ccdb75..bb18f867e 100644 --- a/v3/integrations/nrhttprouter/go.mod +++ b/v3/integrations/nrhttprouter/go.mod @@ -2,12 +2,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrhttprouter // As of Dec 2019, the httprouter go.mod file uses 1.7: // https://github.com/julienschmidt/httprouter/blob/master/go.mod -go 1.20 +go 1.21 require ( // v1.3.0 is the earliest version of httprouter using modules. github.com/julienschmidt/httprouter v1.3.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrhttprouter/nrhttprouter.go b/v3/integrations/nrhttprouter/nrhttprouter.go index 8239dae1a..5292551b3 100644 --- a/v3/integrations/nrhttprouter/nrhttprouter.go +++ b/v3/integrations/nrhttprouter/nrhttprouter.go @@ -159,4 +159,7 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { } r.Router.ServeHTTP(w, req) + if newrelic.IsSecurityAgentPresent() { + newrelic.GetSecurityAgentInterface().SendEvent("RESPONSE_HEADER", w.Header()) + } } diff --git a/v3/integrations/nrlambda/go.mod b/v3/integrations/nrlambda/go.mod index 9f12b1fac..9b43a7bea 100644 --- a/v3/integrations/nrlambda/go.mod +++ b/v3/integrations/nrlambda/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrlambda -go 1.20 +go 1.21 require ( github.com/aws/aws-lambda-go v1.41.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrlogrus/go.mod b/v3/integrations/nrlogrus/go.mod index 6ecb3fd54..39763cf75 100644 --- a/v3/integrations/nrlogrus/go.mod +++ b/v3/integrations/nrlogrus/go.mod @@ -2,10 +2,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrlogrus // As of Dec 2019, the logrus go.mod file uses 1.13: // https://github.com/sirupsen/logrus/blob/master/go.mod -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrlogrus v1.0.0 // v1.1.0 is required for the Logger.GetLevel method, and is the earliest // version of logrus using modules. diff --git a/v3/integrations/nrlogxi/go.mod b/v3/integrations/nrlogxi/go.mod index eab91404f..6cc7eb097 100644 --- a/v3/integrations/nrlogxi/go.mod +++ b/v3/integrations/nrlogxi/go.mod @@ -2,12 +2,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrlogxi // As of Dec 2019, logxi requires 1.3+: // https://github.com/mgutz/logxi#requirements -go 1.20 +go 1.21 require ( // 'v1', at commit aebf8a7d67ab, is the only logxi release. github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrlogxi/nrlogxi.go b/v3/integrations/nrlogxi/nrlogxi.go index 8f0f4bdd8..69d427ae9 100644 --- a/v3/integrations/nrlogxi/nrlogxi.go +++ b/v3/integrations/nrlogxi/nrlogxi.go @@ -8,6 +8,8 @@ package nrlogxi import ( + "math" + log "github.com/mgutz/logxi/v1" "github.com/newrelic/go-agent/v3/internal" newrelic "github.com/newrelic/go-agent/v3/newrelic" @@ -36,6 +38,11 @@ func (l *shim) DebugEnabled() bool { } func convert(c map[string]interface{}) []interface{} { + if len(c) >= math.MaxInt32/2 { + output := make([]interface{}, 0) + return output + } + output := make([]interface{}, 0, 2*len(c)) for k, v := range c { output = append(output, k, v) diff --git a/v3/integrations/nrmicro/go.mod b/v3/integrations/nrmicro/go.mod index 482f339a9..de7e5982e 100644 --- a/v3/integrations/nrmicro/go.mod +++ b/v3/integrations/nrmicro/go.mod @@ -2,14 +2,14 @@ module github.com/newrelic/go-agent/v3/integrations/nrmicro // As of Dec 2019, the go-micro go.mod file uses 1.13: // https://github.com/micro/go-micro/blob/master/go.mod -go 1.20 +go 1.21 toolchain go1.22.3 require ( github.com/golang/protobuf v1.5.4 github.com/micro/go-micro v1.8.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 google.golang.org/protobuf v1.34.1 ) diff --git a/v3/integrations/nrmongo/go.mod b/v3/integrations/nrmongo/go.mod index 10132f41f..10dcccdef 100644 --- a/v3/integrations/nrmongo/go.mod +++ b/v3/integrations/nrmongo/go.mod @@ -2,10 +2,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrmongo // As of Dec 2019, 1.10 is the mongo-driver requirement: // https://github.com/mongodb/mongo-go-driver#requirements -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 // mongo-driver does not support modules as of Nov 2019. go.mongodb.org/mongo-driver v1.10.2 ) diff --git a/v3/integrations/nrmssql/go.mod b/v3/integrations/nrmssql/go.mod index f8df4469c..21ac02623 100644 --- a/v3/integrations/nrmssql/go.mod +++ b/v3/integrations/nrmssql/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrmssql -go 1.20 +go 1.21 require ( github.com/microsoft/go-mssqldb v0.19.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrmysql/go.mod b/v3/integrations/nrmysql/go.mod index 7c41cc27e..ce742df64 100644 --- a/v3/integrations/nrmysql/go.mod +++ b/v3/integrations/nrmysql/go.mod @@ -1,13 +1,13 @@ module github.com/newrelic/go-agent/v3/integrations/nrmysql // 1.10 is the Go version in mysql's go.mod -go 1.20 +go 1.21 require ( // v1.5.0 is the first mysql version to support gomod github.com/go-sql-driver/mysql v1.6.0 // v3.3.0 includes the new location of ParseQuery - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrnats/go.mod b/v3/integrations/nrnats/go.mod index 909a95903..455d82348 100644 --- a/v3/integrations/nrnats/go.mod +++ b/v3/integrations/nrnats/go.mod @@ -2,12 +2,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrnats // As of Jun 2023, 1.19 is the earliest version of Go tested by nats: // https://github.com/nats-io/nats.go/blob/master/.travis.yml -go 1.20 +go 1.21 require ( github.com/nats-io/nats-server v1.4.1 github.com/nats-io/nats.go v1.28.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrnats/test/go.mod b/v3/integrations/nrnats/test/go.mod index 3f6ec494f..93cefa3b4 100644 --- a/v3/integrations/nrnats/test/go.mod +++ b/v3/integrations/nrnats/test/go.mod @@ -1,14 +1,14 @@ module github.com/newrelic/go-agent/v3/integrations/test // This module exists to avoid having extra nrnats module dependencies. -go 1.20 +go 1.21 replace github.com/newrelic/go-agent/v3/integrations/nrnats v1.0.0 => ../ require ( github.com/nats-io/nats-server v1.4.1 github.com/nats-io/nats.go v1.17.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrnats v1.0.0 ) diff --git a/v3/integrations/nropenai/go.mod b/v3/integrations/nropenai/go.mod index 5dd7d6899..4b640f4b7 100644 --- a/v3/integrations/nropenai/go.mod +++ b/v3/integrations/nropenai/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nropenai -go 1.20 +go 1.21 require ( github.com/google/uuid v1.6.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/pkoukk/tiktoken-go v0.1.6 github.com/sashabaranov/go-openai v1.20.2 ) diff --git a/v3/integrations/nrpgx/example/sqlx/go.mod b/v3/integrations/nrpgx/example/sqlx/go.mod index 23e247094..7310a84b2 100644 --- a/v3/integrations/nrpgx/example/sqlx/go.mod +++ b/v3/integrations/nrpgx/example/sqlx/go.mod @@ -1,10 +1,10 @@ // This sqlx example is a separate module to avoid adding sqlx dependency to the // nrpgx go.mod file. module github.com/newrelic/go-agent/v3/integrations/nrpgx/example/sqlx -go 1.20 +go 1.21 require ( github.com/jmoiron/sqlx v1.2.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrpgx v0.0.0 ) replace github.com/newrelic/go-agent/v3/integrations/nrpgx => ../../ diff --git a/v3/integrations/nrpgx/go.mod b/v3/integrations/nrpgx/go.mod index 0a493f988..a72b45d81 100644 --- a/v3/integrations/nrpgx/go.mod +++ b/v3/integrations/nrpgx/go.mod @@ -1,11 +1,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrpgx -go 1.20 +go 1.21 require ( github.com/jackc/pgx v3.6.2+incompatible github.com/jackc/pgx/v4 v4.18.2 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrpgx5/go.mod b/v3/integrations/nrpgx5/go.mod index 296c4a427..aa16f192c 100644 --- a/v3/integrations/nrpgx5/go.mod +++ b/v3/integrations/nrpgx5/go.mod @@ -1,11 +1,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrpgx5 -go 1.20 +go 1.21 require ( github.com/egon12/pgsnap v0.0.0-20221022154027-2847f0124ed8 github.com/jackc/pgx/v5 v5.5.4 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/stretchr/testify v1.8.1 ) diff --git a/v3/integrations/nrpkgerrors/go.mod b/v3/integrations/nrpkgerrors/go.mod index bbfa68b6f..0939765ca 100644 --- a/v3/integrations/nrpkgerrors/go.mod +++ b/v3/integrations/nrpkgerrors/go.mod @@ -2,10 +2,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrpkgerrors // As of Dec 2019, 1.11 is the earliest version of Go tested by pkg/errors: // https://github.com/pkg/errors/blob/master/.travis.yml -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 // v0.8.0 was the last release in 2016, and when // major development on pkg/errors stopped. github.com/pkg/errors v0.8.0 diff --git a/v3/integrations/nrpq/example/sqlx/go.mod b/v3/integrations/nrpq/example/sqlx/go.mod index 8cd169014..5b51f64b1 100644 --- a/v3/integrations/nrpq/example/sqlx/go.mod +++ b/v3/integrations/nrpq/example/sqlx/go.mod @@ -1,11 +1,11 @@ // This sqlx example is a separate module to avoid adding sqlx dependency to the // nrpq go.mod file. module github.com/newrelic/go-agent/v3/integrations/nrpq/example/sqlx -go 1.20 +go 1.21 require ( github.com/jmoiron/sqlx v1.2.0 github.com/lib/pq v1.1.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrpq v0.0.0 ) replace github.com/newrelic/go-agent/v3/integrations/nrpq => ../../ diff --git a/v3/integrations/nrpq/go.mod b/v3/integrations/nrpq/go.mod index ae0452c72..979641e33 100644 --- a/v3/integrations/nrpq/go.mod +++ b/v3/integrations/nrpq/go.mod @@ -1,12 +1,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrpq -go 1.20 +go 1.21 require ( // NewConnector dsn parsing tests expect v1.1.0 error return behavior. github.com/lib/pq v1.1.0 // v3.3.0 includes the new location of ParseQuery - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrredis-v7/go.mod b/v3/integrations/nrredis-v7/go.mod index 6eb4e6f12..b8a899dd8 100644 --- a/v3/integrations/nrredis-v7/go.mod +++ b/v3/integrations/nrredis-v7/go.mod @@ -1,11 +1,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrredis-v7 // https://github.com/go-redis/redis/blob/master/go.mod -go 1.20 +go 1.21 require ( github.com/go-redis/redis/v7 v7.0.0-beta.5 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrredis-v8/go.mod b/v3/integrations/nrredis-v8/go.mod index 7f184a876..cbafc42fa 100644 --- a/v3/integrations/nrredis-v8/go.mod +++ b/v3/integrations/nrredis-v8/go.mod @@ -1,11 +1,11 @@ module github.com/newrelic/go-agent/v3/integrations/nrredis-v8 // https://github.com/go-redis/redis/blob/master/go.mod -go 1.20 +go 1.21 require ( github.com/go-redis/redis/v8 v8.4.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrredis-v9/go.mod b/v3/integrations/nrredis-v9/go.mod index 9134cee4b..0aeddc3bf 100644 --- a/v3/integrations/nrredis-v9/go.mod +++ b/v3/integrations/nrredis-v9/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrredis-v9 // https://github.com/redis/go-redis/blob/a38f75b640398bd709ee46c778a23e80e09d48b5/go.mod#L3 -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/redis/go-redis/v9 v9.0.2 ) diff --git a/v3/integrations/nrsarama/go.mod b/v3/integrations/nrsarama/go.mod index 1d2757a13..39577ab09 100644 --- a/v3/integrations/nrsarama/go.mod +++ b/v3/integrations/nrsarama/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrsarama -go 1.20 +go 1.21 require ( github.com/Shopify/sarama v1.38.1 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/stretchr/testify v1.8.1 ) diff --git a/v3/integrations/nrsecurityagent/go.mod b/v3/integrations/nrsecurityagent/go.mod index aae7f2977..b85d8cea1 100644 --- a/v3/integrations/nrsecurityagent/go.mod +++ b/v3/integrations/nrsecurityagent/go.mod @@ -1,10 +1,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrsecurityagent -go 1.20 +go 1.21 require ( - github.com/newrelic/csec-go-agent v1.3.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/csec-go-agent v1.4.0 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrsqlite3 v1.2.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/v3/integrations/nrslog/go.mod b/v3/integrations/nrslog/go.mod index aad673e83..39a7a016f 100644 --- a/v3/integrations/nrslog/go.mod +++ b/v3/integrations/nrslog/go.mod @@ -4,7 +4,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrslog go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/stretchr/testify v1.9.0 ) diff --git a/v3/integrations/nrsnowflake/go.mod b/v3/integrations/nrsnowflake/go.mod index 8694527a6..e66019fc3 100644 --- a/v3/integrations/nrsnowflake/go.mod +++ b/v3/integrations/nrsnowflake/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/nrsnowflake -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/snowflakedb/gosnowflake v1.6.19 ) diff --git a/v3/integrations/nrsqlite3/go.mod b/v3/integrations/nrsqlite3/go.mod index def941a1f..846de8eb3 100644 --- a/v3/integrations/nrsqlite3/go.mod +++ b/v3/integrations/nrsqlite3/go.mod @@ -2,12 +2,12 @@ module github.com/newrelic/go-agent/v3/integrations/nrsqlite3 // As of Dec 2019, 1.9 is the oldest version of Go tested by go-sqlite3: // https://github.com/mattn/go-sqlite3/blob/master/.travis.yml -go 1.20 +go 1.21 require ( github.com/mattn/go-sqlite3 v1.0.0 // v3.3.0 includes the new location of ParseQuery - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrstan/examples/go.mod b/v3/integrations/nrstan/examples/go.mod index f3b544556..893e5a164 100644 --- a/v3/integrations/nrstan/examples/go.mod +++ b/v3/integrations/nrstan/examples/go.mod @@ -1,9 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/nrstan/examples // This module exists to avoid a dependency on nrnrats. -go 1.20 +go 1.21 require ( github.com/nats-io/stan.go v0.5.0 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrnats v0.0.0 github.com/newrelic/go-agent/v3/integrations/nrstan v0.0.0 ) diff --git a/v3/integrations/nrstan/go.mod b/v3/integrations/nrstan/go.mod index fc7908b79..96a277ef3 100644 --- a/v3/integrations/nrstan/go.mod +++ b/v3/integrations/nrstan/go.mod @@ -2,13 +2,13 @@ module github.com/newrelic/go-agent/v3/integrations/nrstan // As of Dec 2019, 1.11 is the earliest Go version tested by Stan: // https://github.com/nats-io/stan.go/blob/master/.travis.yml -go 1.20 +go 1.21 toolchain go1.22.3 require ( github.com/nats-io/stan.go v0.10.4 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 ) diff --git a/v3/integrations/nrstan/test/go.mod b/v3/integrations/nrstan/test/go.mod index bb0001b15..edf8935a4 100644 --- a/v3/integrations/nrstan/test/go.mod +++ b/v3/integrations/nrstan/test/go.mod @@ -2,14 +2,14 @@ module github.com/newrelic/go-agent/v3/integrations/nrstan/test // This module exists to avoid a dependency on // github.com/nats-io/nats-streaming-server in nrstan. -go 1.20 +go 1.21 toolchain go1.22.3 require ( github.com/nats-io/nats-streaming-server v0.25.6 github.com/nats-io/stan.go v0.10.4 - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/newrelic/go-agent/v3/integrations/nrstan v0.0.0 ) diff --git a/v3/integrations/nrzap/go.mod b/v3/integrations/nrzap/go.mod index 34ce78a3b..c21e20b26 100644 --- a/v3/integrations/nrzap/go.mod +++ b/v3/integrations/nrzap/go.mod @@ -2,10 +2,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrzap // As of Dec 2019, zap has 1.13 in their go.mod file: // https://github.com/uber-go/zap/blob/master/go.mod -go 1.20 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.33.1 + github.com/newrelic/go-agent/v3 v3.35.0 // v1.12.0 is the earliest version of zap using modules. go.uber.org/zap v1.12.0 ) diff --git a/v3/integrations/nrzerolog/example_test.go b/v3/integrations/nrzerolog/example_test.go index 22e9e7b42..33ca22256 100644 --- a/v3/integrations/nrzerolog/example_test.go +++ b/v3/integrations/nrzerolog/example_test.go @@ -6,7 +6,8 @@ package nrzerolog_test import ( "os" - newrelic "github.com/newrelic/go-agent" + "github.com/newrelic/go-agent/v3/integrations/nrzerolog" + "github.com/newrelic/go-agent/v3/newrelic" "github.com/rs/zerolog" ) diff --git a/v3/integrations/nrzerolog/go.mod b/v3/integrations/nrzerolog/go.mod index e2eb6cf41..b8be9873a 100644 --- a/v3/integrations/nrzerolog/go.mod +++ b/v3/integrations/nrzerolog/go.mod @@ -1,8 +1,9 @@ module github.com/newrelic/go-agent/v3/integrations/nrzerolog -go 1.19 +go 1.21 require ( - github.com/newrelic/go-agent/v3 v3.20.2 + github.com/newrelic/go-agent/v3 v3.35.0 github.com/rs/zerolog v1.28.0 ) +replace github.com/newrelic/go-agent/v3 => ../.. diff --git a/v3/internal/com_newrelic_trace_v1/README.md b/v3/internal/com_newrelic_trace_v1/README.md index f628d709a..c24af93b5 100644 --- a/v3/internal/com_newrelic_trace_v1/README.md +++ b/v3/internal/com_newrelic_trace_v1/README.md @@ -4,14 +4,17 @@ To generate the `v1.pb.go` code, run the following from the top level `github.com/newrelic/go-agent` package: ``` -protoc --go_out=paths=source_relative,plugins=grpc:. v3/internal/com_newrelic_trace_v1/v1.proto +protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + v3/internal/com_newrelic_trace_v1/v1.proto ``` -Be mindful which version of `protoc-gen-go` you are using. Upgrade -`protoc-gen-go` to the latest with: +Be mindful which version of `protoc-gen-go` and `protoc-gen-go-grpc` you are using. +Upgrade both of these tools to the latest with: ``` -go get -u github.com/golang/protobuf/protoc-gen-go +go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest ``` ## When you regenerate the file diff --git a/v3/internal/com_newrelic_trace_v1/v1.pb.go b/v3/internal/com_newrelic_trace_v1/v1.pb.go index 7976ecb97..bee2b7b03 100644 --- a/v3/internal/com_newrelic_trace_v1/v1.pb.go +++ b/v3/internal/com_newrelic_trace_v1/v1.pb.go @@ -1,200 +1,191 @@ // Copyright 2020 New Relic Corporation. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -// +build go1.9 // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v5.27.3 // source: v3/internal/com_newrelic_trace_v1/v1.proto package com_newrelic_trace_v1 import ( - context "context" - fmt "fmt" - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type SpanBatch struct { - Spans []*Span `protobuf:"bytes,1,rep,name=spans,proto3" json:"spans,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *SpanBatch) Reset() { *m = SpanBatch{} } -func (m *SpanBatch) String() string { return proto.CompactTextString(m) } -func (*SpanBatch) ProtoMessage() {} -func (*SpanBatch) Descriptor() ([]byte, []int) { - return fileDescriptor_10a7bb7b83f0c5c3, []int{0} + Spans []*Span `protobuf:"bytes,1,rep,name=spans,proto3" json:"spans,omitempty"` } -func (m *SpanBatch) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SpanBatch.Unmarshal(m, b) -} -func (m *SpanBatch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SpanBatch.Marshal(b, m, deterministic) -} -func (m *SpanBatch) XXX_Merge(src proto.Message) { - xxx_messageInfo_SpanBatch.Merge(m, src) +func (x *SpanBatch) Reset() { + *x = SpanBatch{} + if protoimpl.UnsafeEnabled { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SpanBatch) XXX_Size() int { - return xxx_messageInfo_SpanBatch.Size(m) + +func (x *SpanBatch) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SpanBatch) XXX_DiscardUnknown() { - xxx_messageInfo_SpanBatch.DiscardUnknown(m) + +func (*SpanBatch) ProtoMessage() {} + +func (x *SpanBatch) ProtoReflect() protoreflect.Message { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_SpanBatch proto.InternalMessageInfo +// Deprecated: Use SpanBatch.ProtoReflect.Descriptor instead. +func (*SpanBatch) Descriptor() ([]byte, []int) { + return file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescGZIP(), []int{0} +} -func (m *SpanBatch) GetSpans() []*Span { - if m != nil { - return m.Spans +func (x *SpanBatch) GetSpans() []*Span { + if x != nil { + return x.Spans } return nil } type Span struct { - TraceId string `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` - Intrinsics map[string]*AttributeValue `protobuf:"bytes,2,rep,name=intrinsics,proto3" json:"intrinsics,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - UserAttributes map[string]*AttributeValue `protobuf:"bytes,3,rep,name=user_attributes,json=userAttributes,proto3" json:"user_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - AgentAttributes map[string]*AttributeValue `protobuf:"bytes,4,rep,name=agent_attributes,json=agentAttributes,proto3" json:"agent_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Span) Reset() { *m = Span{} } -func (m *Span) String() string { return proto.CompactTextString(m) } -func (*Span) ProtoMessage() {} -func (*Span) Descriptor() ([]byte, []int) { - return fileDescriptor_10a7bb7b83f0c5c3, []int{1} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TraceId string `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` + Intrinsics map[string]*AttributeValue `protobuf:"bytes,2,rep,name=intrinsics,proto3" json:"intrinsics,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + UserAttributes map[string]*AttributeValue `protobuf:"bytes,3,rep,name=user_attributes,json=userAttributes,proto3" json:"user_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + AgentAttributes map[string]*AttributeValue `protobuf:"bytes,4,rep,name=agent_attributes,json=agentAttributes,proto3" json:"agent_attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *Span) Reset() { + *x = Span{} + if protoimpl.UnsafeEnabled { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *Span) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Span.Unmarshal(m, b) -} -func (m *Span) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Span.Marshal(b, m, deterministic) +func (x *Span) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Span) XXX_Merge(src proto.Message) { - xxx_messageInfo_Span.Merge(m, src) -} -func (m *Span) XXX_Size() int { - return xxx_messageInfo_Span.Size(m) -} -func (m *Span) XXX_DiscardUnknown() { - xxx_messageInfo_Span.DiscardUnknown(m) + +func (*Span) ProtoMessage() {} + +func (x *Span) ProtoReflect() protoreflect.Message { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_Span proto.InternalMessageInfo +// Deprecated: Use Span.ProtoReflect.Descriptor instead. +func (*Span) Descriptor() ([]byte, []int) { + return file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescGZIP(), []int{1} +} -func (m *Span) GetTraceId() string { - if m != nil { - return m.TraceId +func (x *Span) GetTraceId() string { + if x != nil { + return x.TraceId } return "" } -func (m *Span) GetIntrinsics() map[string]*AttributeValue { - if m != nil { - return m.Intrinsics +func (x *Span) GetIntrinsics() map[string]*AttributeValue { + if x != nil { + return x.Intrinsics } return nil } -func (m *Span) GetUserAttributes() map[string]*AttributeValue { - if m != nil { - return m.UserAttributes +func (x *Span) GetUserAttributes() map[string]*AttributeValue { + if x != nil { + return x.UserAttributes } return nil } -func (m *Span) GetAgentAttributes() map[string]*AttributeValue { - if m != nil { - return m.AgentAttributes +func (x *Span) GetAgentAttributes() map[string]*AttributeValue { + if x != nil { + return x.AgentAttributes } return nil } type AttributeValue struct { - // Types that are valid to be assigned to Value: + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Value: // *AttributeValue_StringValue // *AttributeValue_BoolValue // *AttributeValue_IntValue // *AttributeValue_DoubleValue - Value isAttributeValue_Value `protobuf_oneof:"value"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AttributeValue) Reset() { *m = AttributeValue{} } -func (m *AttributeValue) String() string { return proto.CompactTextString(m) } -func (*AttributeValue) ProtoMessage() {} -func (*AttributeValue) Descriptor() ([]byte, []int) { - return fileDescriptor_10a7bb7b83f0c5c3, []int{2} + Value isAttributeValue_Value `protobuf_oneof:"value"` } -func (m *AttributeValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AttributeValue.Unmarshal(m, b) -} -func (m *AttributeValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AttributeValue.Marshal(b, m, deterministic) -} -func (m *AttributeValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_AttributeValue.Merge(m, src) -} -func (m *AttributeValue) XXX_Size() int { - return xxx_messageInfo_AttributeValue.Size(m) -} -func (m *AttributeValue) XXX_DiscardUnknown() { - xxx_messageInfo_AttributeValue.DiscardUnknown(m) +func (x *AttributeValue) Reset() { + *x = AttributeValue{} + if protoimpl.UnsafeEnabled { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -var xxx_messageInfo_AttributeValue proto.InternalMessageInfo - -type isAttributeValue_Value interface { - isAttributeValue_Value() +func (x *AttributeValue) String() string { + return protoimpl.X.MessageStringOf(x) } -type AttributeValue_StringValue struct { - StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` -} +func (*AttributeValue) ProtoMessage() {} -type AttributeValue_BoolValue struct { - BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"` -} - -type AttributeValue_IntValue struct { - IntValue int64 `protobuf:"varint,3,opt,name=int_value,json=intValue,proto3,oneof"` +func (x *AttributeValue) ProtoReflect() protoreflect.Message { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -type AttributeValue_DoubleValue struct { - DoubleValue float64 `protobuf:"fixed64,4,opt,name=double_value,json=doubleValue,proto3,oneof"` +// Deprecated: Use AttributeValue.ProtoReflect.Descriptor instead. +func (*AttributeValue) Descriptor() ([]byte, []int) { + return file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescGZIP(), []int{2} } -func (*AttributeValue_StringValue) isAttributeValue_Value() {} - -func (*AttributeValue_BoolValue) isAttributeValue_Value() {} - -func (*AttributeValue_IntValue) isAttributeValue_Value() {} - -func (*AttributeValue_DoubleValue) isAttributeValue_Value() {} - func (m *AttributeValue) GetValue() isAttributeValue_Value { if m != nil { return m.Value @@ -202,319 +193,310 @@ func (m *AttributeValue) GetValue() isAttributeValue_Value { return nil } -func (m *AttributeValue) GetStringValue() string { - if x, ok := m.GetValue().(*AttributeValue_StringValue); ok { +func (x *AttributeValue) GetStringValue() string { + if x, ok := x.GetValue().(*AttributeValue_StringValue); ok { return x.StringValue } return "" } -func (m *AttributeValue) GetBoolValue() bool { - if x, ok := m.GetValue().(*AttributeValue_BoolValue); ok { +func (x *AttributeValue) GetBoolValue() bool { + if x, ok := x.GetValue().(*AttributeValue_BoolValue); ok { return x.BoolValue } return false } -func (m *AttributeValue) GetIntValue() int64 { - if x, ok := m.GetValue().(*AttributeValue_IntValue); ok { +func (x *AttributeValue) GetIntValue() int64 { + if x, ok := x.GetValue().(*AttributeValue_IntValue); ok { return x.IntValue } return 0 } -func (m *AttributeValue) GetDoubleValue() float64 { - if x, ok := m.GetValue().(*AttributeValue_DoubleValue); ok { +func (x *AttributeValue) GetDoubleValue() float64 { + if x, ok := x.GetValue().(*AttributeValue_DoubleValue); ok { return x.DoubleValue } return 0 } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*AttributeValue) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*AttributeValue_StringValue)(nil), - (*AttributeValue_BoolValue)(nil), - (*AttributeValue_IntValue)(nil), - (*AttributeValue_DoubleValue)(nil), - } -} - -type RecordStatus struct { - MessagesSeen uint64 `protobuf:"varint,1,opt,name=messages_seen,json=messagesSeen,proto3" json:"messages_seen,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RecordStatus) Reset() { *m = RecordStatus{} } -func (m *RecordStatus) String() string { return proto.CompactTextString(m) } -func (*RecordStatus) ProtoMessage() {} -func (*RecordStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_10a7bb7b83f0c5c3, []int{3} -} - -func (m *RecordStatus) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RecordStatus.Unmarshal(m, b) -} -func (m *RecordStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RecordStatus.Marshal(b, m, deterministic) -} -func (m *RecordStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_RecordStatus.Merge(m, src) -} -func (m *RecordStatus) XXX_Size() int { - return xxx_messageInfo_RecordStatus.Size(m) -} -func (m *RecordStatus) XXX_DiscardUnknown() { - xxx_messageInfo_RecordStatus.DiscardUnknown(m) +type isAttributeValue_Value interface { + isAttributeValue_Value() } -var xxx_messageInfo_RecordStatus proto.InternalMessageInfo - -func (m *RecordStatus) GetMessagesSeen() uint64 { - if m != nil { - return m.MessagesSeen - } - return 0 +type AttributeValue_StringValue struct { + StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` } -func init() { - proto.RegisterType((*SpanBatch)(nil), "com.newrelic.trace.v1.SpanBatch") - proto.RegisterType((*Span)(nil), "com.newrelic.trace.v1.Span") - proto.RegisterMapType((map[string]*AttributeValue)(nil), "com.newrelic.trace.v1.Span.AgentAttributesEntry") - proto.RegisterMapType((map[string]*AttributeValue)(nil), "com.newrelic.trace.v1.Span.IntrinsicsEntry") - proto.RegisterMapType((map[string]*AttributeValue)(nil), "com.newrelic.trace.v1.Span.UserAttributesEntry") - proto.RegisterType((*AttributeValue)(nil), "com.newrelic.trace.v1.AttributeValue") - proto.RegisterType((*RecordStatus)(nil), "com.newrelic.trace.v1.RecordStatus") -} - -func init() { - proto.RegisterFile("v3/internal/com_newrelic_trace_v1/v1.proto", fileDescriptor_10a7bb7b83f0c5c3) -} - -var fileDescriptor_10a7bb7b83f0c5c3 = []byte{ - // 505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0x61, 0x8b, 0x12, 0x41, - 0x18, 0xc7, 0x1d, 0xf5, 0x3a, 0x7d, 0xf4, 0xce, 0x63, 0x2a, 0x30, 0x23, 0x5a, 0x94, 0x60, 0x29, - 0xda, 0x3d, 0xf5, 0x4d, 0x14, 0x1c, 0x9d, 0x10, 0x28, 0xbd, 0x5b, 0x2b, 0xa2, 0xa0, 0x65, 0x5c, - 0x1f, 0xd6, 0x21, 0x9d, 0x95, 0x99, 0xd9, 0x8d, 0xfb, 0x3c, 0x7d, 0x96, 0xbe, 0x47, 0x1f, 0x25, - 0x76, 0x46, 0x3d, 0x3d, 0x3c, 0xe3, 0x5e, 0xdc, 0xbb, 0xdd, 0xe7, 0xf9, 0xff, 0x7f, 0xff, 0x79, - 0x06, 0x9e, 0x81, 0x97, 0x59, 0xdf, 0xe7, 0x42, 0xa3, 0x14, 0x6c, 0xee, 0x47, 0xc9, 0x22, 0x14, - 0xf8, 0x4b, 0xe2, 0x9c, 0x47, 0xa1, 0x96, 0x2c, 0xc2, 0x30, 0xeb, 0xfa, 0x59, 0xd7, 0x5b, 0xca, - 0x44, 0x27, 0xf4, 0x71, 0x94, 0x2c, 0xbc, 0x75, 0xdf, 0x33, 0x7d, 0x2f, 0xeb, 0xb6, 0x2f, 0xa0, - 0x3a, 0x5e, 0x32, 0x31, 0x60, 0x3a, 0x9a, 0xd1, 0x2e, 0x1c, 0xa9, 0x25, 0x13, 0xaa, 0x49, 0x9c, - 0x92, 0x5b, 0xeb, 0x3d, 0xf5, 0xf6, 0x7a, 0xbc, 0xdc, 0x10, 0x58, 0x65, 0xfb, 0x6f, 0x19, 0xca, - 0xf9, 0x3f, 0x7d, 0x02, 0x15, 0x1b, 0xca, 0xa7, 0x4d, 0xe2, 0x10, 0xb7, 0x1a, 0x1c, 0x9b, 0xff, - 0xd1, 0x94, 0x7e, 0x04, 0xe0, 0x42, 0x4b, 0x2e, 0x14, 0x8f, 0x54, 0xb3, 0x68, 0xd8, 0xaf, 0x0e, - 0xb0, 0xbd, 0xd1, 0x46, 0xfd, 0x41, 0x68, 0x79, 0x15, 0x6c, 0xd9, 0xe9, 0x57, 0x68, 0xa4, 0x0a, - 0x65, 0xc8, 0xb4, 0x96, 0x7c, 0x92, 0x6a, 0x54, 0xcd, 0x92, 0x21, 0xfa, 0x87, 0x88, 0x9f, 0x15, - 0xca, 0xcb, 0x8d, 0xc3, 0x52, 0x4f, 0xd3, 0x9d, 0x22, 0xfd, 0x0e, 0x67, 0x2c, 0x46, 0xa1, 0xb7, - 0xd1, 0x65, 0x83, 0x3e, 0x3f, 0x84, 0xbe, 0xcc, 0x3d, 0x37, 0xd9, 0x0d, 0xb6, 0x5b, 0x6d, 0x4d, - 0xa1, 0x71, 0x63, 0x2a, 0x7a, 0x06, 0xa5, 0x9f, 0x78, 0xb5, 0xba, 0xac, 0xfc, 0x93, 0xbe, 0x83, - 0xa3, 0x8c, 0xcd, 0x53, 0x6c, 0x16, 0x1d, 0xe2, 0xd6, 0x7a, 0x2f, 0x6e, 0x89, 0xdd, 0x60, 0xbf, - 0xe4, 0xe2, 0xc0, 0x7a, 0xde, 0x16, 0xdf, 0x90, 0xd6, 0x0c, 0x1e, 0xee, 0x99, 0xf4, 0x3e, 0x92, - 0x38, 0x3c, 0xda, 0x37, 0xf8, 0x3d, 0x44, 0xb5, 0x7f, 0x13, 0x38, 0xdd, 0xed, 0xd2, 0x0e, 0xd4, - 0x55, 0x7e, 0x99, 0x71, 0x68, 0xd1, 0x26, 0x6e, 0x58, 0x08, 0x6a, 0xb6, 0x6a, 0x45, 0xcf, 0x01, - 0x26, 0x49, 0x32, 0x0f, 0xaf, 0xd3, 0x2b, 0xc3, 0x42, 0x50, 0xcd, 0x6b, 0x56, 0xf0, 0x0c, 0xaa, - 0x5c, 0xe8, 0x55, 0xbf, 0xe4, 0x10, 0xb7, 0x34, 0x2c, 0x04, 0x15, 0x2e, 0xf4, 0x26, 0x64, 0x9a, - 0xa4, 0x93, 0x39, 0xae, 0x14, 0x65, 0x87, 0xb8, 0x24, 0x0f, 0xb1, 0x55, 0x23, 0x1a, 0x1c, 0xaf, - 0xa6, 0x6b, 0xf7, 0xa1, 0x1e, 0x60, 0x94, 0xc8, 0xe9, 0x58, 0x33, 0x9d, 0x2a, 0xda, 0x81, 0x93, - 0x05, 0x2a, 0xc5, 0x62, 0x54, 0xa1, 0x42, 0x14, 0xe6, 0x8c, 0xe5, 0xa0, 0xbe, 0x2e, 0x8e, 0x11, - 0x45, 0xef, 0x0f, 0x81, 0x93, 0x91, 0x88, 0x51, 0xe9, 0x31, 0xca, 0x8c, 0x47, 0x48, 0x3f, 0x01, - 0xac, 0x30, 0xf9, 0x52, 0x1d, 0xda, 0xc0, 0x56, 0xe7, 0x96, 0xe6, 0xf6, 0x31, 0xda, 0x05, 0x97, - 0x9c, 0x13, 0xfa, 0x03, 0x1a, 0xd7, 0x54, 0xbb, 0xeb, 0xce, 0x01, 0xb4, 0x51, 0xdc, 0x81, 0x3f, - 0x78, 0xff, 0xed, 0x22, 0xe6, 0x7a, 0x96, 0x4e, 0x72, 0x8b, 0xbf, 0xb6, 0xf8, 0x71, 0xf2, 0xda, - 0xec, 0x81, 0xff, 0xdf, 0x77, 0x6a, 0xf2, 0xc0, 0xbc, 0x52, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x38, 0x06, 0x7c, 0x3d, 0xd3, 0x04, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConnInterface - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion6 - -// IngestServiceClient is the client API for IngestService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type IngestServiceClient interface { - // Accepts a stream of Span messages, and returns an irregular stream of - // RecordStatus messages. - RecordSpan(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanClient, error) - // Accepts a stream of SpanBatch messages, and returns an irregular - // stream of RecordStatus messages. This endpoint can be used to improve - // throughput when Span messages are small - RecordSpanBatch(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanBatchClient, error) -} - -type ingestServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewIngestServiceClient(cc grpc.ClientConnInterface) IngestServiceClient { - return &ingestServiceClient{cc} -} - -func (c *ingestServiceClient) RecordSpan(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanClient, error) { - stream, err := c.cc.NewStream(ctx, &_IngestService_serviceDesc.Streams[0], "/com.newrelic.trace.v1.IngestService/RecordSpan", opts...) - if err != nil { - return nil, err - } - x := &ingestServiceRecordSpanClient{stream} - return x, nil +type AttributeValue_BoolValue struct { + BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"` } -type IngestService_RecordSpanClient interface { - Send(*Span) error - Recv() (*RecordStatus, error) - grpc.ClientStream +type AttributeValue_IntValue struct { + IntValue int64 `protobuf:"varint,3,opt,name=int_value,json=intValue,proto3,oneof"` } -type ingestServiceRecordSpanClient struct { - grpc.ClientStream +type AttributeValue_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,4,opt,name=double_value,json=doubleValue,proto3,oneof"` } -func (x *ingestServiceRecordSpanClient) Send(m *Span) error { - return x.ClientStream.SendMsg(m) -} +func (*AttributeValue_StringValue) isAttributeValue_Value() {} -func (x *ingestServiceRecordSpanClient) Recv() (*RecordStatus, error) { - m := new(RecordStatus) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +func (*AttributeValue_BoolValue) isAttributeValue_Value() {} -func (c *ingestServiceClient) RecordSpanBatch(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanBatchClient, error) { - stream, err := c.cc.NewStream(ctx, &_IngestService_serviceDesc.Streams[1], "/com.newrelic.trace.v1.IngestService/RecordSpanBatch", opts...) - if err != nil { - return nil, err - } - x := &ingestServiceRecordSpanBatchClient{stream} - return x, nil -} +func (*AttributeValue_IntValue) isAttributeValue_Value() {} -type IngestService_RecordSpanBatchClient interface { - Send(*SpanBatch) error - Recv() (*RecordStatus, error) - grpc.ClientStream -} +func (*AttributeValue_DoubleValue) isAttributeValue_Value() {} -type ingestServiceRecordSpanBatchClient struct { - grpc.ClientStream -} +type RecordStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (x *ingestServiceRecordSpanBatchClient) Send(m *SpanBatch) error { - return x.ClientStream.SendMsg(m) + MessagesSeen uint64 `protobuf:"varint,1,opt,name=messages_seen,json=messagesSeen,proto3" json:"messages_seen,omitempty"` } -func (x *ingestServiceRecordSpanBatchClient) Recv() (*RecordStatus, error) { - m := new(RecordStatus) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (x *RecordStatus) Reset() { + *x = RecordStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return m, nil } -// IngestServiceServer is the server API for IngestService service. -type IngestServiceServer interface { - // Accepts a stream of Span messages, and returns an irregular stream of - // RecordStatus messages. - RecordSpan(IngestService_RecordSpanServer) error - // Accepts a stream of SpanBatch messages, and returns an irregular - // stream of RecordStatus messages. This endpoint can be used to improve - // throughput when Span messages are small - RecordSpanBatch(IngestService_RecordSpanBatchServer) error +func (x *RecordStatus) String() string { + return protoimpl.X.MessageStringOf(x) } -// UnimplementedIngestServiceServer can be embedded to have forward compatible implementations. -type UnimplementedIngestServiceServer struct { -} - -func (*UnimplementedIngestServiceServer) RecordSpan(srv IngestService_RecordSpanServer) error { - return status.Errorf(codes.Unimplemented, "method RecordSpan not implemented") -} -func (*UnimplementedIngestServiceServer) RecordSpanBatch(srv IngestService_RecordSpanBatchServer) error { - return status.Errorf(codes.Unimplemented, "method RecordSpanBatch not implemented") -} - -func RegisterIngestServiceServer(s *grpc.Server, srv IngestServiceServer) { - s.RegisterService(&_IngestService_serviceDesc, srv) -} - -func _IngestService_RecordSpan_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(IngestServiceServer).RecordSpan(&ingestServiceRecordSpanServer{stream}) -} - -type IngestService_RecordSpanServer interface { - Send(*RecordStatus) error - Recv() (*Span, error) - grpc.ServerStream -} - -type ingestServiceRecordSpanServer struct { - grpc.ServerStream -} +func (*RecordStatus) ProtoMessage() {} -func (x *ingestServiceRecordSpanServer) Send(m *RecordStatus) error { - return x.ServerStream.SendMsg(m) -} - -func (x *ingestServiceRecordSpanServer) Recv() (*Span, error) { - m := new(Span) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err +func (x *RecordStatus) ProtoReflect() protoreflect.Message { + mi := &file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return m, nil -} - -func _IngestService_RecordSpanBatch_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(IngestServiceServer).RecordSpanBatch(&ingestServiceRecordSpanBatchServer{stream}) + return mi.MessageOf(x) } -type IngestService_RecordSpanBatchServer interface { - Send(*RecordStatus) error - Recv() (*SpanBatch, error) - grpc.ServerStream +// Deprecated: Use RecordStatus.ProtoReflect.Descriptor instead. +func (*RecordStatus) Descriptor() ([]byte, []int) { + return file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescGZIP(), []int{3} } -type ingestServiceRecordSpanBatchServer struct { - grpc.ServerStream +func (x *RecordStatus) GetMessagesSeen() uint64 { + if x != nil { + return x.MessagesSeen + } + return 0 } -func (x *ingestServiceRecordSpanBatchServer) Send(m *RecordStatus) error { - return x.ServerStream.SendMsg(m) -} +var File_v3_internal_com_newrelic_trace_v1_v1_proto protoreflect.FileDescriptor + +var file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDesc = []byte{ + 0x0a, 0x2a, 0x76, 0x33, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, + 0x6d, 0x5f, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x5f, 0x76, 0x31, 0x2f, 0x76, 0x31, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x63, 0x6f, + 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x2e, 0x76, 0x31, 0x22, 0x3e, 0x0a, 0x09, 0x53, 0x70, 0x61, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x12, 0x31, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x05, 0x73, 0x70, + 0x61, 0x6e, 0x73, 0x22, 0xe0, 0x04, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x19, 0x0a, 0x08, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0a, 0x69, 0x6e, 0x74, 0x72, 0x69, + 0x6e, 0x73, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, + 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x49, 0x6e, 0x74, 0x72, 0x69, 0x6e, 0x73, + 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x72, 0x69, 0x6e, + 0x73, 0x69, 0x63, 0x73, 0x12, 0x58, 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, + 0x75, 0x73, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x5b, + 0x0a, 0x10, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, + 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x64, 0x0a, 0x0f, 0x49, + 0x6e, 0x74, 0x72, 0x69, 0x6e, 0x73, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x3b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x68, 0x0a, 0x13, 0x55, 0x73, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3b, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, + 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x69, 0x0a, 0x14, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, + 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa3, 0x01, 0x0a, 0x0e, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, + 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, + 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x33, 0x0a, 0x0c, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x53, 0x65, 0x65, + 0x6e, 0x32, 0xc5, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x53, 0x70, 0x61, + 0x6e, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, + 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x1a, 0x23, + 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5e, 0x0a, 0x0f, 0x52, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x53, 0x70, 0x61, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x63, + 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x23, + 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, 0x2e, 0x74, 0x72, + 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, 0x69, 0x63, + 0x2f, 0x67, 0x6f, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x33, 0x2f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6d, 0x5f, 0x6e, 0x65, 0x77, 0x72, 0x65, 0x6c, + 0x69, 0x63, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescOnce sync.Once + file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescData = file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDesc +) -func (x *ingestServiceRecordSpanBatchServer) Recv() (*SpanBatch, error) { - m := new(SpanBatch) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err +func file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescGZIP() []byte { + file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescOnce.Do(func() { + file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescData = protoimpl.X.CompressGZIP(file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescData) + }) + return file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDescData +} + +var file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_v3_internal_com_newrelic_trace_v1_v1_proto_goTypes = []interface{}{ + (*SpanBatch)(nil), // 0: com.newrelic.trace.v1.SpanBatch + (*Span)(nil), // 1: com.newrelic.trace.v1.Span + (*AttributeValue)(nil), // 2: com.newrelic.trace.v1.AttributeValue + (*RecordStatus)(nil), // 3: com.newrelic.trace.v1.RecordStatus + nil, // 4: com.newrelic.trace.v1.Span.IntrinsicsEntry + nil, // 5: com.newrelic.trace.v1.Span.UserAttributesEntry + nil, // 6: com.newrelic.trace.v1.Span.AgentAttributesEntry +} +var file_v3_internal_com_newrelic_trace_v1_v1_proto_depIdxs = []int32{ + 1, // 0: com.newrelic.trace.v1.SpanBatch.spans:type_name -> com.newrelic.trace.v1.Span + 4, // 1: com.newrelic.trace.v1.Span.intrinsics:type_name -> com.newrelic.trace.v1.Span.IntrinsicsEntry + 5, // 2: com.newrelic.trace.v1.Span.user_attributes:type_name -> com.newrelic.trace.v1.Span.UserAttributesEntry + 6, // 3: com.newrelic.trace.v1.Span.agent_attributes:type_name -> com.newrelic.trace.v1.Span.AgentAttributesEntry + 2, // 4: com.newrelic.trace.v1.Span.IntrinsicsEntry.value:type_name -> com.newrelic.trace.v1.AttributeValue + 2, // 5: com.newrelic.trace.v1.Span.UserAttributesEntry.value:type_name -> com.newrelic.trace.v1.AttributeValue + 2, // 6: com.newrelic.trace.v1.Span.AgentAttributesEntry.value:type_name -> com.newrelic.trace.v1.AttributeValue + 1, // 7: com.newrelic.trace.v1.IngestService.RecordSpan:input_type -> com.newrelic.trace.v1.Span + 0, // 8: com.newrelic.trace.v1.IngestService.RecordSpanBatch:input_type -> com.newrelic.trace.v1.SpanBatch + 3, // 9: com.newrelic.trace.v1.IngestService.RecordSpan:output_type -> com.newrelic.trace.v1.RecordStatus + 3, // 10: com.newrelic.trace.v1.IngestService.RecordSpanBatch:output_type -> com.newrelic.trace.v1.RecordStatus + 9, // [9:11] is the sub-list for method output_type + 7, // [7:9] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_v3_internal_com_newrelic_trace_v1_v1_proto_init() } +func file_v3_internal_com_newrelic_trace_v1_v1_proto_init() { + if File_v3_internal_com_newrelic_trace_v1_v1_proto != nil { + return } - return m, nil -} - -var _IngestService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "com.newrelic.trace.v1.IngestService", - HandlerType: (*IngestServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "RecordSpan", - Handler: _IngestService_RecordSpan_Handler, - ServerStreams: true, - ClientStreams: true, - }, - { - StreamName: "RecordSpanBatch", - Handler: _IngestService_RecordSpanBatch_Handler, - ServerStreams: true, - ClientStreams: true, + if !protoimpl.UnsafeEnabled { + file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SpanBatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Span); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AttributeValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RecordStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*AttributeValue_StringValue)(nil), + (*AttributeValue_BoolValue)(nil), + (*AttributeValue_IntValue)(nil), + (*AttributeValue_DoubleValue)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 1, }, - }, - Metadata: "v3/internal/com_newrelic_trace_v1/v1.proto", + GoTypes: file_v3_internal_com_newrelic_trace_v1_v1_proto_goTypes, + DependencyIndexes: file_v3_internal_com_newrelic_trace_v1_v1_proto_depIdxs, + MessageInfos: file_v3_internal_com_newrelic_trace_v1_v1_proto_msgTypes, + }.Build() + File_v3_internal_com_newrelic_trace_v1_v1_proto = out.File + file_v3_internal_com_newrelic_trace_v1_v1_proto_rawDesc = nil + file_v3_internal_com_newrelic_trace_v1_v1_proto_goTypes = nil + file_v3_internal_com_newrelic_trace_v1_v1_proto_depIdxs = nil } diff --git a/v3/internal/com_newrelic_trace_v1/v1_grpc.pb.go b/v3/internal/com_newrelic_trace_v1/v1_grpc.pb.go new file mode 100644 index 000000000..e957e8959 --- /dev/null +++ b/v3/internal/com_newrelic_trace_v1/v1_grpc.pb.go @@ -0,0 +1,215 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v5.27.3 +// source: v3/internal/com_newrelic_trace_v1/v1.proto + +package com_newrelic_trace_v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// IngestServiceClient is the client API for IngestService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type IngestServiceClient interface { + // Accepts a stream of Span messages, and returns an irregular stream of + // RecordStatus messages. + RecordSpan(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanClient, error) + // Accepts a stream of SpanBatch messages, and returns an irregular + // stream of RecordStatus messages. This endpoint can be used to improve + // throughput when Span messages are small + RecordSpanBatch(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanBatchClient, error) +} + +type ingestServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewIngestServiceClient(cc grpc.ClientConnInterface) IngestServiceClient { + return &ingestServiceClient{cc} +} + +func (c *ingestServiceClient) RecordSpan(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanClient, error) { + stream, err := c.cc.NewStream(ctx, &IngestService_ServiceDesc.Streams[0], "/com.newrelic.trace.v1.IngestService/RecordSpan", opts...) + if err != nil { + return nil, err + } + x := &ingestServiceRecordSpanClient{stream} + return x, nil +} + +type IngestService_RecordSpanClient interface { + Send(*Span) error + Recv() (*RecordStatus, error) + grpc.ClientStream +} + +type ingestServiceRecordSpanClient struct { + grpc.ClientStream +} + +func (x *ingestServiceRecordSpanClient) Send(m *Span) error { + return x.ClientStream.SendMsg(m) +} + +func (x *ingestServiceRecordSpanClient) Recv() (*RecordStatus, error) { + m := new(RecordStatus) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *ingestServiceClient) RecordSpanBatch(ctx context.Context, opts ...grpc.CallOption) (IngestService_RecordSpanBatchClient, error) { + stream, err := c.cc.NewStream(ctx, &IngestService_ServiceDesc.Streams[1], "/com.newrelic.trace.v1.IngestService/RecordSpanBatch", opts...) + if err != nil { + return nil, err + } + x := &ingestServiceRecordSpanBatchClient{stream} + return x, nil +} + +type IngestService_RecordSpanBatchClient interface { + Send(*SpanBatch) error + Recv() (*RecordStatus, error) + grpc.ClientStream +} + +type ingestServiceRecordSpanBatchClient struct { + grpc.ClientStream +} + +func (x *ingestServiceRecordSpanBatchClient) Send(m *SpanBatch) error { + return x.ClientStream.SendMsg(m) +} + +func (x *ingestServiceRecordSpanBatchClient) Recv() (*RecordStatus, error) { + m := new(RecordStatus) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// IngestServiceServer is the server API for IngestService service. +// All implementations must embed UnimplementedIngestServiceServer +// for forward compatibility +type IngestServiceServer interface { + // Accepts a stream of Span messages, and returns an irregular stream of + // RecordStatus messages. + RecordSpan(IngestService_RecordSpanServer) error + // Accepts a stream of SpanBatch messages, and returns an irregular + // stream of RecordStatus messages. This endpoint can be used to improve + // throughput when Span messages are small + RecordSpanBatch(IngestService_RecordSpanBatchServer) error + mustEmbedUnimplementedIngestServiceServer() +} + +// UnimplementedIngestServiceServer must be embedded to have forward compatible implementations. +type UnimplementedIngestServiceServer struct { +} + +func (UnimplementedIngestServiceServer) RecordSpan(IngestService_RecordSpanServer) error { + return status.Errorf(codes.Unimplemented, "method RecordSpan not implemented") +} +func (UnimplementedIngestServiceServer) RecordSpanBatch(IngestService_RecordSpanBatchServer) error { + return status.Errorf(codes.Unimplemented, "method RecordSpanBatch not implemented") +} +func (UnimplementedIngestServiceServer) mustEmbedUnimplementedIngestServiceServer() {} + +// UnsafeIngestServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to IngestServiceServer will +// result in compilation errors. +type UnsafeIngestServiceServer interface { + mustEmbedUnimplementedIngestServiceServer() +} + +func RegisterIngestServiceServer(s grpc.ServiceRegistrar, srv IngestServiceServer) { + s.RegisterService(&IngestService_ServiceDesc, srv) +} + +func _IngestService_RecordSpan_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(IngestServiceServer).RecordSpan(&ingestServiceRecordSpanServer{stream}) +} + +type IngestService_RecordSpanServer interface { + Send(*RecordStatus) error + Recv() (*Span, error) + grpc.ServerStream +} + +type ingestServiceRecordSpanServer struct { + grpc.ServerStream +} + +func (x *ingestServiceRecordSpanServer) Send(m *RecordStatus) error { + return x.ServerStream.SendMsg(m) +} + +func (x *ingestServiceRecordSpanServer) Recv() (*Span, error) { + m := new(Span) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _IngestService_RecordSpanBatch_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(IngestServiceServer).RecordSpanBatch(&ingestServiceRecordSpanBatchServer{stream}) +} + +type IngestService_RecordSpanBatchServer interface { + Send(*RecordStatus) error + Recv() (*SpanBatch, error) + grpc.ServerStream +} + +type ingestServiceRecordSpanBatchServer struct { + grpc.ServerStream +} + +func (x *ingestServiceRecordSpanBatchServer) Send(m *RecordStatus) error { + return x.ServerStream.SendMsg(m) +} + +func (x *ingestServiceRecordSpanBatchServer) Recv() (*SpanBatch, error) { + m := new(SpanBatch) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// IngestService_ServiceDesc is the grpc.ServiceDesc for IngestService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var IngestService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "com.newrelic.trace.v1.IngestService", + HandlerType: (*IngestServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "RecordSpan", + Handler: _IngestService_RecordSpan_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "RecordSpanBatch", + Handler: _IngestService_RecordSpanBatch_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "v3/internal/com_newrelic_trace_v1/v1.proto", +} diff --git a/v3/internal/sysinfo/memtotal_js.go b/v3/internal/sysinfo/memtotal_js.go new file mode 100644 index 000000000..a0d81766f --- /dev/null +++ b/v3/internal/sysinfo/memtotal_js.go @@ -0,0 +1,11 @@ +// Copyright 2020 New Relic Corporation. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package sysinfo + +import "errors" + +// PhysicalMemoryBytes returns the total amount of host memory. +func PhysicalMemoryBytes() (uint64, error) { + return 0, errors.New("not supported on GOOS=js") +} diff --git a/v3/internal/sysinfo/usage_js.go b/v3/internal/sysinfo/usage_js.go new file mode 100644 index 000000000..74f8ce160 --- /dev/null +++ b/v3/internal/sysinfo/usage_js.go @@ -0,0 +1,11 @@ +// Copyright 2020 New Relic Corporation. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package sysinfo + +import "errors" + +// GetUsage gathers process times. +func GetUsage() (Usage, error) { + return Usage{}, errors.New("not supported on GOOS=js") +} diff --git a/v3/internal/sysinfo/usage_posix.go b/v3/internal/sysinfo/usage_posix.go index 4d758dea1..5b553fd90 100644 --- a/v3/internal/sysinfo/usage_posix.go +++ b/v3/internal/sysinfo/usage_posix.go @@ -1,7 +1,7 @@ // Copyright 2020 New Relic Corporation. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -// +build !windows +// +build !windows,!js package sysinfo diff --git a/v3/newrelic/application.go b/v3/newrelic/application.go index d1ec4994c..06f3c6413 100644 --- a/v3/newrelic/application.go +++ b/v3/newrelic/application.go @@ -18,10 +18,14 @@ type Application struct { /* // IsAIMonitoringEnabled returns true if monitoring for the specified mode of the named integration is enabled. func (app *Application) IsAIMonitoringEnabled(integration string, streaming bool) bool { - if app == nil || app.app == nil || app.app.run == nil { + if app == nil || app.app == nil { + return false + } + run, _ := app.app.getState() + if run == nil { return false } - aiconf := app.app.run.Config.AIMonitoring + aiconf := run.Config.AIMonitoring if !aiconf.Enabled { return false } diff --git a/v3/newrelic/attributes.go b/v3/newrelic/attributes.go index 2fd2f8d09..a3770b47f 100644 --- a/v3/newrelic/attributes.go +++ b/v3/newrelic/attributes.go @@ -118,6 +118,15 @@ const ( // // It is recommended that at most one message is consumed per transaction. const ( + // The account ID of a cloud service provider + AttributeCloudAccountID = "cloud.account.id" + // The region of a cloud service provider + AttributeCloudRegion = "cloud.region" + // The name of the messaging system + AttributeMessageSystem = "messaging.system" + // The name of the messagine broker destination + AttributeMessageDestinationName = "message.destination.name" + // The routing key of the consumed message. AttributeMessageRoutingKey = "message.routingKey" // The name of the queue the message was consumed from. @@ -131,6 +140,18 @@ const ( AttributeMessageCorrelationID = "message.correlationId" // The headers of the message without CAT keys/values AttributeMessageHeaders = "message.headers" + // Host identifier of the message broker + AttributeServerAddress = "server.address" + // Port number of the message broker + AttributeServerPort = "server.port" + // Will take on either the values "producer" or "consumer" + AttributeSpanKind = "span.kind" +) + +// Experimental OTEL Attributes for consumed message transactions +const ( + AttributeMessagingDestinationPublishName = "messaging.destination_publish.name" + AttributeRabbitMQDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key" ) // Attributes destined for Span Events. These attributes appear only on Span diff --git a/v3/newrelic/attributes_from_internal.go b/v3/newrelic/attributes_from_internal.go index 430c5752a..eb1ef14b5 100644 --- a/v3/newrelic/attributes_from_internal.go +++ b/v3/newrelic/attributes_from_internal.go @@ -34,37 +34,45 @@ var ( // attributes.go and add its default destinations here. // agentAttributeDefaultDests = map[string]destinationSet{ - AttributeHostDisplayName: usualDests, - AttributeRequestMethod: usualDests, - AttributeRequestAccept: usualDests, - AttributeRequestContentType: usualDests, - AttributeRequestContentLength: usualDests, - AttributeRequestHost: usualDests, - AttributeRequestUserAgent: tracesDests, - AttributeRequestUserAgentDeprecated: tracesDests, - AttributeRequestReferer: tracesDests, - AttributeRequestURI: usualDests, - AttributeResponseContentType: usualDests, - AttributeResponseContentLength: usualDests, - AttributeResponseCode: usualDests, - AttributeResponseCodeDeprecated: usualDests, - AttributeAWSRequestID: usualDests, - AttributeAWSLambdaARN: usualDests, - AttributeAWSLambdaColdStart: usualDests, - AttributeAWSLambdaEventSourceARN: usualDests, - AttributeMessageRoutingKey: usualDests, - AttributeMessageQueueName: usualDests, - AttributeMessageHeaders: usualDests, - AttributeMessageExchangeType: destNone, - AttributeMessageReplyTo: destNone, - AttributeMessageCorrelationID: destNone, - AttributeCodeFunction: usualDests, - AttributeCodeNamespace: usualDests, - AttributeCodeFilepath: usualDests, - AttributeCodeLineno: usualDests, - AttributeUserID: usualDests, - AttributeLLM: usualDests, - + AttributeCloudAccountID: usualDests, + AttributeMessageDestinationName: usualDests, + AttributeCloudRegion: usualDests, + AttributeMessageSystem: usualDests, + AttributeHostDisplayName: usualDests, + AttributeRequestMethod: usualDests, + AttributeRequestAccept: usualDests, + AttributeRequestContentType: usualDests, + AttributeRequestContentLength: usualDests, + AttributeRequestHost: usualDests, + AttributeRequestUserAgent: tracesDests, + AttributeRequestUserAgentDeprecated: tracesDests, + AttributeRequestReferer: tracesDests, + AttributeRequestURI: usualDests, + AttributeResponseContentType: usualDests, + AttributeResponseContentLength: usualDests, + AttributeResponseCode: usualDests, + AttributeResponseCodeDeprecated: usualDests, + AttributeAWSRequestID: usualDests, + AttributeAWSLambdaARN: usualDests, + AttributeAWSLambdaColdStart: usualDests, + AttributeAWSLambdaEventSourceARN: usualDests, + AttributeMessageRoutingKey: usualDests, + AttributeMessageQueueName: usualDests, + AttributeMessageHeaders: usualDests, + AttributeMessageExchangeType: destNone, + AttributeMessageReplyTo: destNone, + AttributeMessageCorrelationID: destNone, + AttributeCodeFunction: usualDests, + AttributeCodeNamespace: usualDests, + AttributeCodeFilepath: usualDests, + AttributeCodeLineno: usualDests, + AttributeUserID: usualDests, + AttributeLLM: usualDests, + AttributeServerAddress: usualDests, + AttributeServerPort: usualDests, + AttributeSpanKind: usualDests, + AttributeMessagingDestinationPublishName: usualDests, + AttributeRabbitMQDestinationRoutingKey: usualDests, // Span specific attributes SpanAttributeDBStatement: usualDests, SpanAttributeDBInstance: usualDests, @@ -461,6 +469,12 @@ func writeAttributeValueJSON(w *jsonFieldsWriter, key string, val interface{}) { v = v[:maxAttributeLengthBytes] } w.stringField(key, v) + case error: + value := v.Error() + if len(value) > maxAttributeLengthBytes { + value = value[:maxAttributeLengthBytes] + } + w.stringField(key, value) case bool: if v { w.rawField(key, `true`) diff --git a/v3/newrelic/instrumentation.go b/v3/newrelic/instrumentation.go index efc84d22c..0540900d4 100644 --- a/v3/newrelic/instrumentation.go +++ b/v3/newrelic/instrumentation.go @@ -52,13 +52,16 @@ func WrapHandle(app *Application, pattern string, handler http.Handler, options var tOptions *traceOptSet var txnOptionList []TraceOption - if app.app != nil && app.app.run != nil && app.app.run.Config.CodeLevelMetrics.Enabled { - tOptions = resolveCLMTraceOptions(options) - if tOptions != nil && !tOptions.SuppressCLM && (tOptions.DemandCLM || app.app.run.Config.CodeLevelMetrics.Scope == 0 || (app.app.run.Config.CodeLevelMetrics.Scope&TransactionCLM) != 0) { - // we are for sure collecting CLM here, so go to the trouble of collecting this code location if nothing else has yet. - if tOptions.LocationOverride == nil { - if loc, err := cache.FunctionLocation(handler, handler.ServeHTTP); err == nil { - WithCodeLocation(loc)(tOptions) + if app.app != nil { + run, _ := app.app.getState() + if run != nil && run.Config.CodeLevelMetrics.Enabled { + tOptions = resolveCLMTraceOptions(options) + if tOptions != nil && !tOptions.SuppressCLM && (tOptions.DemandCLM || run.Config.CodeLevelMetrics.Scope == 0 || (run.Config.CodeLevelMetrics.Scope&TransactionCLM) != 0) { + // we are for sure collecting CLM here, so go to the trouble of collecting this code location if nothing else has yet. + if tOptions.LocationOverride == nil { + if loc, err := cache.FunctionLocation(handler, handler.ServeHTTP); err == nil { + WithCodeLocation(loc)(tOptions) + } } } } @@ -81,6 +84,9 @@ func WrapHandle(app *Application, pattern string, handler http.Handler, options r = RequestWithTransactionContext(r, txn) handler.ServeHTTP(w, r) + if IsSecurityAgentPresent() { + secureAgent.SendEvent("RESPONSE_HEADER", w.Header()) + } }) } @@ -96,13 +102,16 @@ func AddCodeLevelMetricsTraceOptions(app *Application, options []TraceOption, ca return options } - if app.app != nil && app.app.run != nil && app.app.run.Config.CodeLevelMetrics.Enabled { - tOptions = resolveCLMTraceOptions(options) - if tOptions != nil && !tOptions.SuppressCLM && (tOptions.DemandCLM || app.app.run.Config.CodeLevelMetrics.Scope == 0 || (app.app.run.Config.CodeLevelMetrics.Scope&TransactionCLM) != 0) { - // we are for sure collecting CLM here, so go to the trouble of collecting this code location if nothing else has yet. - if tOptions.LocationOverride == nil { - if loc, err := cache.FunctionLocation(cachedLocations); err == nil { - WithCodeLocation(loc)(tOptions) + if app.app != nil { + run, _ := app.app.getState() + if run != nil && run.Config.CodeLevelMetrics.Enabled { + tOptions = resolveCLMTraceOptions(options) + if tOptions != nil && !tOptions.SuppressCLM && (tOptions.DemandCLM || run.Config.CodeLevelMetrics.Scope == 0 || (run.Config.CodeLevelMetrics.Scope&TransactionCLM) != 0) { + // we are for sure collecting CLM here, so go to the trouble of collecting this code location if nothing else has yet. + if tOptions.LocationOverride == nil { + if loc, err := cache.FunctionLocation(cachedLocations); err == nil { + WithCodeLocation(loc)(tOptions) + } } } } diff --git a/v3/newrelic/internal_txn.go b/v3/newrelic/internal_txn.go index 32060485b..545083ca9 100644 --- a/v3/newrelic/internal_txn.go +++ b/v3/newrelic/internal_txn.go @@ -10,6 +10,7 @@ import ( "net/http" "net/url" "reflect" + "runtime" "runtime/debug" "sync" "time" @@ -445,11 +446,16 @@ func (thd *thread) End(recovered interface{}) error { txn.finished = true - if nil != recovered { - e := txnErrorFromPanic(time.Now(), recovered) - e.Stack = getStackTrace() - thd.noticeErrorInternal(e, nil, false) - log.Println(string(debug.Stack())) + // It used to be the case that panic(nil) would cause recover() to return nil, + // which we test for here. However, that is no longer the case, hence the extra + // check at this point to stop panic(nil) from propagating here. (as of Go 1.21) + if recovered != nil { + if _, isNilPanic := recovered.(*runtime.PanicNilError); !isNilPanic { + e := txnErrorFromPanic(time.Now(), recovered) + e.Stack = getStackTrace() + thd.noticeErrorInternal(e, nil, false) + log.Println(string(debug.Stack())) + } } txn.markEnd(time.Now(), thd.thread) @@ -542,9 +548,12 @@ func (thd *thread) End(recovered interface{}) error { } // Note that if a consumer uses `panic(nil)`, the panic will not - // propagate. - if nil != recovered { - panic(recovered) + // propagate. Update: well, not anymore. Go now returns an actual + // non-nil value in this case. + if recovered != nil { + if _, isNilPanic := recovered.(*runtime.PanicNilError); !isNilPanic { + panic(recovered) + } } return nil diff --git a/v3/newrelic/log_events_test.go b/v3/newrelic/log_events_test.go index e359ef55a..1c9a3abc5 100644 --- a/v3/newrelic/log_events_test.go +++ b/v3/newrelic/log_events_test.go @@ -4,6 +4,7 @@ package newrelic import ( + "errors" "fmt" "testing" "time" @@ -88,12 +89,13 @@ func TestBasicLogEventWithAttributes(t *testing.T) { C: c{"hello"}, } - events := newLogEvents(testCommonAttributes, loggingConfigEnabled(5)) + events := newLogEvents(testCommonAttributes, loggingConfigEnabled(6)) events.Add(sampleLogEvent(0.5, infoLevel, "message1", map[string]any{"two": "hi"})) events.Add(sampleLogEvent(0.5, infoLevel, "message2", map[string]any{"struct": st})) events.Add(sampleLogEvent(0.5, infoLevel, "message3", map[string]any{"map": map[string]string{"hi": "hello"}})) events.Add(sampleLogEvent(0.5, infoLevel, "message4", map[string]any{"slice": []string{"hi", "hello", "test"}})) events.Add(sampleLogEvent(0.5, infoLevel, "message5", map[string]any{"array": [2]int{1, 2}})) + events.Add(sampleLogEvent(0.5, infoLevel, "message6", map[string]any{"error": errors.New("test error")})) json, err := events.CollectorJSON(agentRunID) if nil != err { @@ -105,15 +107,16 @@ func TestBasicLogEventWithAttributes(t *testing.T) { `{"level":"INFO","message":"message2","timestamp":123456,"attributes":{"struct":"{\"A\":\"a\",\"B\":1,\"C\":{\"D\":\"hello\"}}"}},` + `{"level":"INFO","message":"message3","timestamp":123456,"attributes":{"map":"{\"hi\":\"hello\"}"}},` + `{"level":"INFO","message":"message4","timestamp":123456,"attributes":{"slice":"[\"hi\",\"hello\",\"test\"]"}},` + - `{"level":"INFO","message":"message5","timestamp":123456,"attributes":{"array":"[1,2]"}}]}]` + `{"level":"INFO","message":"message5","timestamp":123456,"attributes":{"array":"[1,2]"}},` + + `{"level":"INFO","message":"message6","timestamp":123456,"attributes":{"error":"test error"}}]}]` if string(json) != expected { t.Error("actual not equal to expected:\n", string(json), "\n", expected) } - if events.numSeen != 5 { + if events.numSeen != 6 { t.Error(events.numSeen) } - if events.NumSaved() != 5 { + if events.NumSaved() != 6 { t.Error(events.NumSaved()) } } diff --git a/v3/newrelic/secure_agent.go b/v3/newrelic/secure_agent.go index 40334a53d..86aa8390b 100644 --- a/v3/newrelic/secure_agent.go +++ b/v3/newrelic/secure_agent.go @@ -42,7 +42,8 @@ type securityAgent interface { func (app *Application) RegisterSecurityAgent(s securityAgent) { if app != nil && app.app != nil && s != nil { secureAgent = s - if app.app.run != nil { + run, _ := app.app.getState() + if run != nil { secureAgent.RefreshState(getLinkedMetaData(app.app)) } } diff --git a/v3/newrelic/utilities.go b/v3/newrelic/utilities.go index 9458110f8..69e776000 100644 --- a/v3/newrelic/utilities.go +++ b/v3/newrelic/utilities.go @@ -83,8 +83,8 @@ func stringLengthByteLimit(str string, byteLimit int) string { } func timeFromUnixMilliseconds(millis uint64) time.Time { - secs := int64(millis) / 1000 - msecsRemaining := int64(millis) % 1000 + secs := int64(millis / 1000) + msecsRemaining := int64(millis % 1000) nsecsRemaining := msecsRemaining * (1000 * 1000) return time.Unix(secs, nsecsRemaining) } diff --git a/v3/newrelic/version.go b/v3/newrelic/version.go index 9f569ad00..f3dfeb30d 100644 --- a/v3/newrelic/version.go +++ b/v3/newrelic/version.go @@ -11,7 +11,7 @@ import ( const ( // Version is the full string version of this Go Agent. - Version = "3.34.0" + Version = "3.35.0" ) var (