From a414d2f32c03e51310113253d42abc194dc3b12d Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Tue, 30 Jan 2024 13:40:18 -0500 Subject: [PATCH 1/6] protect trace observer from leaking license keys on error --- v3/newrelic/trace_observer.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/v3/newrelic/trace_observer.go b/v3/newrelic/trace_observer.go index 784dfa921..4274c05ed 100644 --- a/v3/newrelic/trace_observer.go +++ b/v3/newrelic/trace_observer.go @@ -1,7 +1,9 @@ // Copyright 2020 New Relic Corporation. All rights reserved. // SPDX-License-Identifier: Apache-2.0 +//go:build go1.9 // +build go1.9 + // This build tag is necessary because GRPC/ProtoBuf libraries only support Go version 1.9 and up. package newrelic @@ -184,10 +186,11 @@ func newDialOptions(cfg observerConfig) []grpc.DialOption { func (to *gRPCtraceObserver) connectToTraceObserver() { conn, err := grpc.Dial(to.endpoint.host, to.dialOptions...) if nil != err { + errMsg := strings.Replace(err.Error(), to.license, "--REDACTED_LICENSE_KEY--", -1) // this error is unrecoverable and will not be retried to.log.Error("trace observer unable to dial grpc endpoint", map[string]interface{}{ "host": to.endpoint.host, - "err": err.Error(), + "err": errMsg, }) return } From 2c9d56be746edb17841db92ba826cbb06a344d25 Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Tue, 6 Feb 2024 19:06:17 -0500 Subject: [PATCH 2/6] New Relic Slog Instrumentation Automatically configure slog to integrate with New Relic logs in context using this tooling. --- v3/integrations/logcontext-v2/nrslog/go.mod | 19 ++ .../logcontext-v2/nrslog/handler.go | 178 ++++++++++++++++++ .../logcontext-v2/nrslog/handler_test.go | 158 ++++++++++++++++ .../logcontext-v2/nrslog/writer.go | 82 ++++++++ 4 files changed, 437 insertions(+) create mode 100644 v3/integrations/logcontext-v2/nrslog/go.mod create mode 100644 v3/integrations/logcontext-v2/nrslog/handler.go create mode 100644 v3/integrations/logcontext-v2/nrslog/handler_test.go create mode 100644 v3/integrations/logcontext-v2/nrslog/writer.go diff --git a/v3/integrations/logcontext-v2/nrslog/go.mod b/v3/integrations/logcontext-v2/nrslog/go.mod new file mode 100644 index 000000000..b129f04a6 --- /dev/null +++ b/v3/integrations/logcontext-v2/nrslog/go.mod @@ -0,0 +1,19 @@ +module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog + +go 1.21.6 + +require ( + github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter v1.0.1 +) + +require ( + github.com/golang/protobuf v1.5.3 // indirect + github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.56.3 // indirect + google.golang.org/protobuf v1.30.0 // indirect +) diff --git a/v3/integrations/logcontext-v2/nrslog/handler.go b/v3/integrations/logcontext-v2/nrslog/handler.go new file mode 100644 index 000000000..5b8b58146 --- /dev/null +++ b/v3/integrations/logcontext-v2/nrslog/handler.go @@ -0,0 +1,178 @@ +package nrslog + +import ( + "context" + "io" + "log/slog" + + "github.com/newrelic/go-agent/v3/newrelic" +) + +type NRHandler struct { + handler slog.Handler + w *LogWriter + app *newrelic.Application + txn *newrelic.Transaction +} + +// TextHandler creates a wrapped slog TextHandler, enabling it to both automatically capture logs +// and to enrich logs locally depending on your logs in context configuration in your New Relic +// application. +func TextHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptions) NRHandler { + nrWriter := NewWriter(w, app) + textHandler := slog.NewTextHandler(nrWriter, opts) + wrappedHandler := WrapHandler(app, textHandler) + wrappedHandler.addWriter(&nrWriter) + return wrappedHandler +} + +// JSONHandler creates a wrapped slog JSONHandler, enabling it to both automatically capture logs +// and to enrich logs locally depending on your logs in context configuration in your New Relic +// application. +func JSONHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptions) NRHandler { + nrWriter := NewWriter(w, app) + jsonHandler := slog.NewJSONHandler(nrWriter, opts) + wrappedHandler := WrapHandler(app, jsonHandler) + wrappedHandler.addWriter(&nrWriter) + return wrappedHandler +} + +// WithTransaction creates a new slog Logger object to be used for logging within a given transaction. +func WithTransaction(txn *newrelic.Transaction, logger *slog.Logger) *slog.Logger { + if txn == nil { + return logger + } + + h := logger.Handler() + switch nrHandler := h.(type) { + case NRHandler: + txnHandler := nrHandler.WithTransaction(txn) + return slog.New(txnHandler) + default: + return logger + } +} + +// WithTransaction creates a new slog Logger object to be used for logging within a given transaction it its found +// in a context. +func WithContext(ctx context.Context, logger *slog.Logger) *slog.Logger { + if ctx == nil { + return logger + } + + txn := newrelic.FromContext(ctx) + return WithTransaction(txn, logger) +} + +// WrapHandler returns a new handler that is wrapped with New Relic tools to capture +// log data based on your application's logs in context settings. +func WrapHandler(app *newrelic.Application, handler slog.Handler) NRHandler { + return NRHandler{ + handler: handler, + app: app, + } +} + +func (h *NRHandler) addWriter(w *LogWriter) { + h.w = w +} + +// WithTransaction returns a new handler that is configured to capture log data +// and attribute it to a specific transaction. +func (h NRHandler) WithTransaction(txn *newrelic.Transaction) NRHandler { + handler := NRHandler{ + handler: h.handler, + app: h.app, + txn: txn, + } + + writer := h.w.WithTransaction(txn) + handler.addWriter(&writer) + return handler +} + +// Enabled reports whether the handler handles records at the given level. +// The handler ignores records whose level is lower. +// It is called early, before any arguments are processed, +// to save effort if the log event should be discarded. +// If called from a Logger method, the first argument is the context +// passed to that method, or context.Background() if nil was passed +// or the method does not take a context. +// The context is passed so Enabled can use its values +// to make a decision. +func (h NRHandler) Enabled(ctx context.Context, lvl slog.Level) bool { + return h.handler.Enabled(ctx, lvl) +} + +// Handle handles the Record. +// It will only be called when Enabled returns true. +// The Context argument is as for Enabled. +// It is present solely to provide Handlers access to the context's values. +// Canceling the context should not affect record processing. +// (Among other things, log messages may be necessary to debug a +// cancellation-related problem.) +// +// Handle methods that produce output should observe the following rules: +// - If r.Time is the zero time, ignore the time. +// - If r.PC is zero, ignore it. +// - Attr's values should be resolved. +// - If an Attr's key and value are both the zero value, ignore the Attr. +// This can be tested with attr.Equal(Attr{}). +// - If a group's key is empty, inline the group's Attrs. +// - If a group has no Attrs (even if it has a non-empty key), +// ignore it. +func (h NRHandler) Handle(ctx context.Context, record slog.Record) error { + data := newrelic.LogData{ + Severity: record.Level.String(), + Timestamp: record.Time.UnixMilli(), + Message: record.Message, + } + if h.txn != nil { + h.txn.RecordLog(data) + } else { + h.app.RecordLog(data) + } + + return h.handler.Handle(ctx, record) +} + +// WithAttrs returns a new Handler whose attributes consist of +// both the receiver's attributes and the arguments. +// The Handler owns the slice: it may retain, modify or discard it. +func (h NRHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + handler := h.handler.WithAttrs(attrs) + return NRHandler{ + handler: handler, + app: h.app, + txn: h.txn, + } + +} + +// WithGroup returns a new Handler with the given group appended to +// the receiver's existing groups. +// The keys of all subsequent attributes, whether added by With or in a +// Record, should be qualified by the sequence of group names. +// +// How this qualification happens is up to the Handler, so long as +// this Handler's attribute keys differ from those of another Handler +// with a different sequence of group names. +// +// A Handler should treat WithGroup as starting a Group of Attrs that ends +// at the end of the log event. That is, +// +// logger.WithGroup("s").LogAttrs(level, msg, slog.Int("a", 1), slog.Int("b", 2)) +// +// should behave like +// +// logger.LogAttrs(level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2))) +// +// If the name is empty, WithGroup returns the receiver. +func (h NRHandler) WithGroup(name string) slog.Handler { + handler := h.handler.WithGroup(name) + return NRHandler{ + handler: handler, + app: h.app, + txn: h.txn, + } +} diff --git a/v3/integrations/logcontext-v2/nrslog/handler_test.go b/v3/integrations/logcontext-v2/nrslog/handler_test.go new file mode 100644 index 000000000..55f8e0ba2 --- /dev/null +++ b/v3/integrations/logcontext-v2/nrslog/handler_test.go @@ -0,0 +1,158 @@ +package nrslog + +import ( + "bytes" + "log/slog" + "testing" + + "github.com/newrelic/go-agent/v3/internal" + "github.com/newrelic/go-agent/v3/internal/integrationsupport" + "github.com/newrelic/go-agent/v3/internal/logcontext" + "github.com/newrelic/go-agent/v3/internal/sysinfo" + "github.com/newrelic/go-agent/v3/newrelic" +) + +var ( + host, _ = sysinfo.Hostname() +) + +func TestHandler(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(true), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + out := bytes.NewBuffer([]byte{}) + handler := TextHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + message := "Hello World!" + log.Info(message) + logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ + EntityGUID: integrationsupport.TestEntityGUID, + Hostname: host, + EntityName: integrationsupport.SampleAppName, + }) + app.ExpectLogEvents(t, []internal.WantLog{ + { + Severity: slog.LevelInfo.String(), + Message: message, + Timestamp: internal.MatchAnyUnixMilli, + }, + }) +} + +func TestJSONHandler(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(true), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + out := bytes.NewBuffer([]byte{}) + handler := JSONHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + message := "Hello World!" + log.Info(message) + logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ + EntityGUID: integrationsupport.TestEntityGUID, + Hostname: host, + EntityName: integrationsupport.SampleAppName, + }) + app.ExpectLogEvents(t, []internal.WantLog{ + { + Severity: slog.LevelInfo.String(), + Message: message, + Timestamp: internal.MatchAnyUnixMilli, + }, + }) +} + +func TestHandlerTransactions(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(true), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + + out := bytes.NewBuffer([]byte{}) + message := "Hello World!" + + handler := TextHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + + txn := app.Application.StartTransaction("my txn") + txninfo := txn.GetLinkingMetadata() + + txnLogger := WithTransaction(txn, log) + txnLogger.Info(message) + + backgroundMsg := "this is a background message" + log.Debug(backgroundMsg) + txn.End() + + /* + logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ + EntityGUID: integrationsupport.TestEntityGUID, + Hostname: host, + EntityName: integrationsupport.SampleAppName, + }) */ + + app.ExpectLogEvents(t, []internal.WantLog{ + { + Severity: slog.LevelInfo.String(), + Message: message, + Timestamp: internal.MatchAnyUnixMilli, + SpanID: txninfo.SpanID, + TraceID: txninfo.TraceID, + }, + }) +} + +func TestHandlerTransactionsAndBackground(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(true), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + + out := bytes.NewBuffer([]byte{}) + message := "Hello World!" + messageTxn := "Hello Transaction!" + messageBackground := "Hello Background!" + + handler := TextHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + + log.Info(message) + + txn := app.Application.StartTransaction("my txn") + txninfo := txn.GetLinkingMetadata() + + txnLogger := WithTransaction(txn, log) + txnLogger.Info(messageTxn) + + log.Warn(messageBackground) + txn.End() + + /* + logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ + EntityGUID: integrationsupport.TestEntityGUID, + Hostname: host, + EntityName: integrationsupport.SampleAppName, + }) */ + + app.ExpectLogEvents(t, []internal.WantLog{ + { + Severity: slog.LevelInfo.String(), + Message: message, + Timestamp: internal.MatchAnyUnixMilli, + }, + { + Severity: slog.LevelWarn.String(), + Message: messageBackground, + Timestamp: internal.MatchAnyUnixMilli, + }, + { + Severity: slog.LevelInfo.String(), + Message: messageTxn, + Timestamp: internal.MatchAnyUnixMilli, + SpanID: txninfo.SpanID, + TraceID: txninfo.TraceID, + }, + }) +} diff --git a/v3/integrations/logcontext-v2/nrslog/writer.go b/v3/integrations/logcontext-v2/nrslog/writer.go new file mode 100644 index 000000000..879eb30fe --- /dev/null +++ b/v3/integrations/logcontext-v2/nrslog/writer.go @@ -0,0 +1,82 @@ +package nrslog + +import ( + "bytes" + "context" + "io" + + "github.com/newrelic/go-agent/v3/newrelic" +) + +// LogWriter is an io.Writer that captures log data for use with New Relic Logs in Context +type LogWriter struct { + debug bool + out io.Writer + app *newrelic.Application + txn *newrelic.Transaction +} + +// New creates a new NewRelicWriter Object +// output is the io.Writer destination that you want your log to be written to +// app must be a vaild, non nil new relic Application +func NewWriter(output io.Writer, app *newrelic.Application) LogWriter { + return LogWriter{ + out: output, + app: app, + } +} + +// DebugLogging enables or disables debug error messages being written in the IO output. +// By default, the nrwriter debug logging is set to false and will fail silently +func (b *LogWriter) DebugLogging(enabled bool) { + b.debug = enabled +} + +// WithTransaction duplicates the current NewRelicWriter and sets the transaction to txn +func (b *LogWriter) WithTransaction(txn *newrelic.Transaction) LogWriter { + return LogWriter{ + out: b.out, + app: b.app, + debug: b.debug, + txn: txn, + } +} + +// WithTransaction duplicates the current NewRelicWriter and sets the transaction to the transaction parsed from ctx +func (b *LogWriter) WithContext(ctx context.Context) LogWriter { + txn := newrelic.FromContext(ctx) + return LogWriter{ + out: b.out, + app: b.app, + debug: b.debug, + txn: txn, + } +} + +// EnrichLog attempts to enrich a log with New Relic linking metadata. If it fails, +// it will return the original log line unless debug=true, otherwise it will print +// an error on a following line. +func (b *LogWriter) EnrichLog(p []byte) []byte { + logLine := bytes.TrimRight(p, "\n") + buf := bytes.NewBuffer(logLine) + + var enrichErr error + if b.txn != nil { + enrichErr = newrelic.EnrichLog(buf, newrelic.FromTxn(b.txn)) + } else { + enrichErr = newrelic.EnrichLog(buf, newrelic.FromApp(b.app)) + } + + if b.debug && enrichErr != nil { + buf.WriteString("\n") + buf.WriteString(enrichErr.Error()) + } + + buf.WriteString("\n") + return buf.Bytes() +} + +// Write implements io.Write +func (b LogWriter) Write(p []byte) (n int, err error) { + return b.out.Write(b.EnrichLog(p)) +} From 72dd1ca2c80a74a4cb6d106c43d92c257aae5473 Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Wed, 7 Feb 2024 11:36:22 -0500 Subject: [PATCH 3/6] nrslog cleanup and prep for release --- .../logcontext-v2/nrslog/example/main.go | 38 +++++++++++++++++ v3/integrations/logcontext-v2/nrslog/go.mod | 17 +------- .../logcontext-v2/nrslog/handler.go | 12 +++--- .../logcontext-v2/nrslog/handler_test.go | 42 +++++++++++++++++++ 4 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 v3/integrations/logcontext-v2/nrslog/example/main.go diff --git a/v3/integrations/logcontext-v2/nrslog/example/main.go b/v3/integrations/logcontext-v2/nrslog/example/main.go new file mode 100644 index 000000000..57a7d11d1 --- /dev/null +++ b/v3/integrations/logcontext-v2/nrslog/example/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "log/slog" + "os" + "time" + + "github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog" + "github.com/newrelic/go-agent/v3/newrelic" +) + +func main() { + app, err := newrelic.NewApplication( + newrelic.ConfigFromEnvironment(), + newrelic.ConfigAppLogEnabled(true), + ) + if err != nil { + panic(err) + } + + app.WaitForConnection(time.Second * 5) + log := slog.New(nrslog.TextHandler(app, os.Stdout, &slog.HandlerOptions{})) + + log.Info("I am a log message") + + txn := app.StartTransaction("example transaction") + txnLogger := nrslog.WithTransaction(txn, log) + txnLogger.Info("I am a log inside a transaction") + + // pretend to do some work + time.Sleep(500 * time.Millisecond) + txnLogger.Warn("Uh oh, something important happened!") + txn.End() + + log.Info("All Done!") + + app.Shutdown(time.Second * 10) +} diff --git a/v3/integrations/logcontext-v2/nrslog/go.mod b/v3/integrations/logcontext-v2/nrslog/go.mod index b129f04a6..202319dcb 100644 --- a/v3/integrations/logcontext-v2/nrslog/go.mod +++ b/v3/integrations/logcontext-v2/nrslog/go.mod @@ -1,19 +1,6 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog -go 1.21.6 +go 1.21 -require ( - github.com/newrelic/go-agent/v3 v3.29.1 - github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter v1.0.1 -) +require github.com/newrelic/go-agent/v3 v3.30.0 -require ( - github.com/golang/protobuf v1.5.3 // indirect - github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.56.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect -) diff --git a/v3/integrations/logcontext-v2/nrslog/handler.go b/v3/integrations/logcontext-v2/nrslog/handler.go index 5b8b58146..df55abb35 100644 --- a/v3/integrations/logcontext-v2/nrslog/handler.go +++ b/v3/integrations/logcontext-v2/nrslog/handler.go @@ -8,6 +8,7 @@ import ( "github.com/newrelic/go-agent/v3/newrelic" ) +// NRHandler is an Slog handler that includes logic to implement New Relic Logs in Context type NRHandler struct { handler slog.Handler w *LogWriter @@ -15,7 +16,7 @@ type NRHandler struct { txn *newrelic.Transaction } -// TextHandler creates a wrapped slog TextHandler, enabling it to both automatically capture logs +// TextHandler creates a wrapped Slog TextHandler, enabling it to both automatically capture logs // and to enrich logs locally depending on your logs in context configuration in your New Relic // application. func TextHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptions) NRHandler { @@ -26,7 +27,7 @@ func TextHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptio return wrappedHandler } -// JSONHandler creates a wrapped slog JSONHandler, enabling it to both automatically capture logs +// JSONHandler creates a wrapped Slog JSONHandler, enabling it to both automatically capture logs // and to enrich logs locally depending on your logs in context configuration in your New Relic // application. func JSONHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptions) NRHandler { @@ -37,7 +38,7 @@ func JSONHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptio return wrappedHandler } -// WithTransaction creates a new slog Logger object to be used for logging within a given transaction. +// WithTransaction creates a new Slog Logger object to be used for logging within a given transaction. func WithTransaction(txn *newrelic.Transaction, logger *slog.Logger) *slog.Logger { if txn == nil { return logger @@ -53,7 +54,7 @@ func WithTransaction(txn *newrelic.Transaction, logger *slog.Logger) *slog.Logge } } -// WithTransaction creates a new slog Logger object to be used for logging within a given transaction it its found +// WithTransaction creates a new Slog Logger object to be used for logging within a given transaction it its found // in a context. func WithContext(ctx context.Context, logger *slog.Logger) *slog.Logger { if ctx == nil { @@ -73,13 +74,14 @@ func WrapHandler(app *newrelic.Application, handler slog.Handler) NRHandler { } } +// addWriter is an internal helper function to append an io.Writer to the NRHandler object func (h *NRHandler) addWriter(w *LogWriter) { h.w = w } // WithTransaction returns a new handler that is configured to capture log data // and attribute it to a specific transaction. -func (h NRHandler) WithTransaction(txn *newrelic.Transaction) NRHandler { +func (h *NRHandler) WithTransaction(txn *newrelic.Transaction) NRHandler { handler := NRHandler{ handler: h.handler, app: h.app, diff --git a/v3/integrations/logcontext-v2/nrslog/handler_test.go b/v3/integrations/logcontext-v2/nrslog/handler_test.go index 55f8e0ba2..ec9c7f2ad 100644 --- a/v3/integrations/logcontext-v2/nrslog/handler_test.go +++ b/v3/integrations/logcontext-v2/nrslog/handler_test.go @@ -2,6 +2,7 @@ package nrslog import ( "bytes" + "context" "log/slog" "testing" @@ -104,6 +105,47 @@ func TestHandlerTransactions(t *testing.T) { }) } +func TestHandlerTransactionCtx(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(true), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + + out := bytes.NewBuffer([]byte{}) + message := "Hello World!" + + handler := TextHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + + txn := app.Application.StartTransaction("my txn") + ctx := newrelic.NewContext(context.Background(), txn) + txninfo := txn.GetLinkingMetadata() + + txnLogger := WithContext(ctx, log) + txnLogger.Info(message) + + backgroundMsg := "this is a background message" + log.Debug(backgroundMsg) + txn.End() + + /* + logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ + EntityGUID: integrationsupport.TestEntityGUID, + Hostname: host, + EntityName: integrationsupport.SampleAppName, + }) */ + + app.ExpectLogEvents(t, []internal.WantLog{ + { + Severity: slog.LevelInfo.String(), + Message: message, + Timestamp: internal.MatchAnyUnixMilli, + SpanID: txninfo.SpanID, + TraceID: txninfo.TraceID, + }, + }) +} + func TestHandlerTransactionsAndBackground(t *testing.T) { app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, newrelic.ConfigAppLogDecoratingEnabled(true), From 55a5c6b5863d4dd55226d9165ab696d9981d3092 Mon Sep 17 00:00:00 2001 From: Emilio Garcia Date: Wed, 14 Feb 2024 14:05:23 -0500 Subject: [PATCH 4/6] bug fix for nil io.Writer bug and new test coverage --- .../logcontext-v2/nrslog/handler.go | 9 +- .../logcontext-v2/nrslog/handler_test.go | 86 ++++++++++++++++--- .../logcontext-v2/nrslog/writer.go | 12 --- 3 files changed, 79 insertions(+), 28 deletions(-) diff --git a/v3/integrations/logcontext-v2/nrslog/handler.go b/v3/integrations/logcontext-v2/nrslog/handler.go index df55abb35..551e32b0c 100644 --- a/v3/integrations/logcontext-v2/nrslog/handler.go +++ b/v3/integrations/logcontext-v2/nrslog/handler.go @@ -40,7 +40,7 @@ func JSONHandler(app *newrelic.Application, w io.Writer, opts *slog.HandlerOptio // WithTransaction creates a new Slog Logger object to be used for logging within a given transaction. func WithTransaction(txn *newrelic.Transaction, logger *slog.Logger) *slog.Logger { - if txn == nil { + if txn == nil || logger == nil { return logger } @@ -88,8 +88,11 @@ func (h *NRHandler) WithTransaction(txn *newrelic.Transaction) NRHandler { txn: txn, } - writer := h.w.WithTransaction(txn) - handler.addWriter(&writer) + if h.w != nil { + writer := h.w.WithTransaction(txn) + handler.addWriter(&writer) + } + return handler } diff --git a/v3/integrations/logcontext-v2/nrslog/handler_test.go b/v3/integrations/logcontext-v2/nrslog/handler_test.go index ec9c7f2ad..503fec909 100644 --- a/v3/integrations/logcontext-v2/nrslog/handler_test.go +++ b/v3/integrations/logcontext-v2/nrslog/handler_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "log/slog" + "strings" "testing" "github.com/newrelic/go-agent/v3/internal" @@ -128,12 +129,11 @@ func TestHandlerTransactionCtx(t *testing.T) { log.Debug(backgroundMsg) txn.End() - /* - logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ - EntityGUID: integrationsupport.TestEntityGUID, - Hostname: host, - EntityName: integrationsupport.SampleAppName, - }) */ + logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ + EntityGUID: integrationsupport.TestEntityGUID, + Hostname: host, + EntityName: integrationsupport.SampleAppName, + }) app.ExpectLogEvents(t, []internal.WantLog{ { @@ -171,13 +171,6 @@ func TestHandlerTransactionsAndBackground(t *testing.T) { log.Warn(messageBackground) txn.End() - /* - logcontext.ValidateDecoratedOutput(t, out, &logcontext.DecorationExpect{ - EntityGUID: integrationsupport.TestEntityGUID, - Hostname: host, - EntityName: integrationsupport.SampleAppName, - }) */ - app.ExpectLogEvents(t, []internal.WantLog{ { Severity: slog.LevelInfo.String(), @@ -198,3 +191,70 @@ func TestHandlerTransactionsAndBackground(t *testing.T) { }, }) } + +func TestWithAttributes(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(false), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + out := bytes.NewBuffer([]byte{}) + handler := TextHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + message := "Hello World!" + log = log.With(slog.String("string key", "val"), slog.Int("int key", 1)) + + log.Info(message) + + log1 := string(out.String()) + + txn := app.StartTransaction("hi") + txnLog := WithTransaction(txn, log) + txnLog.Info(message) + txn.End() + + log2 := string(out.String()) + + attrString := `"string key"=val "int key"=1` + if !strings.Contains(log1, attrString) { + t.Errorf("expected %s to contain %s", log1, attrString) + } + + if !strings.Contains(log2, attrString) { + t.Errorf("expected %s to contain %s", log2, attrString) + } + +} + +func TestWithGroup(t *testing.T) { + app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn, + newrelic.ConfigAppLogDecoratingEnabled(false), + newrelic.ConfigAppLogForwardingEnabled(true), + ) + out := bytes.NewBuffer([]byte{}) + handler := TextHandler(app.Application, out, &slog.HandlerOptions{}) + log := slog.New(handler) + message := "Hello World!" + log = log.With(slog.Group("test group", slog.String("string key", "val"))) + log = log.WithGroup("test group") + + log.Info(message) + + log1 := string(out.String()) + + txn := app.StartTransaction("hi") + txnLog := WithTransaction(txn, log) + txnLog.Info(message) + txn.End() + + log2 := string(out.String()) + + attrString := `"test group.string key"=val` + if !strings.Contains(log1, attrString) { + t.Errorf("expected %s to contain %s", log1, attrString) + } + + if !strings.Contains(log2, attrString) { + t.Errorf("expected %s to contain %s", log2, attrString) + } + +} diff --git a/v3/integrations/logcontext-v2/nrslog/writer.go b/v3/integrations/logcontext-v2/nrslog/writer.go index 879eb30fe..4248469a4 100644 --- a/v3/integrations/logcontext-v2/nrslog/writer.go +++ b/v3/integrations/logcontext-v2/nrslog/writer.go @@ -2,7 +2,6 @@ package nrslog import ( "bytes" - "context" "io" "github.com/newrelic/go-agent/v3/newrelic" @@ -42,17 +41,6 @@ func (b *LogWriter) WithTransaction(txn *newrelic.Transaction) LogWriter { } } -// WithTransaction duplicates the current NewRelicWriter and sets the transaction to the transaction parsed from ctx -func (b *LogWriter) WithContext(ctx context.Context) LogWriter { - txn := newrelic.FromContext(ctx) - return LogWriter{ - out: b.out, - app: b.app, - debug: b.debug, - txn: txn, - } -} - // EnrichLog attempts to enrich a log with New Relic linking metadata. If it fails, // it will return the original log line unless debug=true, otherwise it will print // an error on a following line. From 1cc8804a11cac77effefef3f574b28d85320fbe7 Mon Sep 17 00:00:00 2001 From: Steve Willoughby Date: Thu, 15 Feb 2024 11:04:44 -0800 Subject: [PATCH 5/6] update dependency on csec --- v3/integrations/nrsecurityagent/go.mod | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/v3/integrations/nrsecurityagent/go.mod b/v3/integrations/nrsecurityagent/go.mod index 9e268821e..4fa48417e 100644 --- a/v3/integrations/nrsecurityagent/go.mod +++ b/v3/integrations/nrsecurityagent/go.mod @@ -3,11 +3,10 @@ module github.com/newrelic/go-agent/v3/integrations/nrsecurityagent go 1.19 require ( - github.com/newrelic/csec-go-agent v0.7.0 + github.com/newrelic/csec-go-agent v1.0.0 github.com/newrelic/go-agent/v3 v3.29.1 github.com/newrelic/go-agent/v3/integrations/nrsqlite3 v1.2.0 gopkg.in/yaml.v2 v2.4.0 ) - replace github.com/newrelic/go-agent/v3 => ../.. From 9d60fd7e043c3c7042fdb05bc3522ad20b272188 Mon Sep 17 00:00:00 2001 From: Steve Willoughby Date: Thu, 15 Feb 2024 11:35:06 -0800 Subject: [PATCH 6/6] release 3.30.0 --- CHANGELOG.md | 12 ++++++++++++ v3/integrations/logcontext-v2/logWriter/go.mod | 2 +- v3/integrations/logcontext-v2/nrlogrus/go.mod | 2 +- v3/integrations/logcontext-v2/nrslog/go.mod | 3 ++- v3/integrations/logcontext-v2/nrwriter/go.mod | 2 +- v3/integrations/logcontext-v2/nrzap/go.mod | 2 +- v3/integrations/logcontext-v2/nrzerolog/go.mod | 2 +- v3/integrations/logcontext-v2/zerologWriter/go.mod | 2 +- v3/integrations/logcontext/nrlogrusplugin/go.mod | 2 +- v3/integrations/nramqp/go.mod | 2 +- v3/integrations/nrawssdk-v1/go.mod | 2 +- v3/integrations/nrawssdk-v2/go.mod | 2 +- v3/integrations/nrb3/go.mod | 2 +- v3/integrations/nrecho-v3/go.mod | 2 +- v3/integrations/nrecho-v4/go.mod | 2 +- v3/integrations/nrelasticsearch-v7/go.mod | 2 +- .../nrfasthttp/examples/client-fasthttp/go.mod | 2 +- .../nrfasthttp/examples/server-fasthttp/go.mod | 2 +- v3/integrations/nrfasthttp/go.mod | 4 +++- v3/integrations/nrgin/go.mod | 2 +- v3/integrations/nrgorilla/go.mod | 2 +- v3/integrations/nrgraphgophers/go.mod | 2 +- v3/integrations/nrgraphqlgo/example/go.mod | 2 +- v3/integrations/nrgraphqlgo/go.mod | 2 +- v3/integrations/nrgrpc/go.mod | 2 +- v3/integrations/nrhttprouter/go.mod | 2 +- v3/integrations/nrlambda/go.mod | 2 +- v3/integrations/nrlogrus/go.mod | 2 +- v3/integrations/nrlogxi/go.mod | 2 +- v3/integrations/nrmicro/go.mod | 2 +- v3/integrations/nrmongo/go.mod | 2 +- v3/integrations/nrmssql/go.mod | 2 +- v3/integrations/nrmysql/go.mod | 2 +- v3/integrations/nrnats/go.mod | 2 +- v3/integrations/nrnats/test/go.mod | 2 +- v3/integrations/nrpgx/example/sqlx/go.mod | 2 +- v3/integrations/nrpgx/go.mod | 2 +- v3/integrations/nrpgx5/go.mod | 2 +- v3/integrations/nrpkgerrors/go.mod | 2 +- v3/integrations/nrpq/example/sqlx/go.mod | 2 +- v3/integrations/nrpq/go.mod | 2 +- v3/integrations/nrredis-v7/go.mod | 2 +- v3/integrations/nrredis-v8/go.mod | 2 +- v3/integrations/nrredis-v9/go.mod | 2 +- v3/integrations/nrsarama/go.mod | 2 +- v3/integrations/nrsecurityagent/go.mod | 3 ++- v3/integrations/nrsnowflake/go.mod | 2 +- v3/integrations/nrsqlite3/go.mod | 2 +- v3/integrations/nrstan/examples/go.mod | 2 +- v3/integrations/nrstan/go.mod | 2 +- v3/integrations/nrstan/test/go.mod | 2 +- v3/integrations/nrzap/go.mod | 2 +- v3/newrelic/version.go | 2 +- 53 files changed, 68 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98dc20e43..740cafe07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 3.30.0 +### Added + * Updated the depencency on nrsecurityagent to 1.0.0. + * Added new integration, logcontext-v2/nrslog, which instruments logging via the new slog library. + +### Fixed + * Redacts license keys from error reporting. + +### 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.29.1 ### Added * Added Dockerized Unit Tests for Github Actions (internal build support) diff --git a/v3/integrations/logcontext-v2/logWriter/go.mod b/v3/integrations/logcontext-v2/logWriter/go.mod index 191b48fcb..ee0a9d49a 100644 --- a/v3/integrations/logcontext-v2/logWriter/go.mod +++ b/v3/integrations/logcontext-v2/logWriter/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 65afaa5cc..98ed0571f 100644 --- a/v3/integrations/logcontext-v2/nrlogrus/go.mod +++ b/v3/integrations/logcontext-v2/nrlogrus/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrlogrus go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 202319dcb..c88288932 100644 --- a/v3/integrations/logcontext-v2/nrslog/go.mod +++ b/v3/integrations/logcontext-v2/nrslog/go.mod @@ -1,6 +1,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog -go 1.21 +go 1.19 require github.com/newrelic/go-agent/v3 v3.30.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 6ebdbf5ae..ddaa12e0b 100644 --- a/v3/integrations/logcontext-v2/nrwriter/go.mod +++ b/v3/integrations/logcontext-v2/nrwriter/go.mod @@ -2,7 +2,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter go 1.19 -require github.com/newrelic/go-agent/v3 v3.29.1 +require github.com/newrelic/go-agent/v3 v3.30.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 30bf65bd6..745aba1fb 100644 --- a/v3/integrations/logcontext-v2/nrzap/go.mod +++ b/v3/integrations/logcontext-v2/nrzap/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzap go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 b218b34bb..87e64586c 100644 --- a/v3/integrations/logcontext-v2/nrzerolog/go.mod +++ b/v3/integrations/logcontext-v2/nrzerolog/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzerolog go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 a971ac52f..dab236cba 100644 --- a/v3/integrations/logcontext-v2/zerologWriter/go.mod +++ b/v3/integrations/logcontext-v2/zerologWriter/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/zerologWriter go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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/nrlogrusplugin/go.mod b/v3/integrations/logcontext/nrlogrusplugin/go.mod index 7fe08fead..443798ee8 100644 --- a/v3/integrations/logcontext/nrlogrusplugin/go.mod +++ b/v3/integrations/logcontext/nrlogrusplugin/go.mod @@ -5,7 +5,7 @@ module github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 // v1.4.0 is required for for the log.WithContext. github.com/sirupsen/logrus v1.4.0 ) diff --git a/v3/integrations/nramqp/go.mod b/v3/integrations/nramqp/go.mod index a7aaf24c1..260518338 100644 --- a/v3/integrations/nramqp/go.mod +++ b/v3/integrations/nramqp/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/nramqp go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/rabbitmq/amqp091-go v1.9.0 ) replace github.com/newrelic/go-agent/v3 => ../.. diff --git a/v3/integrations/nrawssdk-v1/go.mod b/v3/integrations/nrawssdk-v1/go.mod index c246c15a8..4837d9ab6 100644 --- a/v3/integrations/nrawssdk-v1/go.mod +++ b/v3/integrations/nrawssdk-v1/go.mod @@ -8,7 +8,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrawssdk-v2/go.mod b/v3/integrations/nrawssdk-v2/go.mod index 14b47fe13..1597772e1 100644 --- a/v3/integrations/nrawssdk-v2/go.mod +++ b/v3/integrations/nrawssdk-v2/go.mod @@ -11,7 +11,7 @@ require ( 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrb3/go.mod b/v3/integrations/nrb3/go.mod index 979ffa3de..3c15e47e2 100644 --- a/v3/integrations/nrb3/go.mod +++ b/v3/integrations/nrb3/go.mod @@ -2,7 +2,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrb3 go 1.19 -require github.com/newrelic/go-agent/v3 v3.29.1 +require github.com/newrelic/go-agent/v3 v3.30.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 a5ee47299..d8758722d 100644 --- a/v3/integrations/nrecho-v3/go.mod +++ b/v3/integrations/nrecho-v3/go.mod @@ -8,7 +8,7 @@ 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrecho-v4/go.mod b/v3/integrations/nrecho-v4/go.mod index 4388509cd..176fdbc3e 100644 --- a/v3/integrations/nrecho-v4/go.mod +++ b/v3/integrations/nrecho-v4/go.mod @@ -6,7 +6,7 @@ go 1.19 require ( github.com/labstack/echo/v4 v4.9.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrelasticsearch-v7/go.mod b/v3/integrations/nrelasticsearch-v7/go.mod index 058260767..7db1722de 100644 --- a/v3/integrations/nrelasticsearch-v7/go.mod +++ b/v3/integrations/nrelasticsearch-v7/go.mod @@ -6,7 +6,7 @@ go 1.19 require ( github.com/elastic/go-elasticsearch/v7 v7.17.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod b/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod index 5addc7cff..a99a17b73 100644 --- a/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod +++ b/v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod @@ -3,7 +3,7 @@ module client-example go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 32fa65f5a..f24af19bc 100644 --- a/v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod +++ b/v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod @@ -3,7 +3,7 @@ module server-example go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 8a0c4f2b6..2968bff93 100644 --- a/v3/integrations/nrfasthttp/go.mod +++ b/v3/integrations/nrfasthttp/go.mod @@ -3,7 +3,9 @@ module github.com/newrelic/go-agent/v3/integrations/nrfasthttp go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/valyala/fasthttp v1.49.0 ) + + replace github.com/newrelic/go-agent/v3 => ../.. diff --git a/v3/integrations/nrgin/go.mod b/v3/integrations/nrgin/go.mod index b5fe9c9d5..9ee324ae9 100644 --- a/v3/integrations/nrgin/go.mod +++ b/v3/integrations/nrgin/go.mod @@ -6,7 +6,7 @@ go 1.19 require ( github.com/gin-gonic/gin v1.9.1 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrgorilla/go.mod b/v3/integrations/nrgorilla/go.mod index bf6f98f68..38ec4acd8 100644 --- a/v3/integrations/nrgorilla/go.mod +++ b/v3/integrations/nrgorilla/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrgraphgophers/go.mod b/v3/integrations/nrgraphgophers/go.mod index b2b7d9791..e57bb3496 100644 --- a/v3/integrations/nrgraphgophers/go.mod +++ b/v3/integrations/nrgraphgophers/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrgraphqlgo/example/go.mod b/v3/integrations/nrgraphqlgo/example/go.mod index e62e55236..721e46a44 100644 --- a/v3/integrations/nrgraphqlgo/example/go.mod +++ b/v3/integrations/nrgraphqlgo/example/go.mod @@ -5,7 +5,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 d9434d1db..220749a52 100644 --- a/v3/integrations/nrgraphqlgo/go.mod +++ b/v3/integrations/nrgraphqlgo/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/graphql-go/graphql v0.8.1 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrgrpc/go.mod b/v3/integrations/nrgrpc/go.mod index ef93f3f53..e6f3e5c75 100644 --- a/v3/integrations/nrgrpc/go.mod +++ b/v3/integrations/nrgrpc/go.mod @@ -6,7 +6,7 @@ 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 bad7131a0..ba2d3b551 100644 --- a/v3/integrations/nrhttprouter/go.mod +++ b/v3/integrations/nrhttprouter/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrlambda/go.mod b/v3/integrations/nrlambda/go.mod index c08c9c71d..08f1c5d5e 100644 --- a/v3/integrations/nrlambda/go.mod +++ b/v3/integrations/nrlambda/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/aws/aws-lambda-go v1.41.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrlogrus/go.mod b/v3/integrations/nrlogrus/go.mod index 8f10989ad..8e40e94bb 100644 --- a/v3/integrations/nrlogrus/go.mod +++ b/v3/integrations/nrlogrus/go.mod @@ -5,7 +5,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrlogrus go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 5b1b23cc2..4996ebf02 100644 --- a/v3/integrations/nrlogxi/go.mod +++ b/v3/integrations/nrlogxi/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrmicro/go.mod b/v3/integrations/nrmicro/go.mod index e3996c59e..e47bea1e0 100644 --- a/v3/integrations/nrmicro/go.mod +++ b/v3/integrations/nrmicro/go.mod @@ -7,7 +7,7 @@ go 1.19 require ( github.com/golang/protobuf v1.5.3 github.com/micro/go-micro v1.8.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 google.golang.org/protobuf v1.32.0 ) diff --git a/v3/integrations/nrmongo/go.mod b/v3/integrations/nrmongo/go.mod index ccc654841..c20c3adba 100644 --- a/v3/integrations/nrmongo/go.mod +++ b/v3/integrations/nrmongo/go.mod @@ -5,7 +5,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrmongo go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 72d7c1f5a..142e82f53 100644 --- a/v3/integrations/nrmssql/go.mod +++ b/v3/integrations/nrmssql/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/microsoft/go-mssqldb v0.19.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrmysql/go.mod b/v3/integrations/nrmysql/go.mod index 978899404..bc7c39e99 100644 --- a/v3/integrations/nrmysql/go.mod +++ b/v3/integrations/nrmysql/go.mod @@ -7,7 +7,7 @@ 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrnats/go.mod b/v3/integrations/nrnats/go.mod index 6ed253247..4f88ca955 100644 --- a/v3/integrations/nrnats/go.mod +++ b/v3/integrations/nrnats/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrnats/test/go.mod b/v3/integrations/nrnats/test/go.mod index 1d9eb29e0..fde2c4dd5 100644 --- a/v3/integrations/nrnats/test/go.mod +++ b/v3/integrations/nrnats/test/go.mod @@ -8,7 +8,7 @@ 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/newrelic/go-agent/v3/integrations/nrnats v1.0.0 ) diff --git a/v3/integrations/nrpgx/example/sqlx/go.mod b/v3/integrations/nrpgx/example/sqlx/go.mod index 6b73f19f8..e45d6ce4a 100644 --- a/v3/integrations/nrpgx/example/sqlx/go.mod +++ b/v3/integrations/nrpgx/example/sqlx/go.mod @@ -4,7 +4,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrpgx/example/sqlx go 1.19 require ( github.com/jmoiron/sqlx v1.2.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 d2fecfb54..9bf8b686a 100644 --- a/v3/integrations/nrpgx/go.mod +++ b/v3/integrations/nrpgx/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/jackc/pgx v3.6.2+incompatible github.com/jackc/pgx/v4 v4.13.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrpgx5/go.mod b/v3/integrations/nrpgx5/go.mod index 80752b454..554db5aaa 100644 --- a/v3/integrations/nrpgx5/go.mod +++ b/v3/integrations/nrpgx5/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/egon12/pgsnap v0.0.0-20221022154027-2847f0124ed8 github.com/jackc/pgx/v5 v5.0.3 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/stretchr/testify v1.8.0 ) diff --git a/v3/integrations/nrpkgerrors/go.mod b/v3/integrations/nrpkgerrors/go.mod index 3f9b3c3c6..e70ff4b6e 100644 --- a/v3/integrations/nrpkgerrors/go.mod +++ b/v3/integrations/nrpkgerrors/go.mod @@ -5,7 +5,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrpkgerrors go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 d2da80385..922e4fd1a 100644 --- a/v3/integrations/nrpq/example/sqlx/go.mod +++ b/v3/integrations/nrpq/example/sqlx/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/jmoiron/sqlx v1.2.0 github.com/lib/pq v1.1.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 e27d05943..cae881021 100644 --- a/v3/integrations/nrpq/go.mod +++ b/v3/integrations/nrpq/go.mod @@ -6,7 +6,7 @@ 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrredis-v7/go.mod b/v3/integrations/nrredis-v7/go.mod index 212e4ea7c..aece5ff8a 100644 --- a/v3/integrations/nrredis-v7/go.mod +++ b/v3/integrations/nrredis-v7/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/go-redis/redis/v7 v7.0.0-beta.5 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrredis-v8/go.mod b/v3/integrations/nrredis-v8/go.mod index c38c5d8bd..25725d257 100644 --- a/v3/integrations/nrredis-v8/go.mod +++ b/v3/integrations/nrredis-v8/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/go-redis/redis/v8 v8.4.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrredis-v9/go.mod b/v3/integrations/nrredis-v9/go.mod index f8a2127ed..740764936 100644 --- a/v3/integrations/nrredis-v9/go.mod +++ b/v3/integrations/nrredis-v9/go.mod @@ -4,7 +4,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrredis-v9 go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 b82aa9b88..fc0dfabfc 100644 --- a/v3/integrations/nrsarama/go.mod +++ b/v3/integrations/nrsarama/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/Shopify/sarama v1.38.1 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/stretchr/testify v1.8.1 ) diff --git a/v3/integrations/nrsecurityagent/go.mod b/v3/integrations/nrsecurityagent/go.mod index 4fa48417e..979a8dd7b 100644 --- a/v3/integrations/nrsecurityagent/go.mod +++ b/v3/integrations/nrsecurityagent/go.mod @@ -4,9 +4,10 @@ go 1.19 require ( github.com/newrelic/csec-go-agent v1.0.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/newrelic/go-agent/v3/integrations/nrsqlite3 v1.2.0 gopkg.in/yaml.v2 v2.4.0 ) + replace github.com/newrelic/go-agent/v3 => ../.. diff --git a/v3/integrations/nrsnowflake/go.mod b/v3/integrations/nrsnowflake/go.mod index eb865485b..a92e5d9c0 100644 --- a/v3/integrations/nrsnowflake/go.mod +++ b/v3/integrations/nrsnowflake/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrsnowflake go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 github.com/snowflakedb/gosnowflake v1.6.19 ) diff --git a/v3/integrations/nrsqlite3/go.mod b/v3/integrations/nrsqlite3/go.mod index b661bcf73..df13a4ea1 100644 --- a/v3/integrations/nrsqlite3/go.mod +++ b/v3/integrations/nrsqlite3/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrstan/examples/go.mod b/v3/integrations/nrstan/examples/go.mod index b418e5371..dc9012afd 100644 --- a/v3/integrations/nrstan/examples/go.mod +++ b/v3/integrations/nrstan/examples/go.mod @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrstan/examples go 1.19 require ( github.com/nats-io/stan.go v0.5.0 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 fc826b498..41756b99c 100644 --- a/v3/integrations/nrstan/go.mod +++ b/v3/integrations/nrstan/go.mod @@ -6,7 +6,7 @@ go 1.19 require ( github.com/nats-io/stan.go v0.10.4 - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 ) diff --git a/v3/integrations/nrstan/test/go.mod b/v3/integrations/nrstan/test/go.mod index 7535757f1..ab595bd27 100644 --- a/v3/integrations/nrstan/test/go.mod +++ b/v3/integrations/nrstan/test/go.mod @@ -7,7 +7,7 @@ go 1.19 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.29.1 + github.com/newrelic/go-agent/v3 v3.30.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 4dc3856be..13cb5af27 100644 --- a/v3/integrations/nrzap/go.mod +++ b/v3/integrations/nrzap/go.mod @@ -5,7 +5,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrzap go 1.19 require ( - github.com/newrelic/go-agent/v3 v3.29.1 + github.com/newrelic/go-agent/v3 v3.30.0 // v1.12.0 is the earliest version of zap using modules. go.uber.org/zap v1.12.0 ) diff --git a/v3/newrelic/version.go b/v3/newrelic/version.go index 1b1f68799..5e1658b1c 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.29.1" + Version = "3.30.0" ) var (