1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-08-10 22:31:50 +02:00

log: Add Record.Clone (#7001)

Fixes #6986

This PR adds a `Clone()` method to the `log.Record` type.

The `Clone` method returns a copy of the record with no shared state,
allowing both the original and the clone to be modified independently.

This functionality mirrors the existing `sdk/log.Record.Clone()`
behavior and includes a corresponding unit test (`TestRecordClone`) to
ensure correctness.

---------

Co-authored-by: Robert Pająk <pellared@hotmail.com>
This commit is contained in:
arjun
2025-07-15 13:20:43 +05:30
committed by GitHub
parent 55d2e69a7b
commit 291140b0d8
3 changed files with 70 additions and 0 deletions

View File

@@ -41,6 +41,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- `RPCGRPCResponseMetadata` - `RPCGRPCResponseMetadata`
- Add `ErrorType` attribute helper function to the `go.opentelmetry.io/otel/semconv/v1.34.0` package. (#6962) - Add `ErrorType` attribute helper function to the `go.opentelmetry.io/otel/semconv/v1.34.0` package. (#6962)
- Add `WithAllowKeyDuplication` in `go.opentelemetry.io/otel/sdk/log` which can be used to disable deduplication for log records. (#6968) - Add `WithAllowKeyDuplication` in `go.opentelemetry.io/otel/sdk/log` which can be used to disable deduplication for log records. (#6968)
- Add `Clone` method to `Record` in `go.opentelemetry.io/otel/log` that returns a copy of the record with no shared state. (#7001)
### Changed ### Changed

View File

@@ -142,3 +142,11 @@ func (r *Record) AddAttributes(attrs ...KeyValue) {
func (r *Record) AttributesLen() int { func (r *Record) AttributesLen() int {
return r.nFront + len(r.back) return r.nFront + len(r.back)
} }
// Clone returns a copy of the record with no shared state.
// The original record and the clone can both be modified without interfering with each other.
func (r *Record) Clone() Record {
res := *r
res.back = slices.Clone(r.back)
return res
}

View File

@@ -160,3 +160,64 @@ func TestRecordAllocationLimits(t *testing.T) {
// Convince the linter these values are used. // Convince the linter these values are used.
_, _, _, _, _, _ = tStamp, sev, text, body, n, attr _, _, _, _, _, _ = tStamp, sev, text, body, n, attr
} }
func TestRecordClone(t *testing.T) {
now0 := time.Now()
sev0 := log.SeverityInfo
text0 := "text"
val0 := log.BoolValue(true)
attr0 := log.Bool("0", true)
r0 := log.Record{}
r0.SetTimestamp(now0)
r0.SetObservedTimestamp(now0)
r0.SetSeverity(sev0)
r0.SetSeverityText(text0)
r0.SetBody(val0)
r0.AddAttributes(attr0)
// Clone and modify the clone
now1 := now0.Add(time.Second)
sev1 := log.SeverityDebug
text1 := "string"
val1 := log.IntValue(1)
attr1 := log.Int64("1", 2)
r1 := r0.Clone()
r1.SetTimestamp(now1)
r1.SetObservedTimestamp(now1)
r1.SetSeverity(sev1)
r1.SetSeverityText(text1)
r1.SetBody(val1)
r1.AddAttributes(attr1)
// Assertions on original record (r0)
assert.Equal(t, now0, r0.Timestamp())
assert.Equal(t, now0, r0.ObservedTimestamp())
assert.Equal(t, sev0, r0.Severity())
assert.Equal(t, text0, r0.SeverityText())
assert.True(t, val0.Equal(r0.Body()))
var r0Attrs []log.KeyValue
r0.WalkAttributes(func(kv log.KeyValue) bool {
r0Attrs = append(r0Attrs, kv)
return true
})
assert.Contains(t, r0Attrs, attr0)
assert.NotContains(t, r0Attrs, attr1)
// Assertions on cloned record (r1)
assert.Equal(t, now1, r1.Timestamp())
assert.Equal(t, now1, r1.ObservedTimestamp())
assert.Equal(t, sev1, r1.Severity())
assert.Equal(t, text1, r1.SeverityText())
assert.True(t, val1.Equal(r1.Body()))
var r1Attrs []log.KeyValue
r1.WalkAttributes(func(kv log.KeyValue) bool {
r1Attrs = append(r1Attrs, kv)
return true
})
assert.Contains(t, r1Attrs, attr0)
assert.Contains(t, r1Attrs, attr1)
}