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

log/logtest: provide record with their context #5468

Merged
merged 11 commits into from
Jun 6, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
The package contains semantic conventions from the `v1.26.0` version of the OpenTelemetry Semantic Conventions. (#5476)
- The `IsEmpty` method is added to the `Instrument` type in `go.opentelemetry.io/otel/sdk/metric`.
This method is used to check if an `Instrument` instance is a zero-value. (#5431)
- Store and provide the emitted `context.Context` in `ScopeRecords` of `go.opentelemetry.io/otel/sdk/log/logtest`. (#5468)

### Changed

Expand Down
25 changes: 25 additions & 0 deletions log/logtest/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,31 @@ func TestRecordFactoryMultiple(t *testing.T) {
assertAttributes(t, attrs, record1)
}

func assertRecord(t *testing.T, want log.Record, got log.Record) {
t.Helper()

if !want.Timestamp().Equal(got.Timestamp()) {
t.Errorf("Timestamp value is not equal:\nwant: %v\ngot: %v", want.Timestamp(), got.Timestamp())
}
if !want.ObservedTimestamp().Equal(got.ObservedTimestamp()) {
t.Errorf("ObservedTimestamp value is not equal:\nwant: %v\ngot: %v", want.ObservedTimestamp(), got.ObservedTimestamp())
}
if want.Severity() != got.Severity() {
t.Errorf("Severity value is not equal:\nwant: %v\ngot: %v", want.Severity(), got.Severity())
}
if want.SeverityText() != got.SeverityText() {
t.Errorf("SeverityText value is not equal:\nwant: %v\ngot: %v", want.SeverityText(), got.SeverityText())
}
assertBody(t, want.Body(), got)

var attrs []log.KeyValue
want.WalkAttributes(func(kv log.KeyValue) bool {
attrs = append(attrs, kv)
return true
})
assertAttributes(t, attrs, got)
}

func assertBody(t *testing.T, want log.Value, r log.Record) {
t.Helper()
got := r.Body()
Expand Down
22 changes: 18 additions & 4 deletions log/logtest/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,22 @@ type ScopeRecords struct {
// SchemaURL of the telemetry emitted by the scope.
SchemaURL string

// Records are the log records this instrumentation scope recorded.
Records []log.Record
// Records are the log records, and their associated context this
// instrumentation scope recorded.
Records []EmittedRecord
}

// EmittedRecord holds a log record the instrumentation received, alongside its
// context.
type EmittedRecord struct {
log.Record

ctx context.Context
}

// Context provides the context emitted with the record.
func (rwc EmittedRecord) Context() context.Context {
return rwc.ctx
}

// Recorder is a recorder that stores all received log records
Expand Down Expand Up @@ -150,11 +164,11 @@ func (l *logger) Enabled(ctx context.Context, record log.Record) bool {
}

// Emit stores the log record.
func (l *logger) Emit(_ context.Context, record log.Record) {
func (l *logger) Emit(ctx context.Context, record log.Record) {
l.mu.Lock()
defer l.mu.Unlock()

l.scopeRecord.Records = append(l.scopeRecord.Records, record)
l.scopeRecord.Records = append(l.scopeRecord.Records, EmittedRecord{record, ctx})
}

// Reset clears the in-memory log records.
Expand Down
23 changes: 18 additions & 5 deletions log/logtest/recorder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,30 @@ func TestRecorderEmitAndReset(t *testing.T) {

r1 := log.Record{}
r1.SetSeverity(log.SeverityInfo)
l.Emit(context.Background(), r1)
assert.Equal(t, r.Result()[0].Records, []log.Record{r1})
ctx := context.Background()

l.Emit(ctx, r1)
assert.Equal(t, r.Result()[0].Records, []EmittedRecord{
{r1, ctx},
})

nl := r.Logger("test")
assert.Empty(t, r.Result()[1].Records)

r2 := log.Record{}
r2.SetSeverity(log.SeverityError)
nl.Emit(context.Background(), r2)
assert.Equal(t, r.Result()[0].Records, []log.Record{r1})
assert.Equal(t, r.Result()[1].Records, []log.Record{r2})
// We want a non-background context here so it's different from `ctx`.
ctx2, cancel := context.WithCancel(ctx)
defer cancel()

nl.Emit(ctx2, r2)
assert.Len(t, r.Result()[0].Records, 1)
assertRecord(t, r.Result()[0].Records[0].Record, r1)
assert.Equal(t, r.Result()[0].Records[0].Context(), ctx)

assert.Len(t, r.Result()[1].Records, 1)
assertRecord(t, r.Result()[1].Records[0].Record, r2)
assert.Equal(t, r.Result()[1].Records[0].Context(), ctx2)

r.Reset()
assert.Empty(t, r.Result()[0].Records)
Expand Down