Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom attributes to log messages in transaction context for slog #911

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is true by default

)
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
Loading