Skip to content

Commit

Permalink
nrslog cleanup and prep for release
Browse files Browse the repository at this point in the history
  • Loading branch information
iamemilio committed Feb 7, 2024
1 parent 2c9d56b commit 72dd1ca
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 20 deletions.
38 changes: 38 additions & 0 deletions v3/integrations/logcontext-v2/nrslog/example/main.go
Original file line number Diff line number Diff line change
@@ -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)
}
17 changes: 2 additions & 15 deletions v3/integrations/logcontext-v2/nrslog/go.mod
Original file line number Diff line number Diff line change
@@ -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
)
12 changes: 7 additions & 5 deletions v3/integrations/logcontext-v2/nrslog/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ 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
app *newrelic.Application
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 {
Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
42 changes: 42 additions & 0 deletions v3/integrations/logcontext-v2/nrslog/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package nrslog

import (
"bytes"
"context"
"log/slog"
"testing"

Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit 72dd1ca

Please sign in to comment.