Skip to content

Commit

Permalink
otellogr: Implement Error and comment Init (#6295)
Browse files Browse the repository at this point in the history
Implements remaining methods and adds to the changelog

Part of
#5192

---------

Co-authored-by: Damien Mathieu <42@dmathieu.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
  • Loading branch information
3 people authored Nov 14, 2024
1 parent f9d4025 commit 5b9cf72
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
2 changes: 1 addition & 1 deletion bridges/otellogr/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ go 1.22
require (
github.com/go-logr/logr v1.4.2
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/otel v1.32.0
go.opentelemetry.io/otel/log v0.8.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/otel v1.32.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
25 changes: 22 additions & 3 deletions bridges/otellogr/logsink.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// - Level is transformed and set as the Severity. The SeverityText is not
// set.
// - KeyAndValues are transformed and set as Attributes.
// - Error is always logged as an additional attribute with the key
// "exception.message" and with the severity [log.SeverityError].
// - The [context.Context] value in KeyAndValues is propagated to OpenTelemetry
// log record. All non-nested [context.Context] values are ignored and not
// added as attributes. If there are multiple [context.Context] the last one
Expand Down Expand Up @@ -59,6 +61,7 @@ import (

"go.opentelemetry.io/otel/log"
"go.opentelemetry.io/otel/log/global"
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
)

type config struct {
Expand Down Expand Up @@ -206,7 +209,20 @@ func (l *LogSink) Enabled(level int) bool {

// Error logs an error, with the given message and key/value pairs.
func (l *LogSink) Error(err error, msg string, keysAndValues ...any) {
// TODO
var record log.Record
record.SetBody(log.StringValue(msg))
record.SetSeverity(log.SeverityError)

record.AddAttributes(
log.String(string(semconv.ExceptionMessageKey), err.Error()),
)

record.AddAttributes(l.attr...)

ctx, attr := convertKVs(l.ctx, keysAndValues...)
record.AddAttributes(attr...)

l.logger.Emit(ctx, record)
}

// Info logs a non-error message with the given key/value pairs.
Expand All @@ -223,9 +239,12 @@ func (l *LogSink) Info(level int, msg string, keysAndValues ...any) {
l.logger.Emit(ctx, record)
}

// Init initializes the LogSink.
// Init receives optional information about the logr library this
// implementation does not use it.
func (l *LogSink) Init(info logr.RuntimeInfo) {
// TODO
// We don't need to do anything here.
// CallDepth is used to calculate the caller's PC.
// PC is dropped as part of the conversion to the OpenTelemetry log.Record.
}

// WithName returns a new LogSink with the specified name appended.
Expand Down
44 changes: 44 additions & 0 deletions bridges/otellogr/logsink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package otellogr

import (
"context"
"errors"
"testing"
"time"

Expand Down Expand Up @@ -277,6 +278,49 @@ func TestLogSink(t *testing.T) {
},
},
},
{
name: "error",
f: func(l *logr.Logger) {
l.Error(errors.New("test"), "error message")
},
wantRecords: map[string][]log.Record{
name: {
buildRecord(log.StringValue("error message"), time.Time{}, log.SeverityError, []log.KeyValue{
{Key: "exception.message", Value: log.StringValue("test")},
}),
},
},
},
{
name: "error_multi_attrs",
f: func(l *logr.Logger) {
l.Error(errors.New("test error"), "msg",
"struct", struct{ data int64 }{data: 1},
"bool", true,
"duration", time.Minute,
"float64", 3.14159,
"int64", -2,
"string", "str",
"time", time.Unix(1000, 1000),
"uint64", uint64(3),
)
},
wantRecords: map[string][]log.Record{
name: {
buildRecord(log.StringValue("msg"), time.Time{}, log.SeverityError, []log.KeyValue{
{Key: "exception.message", Value: log.StringValue("test error")},
log.String("struct", "{data:1}"),
log.Bool("bool", true),
log.Int64("duration", 60_000_000_000),
log.Float64("float64", 3.14159),
log.Int64("int64", -2),
log.String("string", "str"),
log.Int64("time", time.Unix(1000, 1000).UnixNano()),
log.Int64("uint64", 3),
}),
},
},
},
} {
t.Run(tt.name, func(t *testing.T) {
rec := logtest.NewRecorder()
Expand Down

0 comments on commit 5b9cf72

Please sign in to comment.