Skip to content

Commit

Permalink
Add custom attributes to log messages in transaction context for slog
Browse files Browse the repository at this point in the history
  • Loading branch information
mirackara committed May 3, 2024
1 parent 668533d commit 0506108
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
12 changes: 9 additions & 3 deletions v3/integrations/logcontext-v2/nrslog/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import (

func main() {
app, err := newrelic.NewApplication(
newrelic.ConfigFromEnvironment(),
newrelic.ConfigAppLogEnabled(true),
newrelic.ConfigAppName("Slog Logs In Context Example"),
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
newrelic.ConfigDebugLogger(os.Stdout),
newrelic.ConfigAppLogForwardingEnabled(true),
)
if err != nil {
panic(err)
Expand All @@ -27,7 +29,11 @@ func main() {
txn := app.StartTransaction("example transaction")
ctx := newrelic.NewContext(context.Background(), txn)

log.InfoContext(ctx, "I am a log inside a transaction")
log.InfoContext(ctx, "I am a log inside a transaction with custom attributes!",
slog.String("foo", "bar"),
slog.Int("answer", 42),
slog.Any("some_map", map[string]interface{}{"a": 1.0, "b": 2}),
)

// pretend to do some work
time.Sleep(500 * time.Millisecond)
Expand Down
14 changes: 11 additions & 3 deletions v3/integrations/logcontext-v2/nrslog/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,18 @@ func (h NRHandler) Enabled(ctx context.Context, lvl slog.Level) bool {
// - 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 {
attrs := map[string]interface{}{}

record.Attrs(func(attr slog.Attr) bool {
attrs[attr.Key] = attr.Value.Any()
return true
})

data := newrelic.LogData{
Severity: record.Level.String(),
Timestamp: record.Time.UnixMilli(),
Message: record.Message,
Severity: record.Level.String(),
Timestamp: record.Time.UnixMilli(),
Message: record.Message,
Attributes: attrs,
}
if h.txn != nil {
h.txn.RecordLog(data)
Expand Down
40 changes: 40 additions & 0 deletions v3/integrations/logcontext-v2/nrslog/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"log/slog"
"os"
"strings"
"testing"

Expand Down Expand Up @@ -225,6 +226,45 @@ func TestWithAttributes(t *testing.T) {

}

func TestWithAttributesFromContext(t *testing.T) {
app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn,
newrelic.ConfigAppLogDecoratingEnabled(false),
newrelic.ConfigAppLogForwardingEnabled(true),
)
log := slog.New(TextHandler(app.Application, os.Stdout, &slog.HandlerOptions{}))

log.Info("I am a log message")

txn := app.StartTransaction("example transaction")
ctx := newrelic.NewContext(context.Background(), txn)

log.InfoContext(ctx, "I am a log inside a transaction with custom attributes!",
slog.String("foo", "bar"),
slog.Int("answer", 42),
slog.Any("some_map", map[string]interface{}{"a": 1.0, "b": 2}),
)

txn.End()

app.ExpectLogEvents(t, []internal.WantLog{
{
Severity: slog.LevelInfo.String(),
Message: "I am a log message",
Timestamp: internal.MatchAnyUnixMilli,
},
{
Severity: slog.LevelInfo.String(),
Message: "I am a log inside a transaction with custom attributes!",
Timestamp: internal.MatchAnyUnixMilli,
Attributes: map[string]interface{}{
"foo": "bar",
"answer": 42,
"some_map": map[string]interface{}{"a": 1.0, "b": 2},
},
},
})

}
func TestWithGroup(t *testing.T) {
app := integrationsupport.NewTestApp(integrationsupport.SampleEverythingReplyFn,
newrelic.ConfigAppLogDecoratingEnabled(false),
Expand Down

0 comments on commit 0506108

Please sign in to comment.