mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-01-30 04:40:41 +02:00
Record links/events attribute drops independently (#1771)
* Record links/events attribute drops independently * Update PR number * Remove unneeded span.droppedAttributeCount
This commit is contained in:
parent
5bbfc22cbc
commit
e9aaa04b8f
@ -30,6 +30,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE`
|
- `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE`
|
||||||
- `OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE`
|
- `OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE`
|
||||||
- `trace.TraceFlags` is now a defined type over `byte` and `WithSampled(bool) TraceFlags` and `IsSampled() bool` methods have been added to it. (#1770)
|
- `trace.TraceFlags` is now a defined type over `byte` and `WithSampled(bool) TraceFlags` and `IsSampled() bool` methods have been added to it. (#1770)
|
||||||
|
- The `Event` and `Link` struct types from the `go.opentelemetry.io/otel` package now include a `DroppedAttributeCount` field to record the number of attributes that were not recorded due to configured limits being reached. (#1771)
|
||||||
|
- The Jaeger exporter now reports dropped attributes for a Span event in the exported log. (#1771)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@ -54,6 +56,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
This changes it to make `SamplingParameters` conform with the OpenTelemetry specification. (#1749)
|
This changes it to make `SamplingParameters` conform with the OpenTelemetry specification. (#1749)
|
||||||
- Modify `BatchSpanProcessor.ForceFlush` to abort after timeout/cancellation. (#1757)
|
- Modify `BatchSpanProcessor.ForceFlush` to abort after timeout/cancellation. (#1757)
|
||||||
- Improve OTLP/gRPC exporter connection errors. (#1737)
|
- Improve OTLP/gRPC exporter connection errors. (#1737)
|
||||||
|
- The `DroppedAttributeCount` field of the `Span` in the `go.opentelemetry.io/otel` package now only represents the number of attributes dropped for the span itself.
|
||||||
|
It no longer is a conglomerate of itself, events, and link attributes that have been dropped. (#1771)
|
||||||
- Make `ExportSpans` in Jaeger Exporter honor context deadline. (#1773)
|
- Make `ExportSpans` in Jaeger Exporter honor context deadline. (#1773)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
@ -113,6 +113,7 @@ func TestExporter_ExportSpan(t *testing.T) {
|
|||||||
`"Value":{"Type":"STRING","Value":"value"}` +
|
`"Value":{"Type":"STRING","Value":"value"}` +
|
||||||
`}` +
|
`}` +
|
||||||
`],` +
|
`],` +
|
||||||
|
`"DroppedAttributeCount":0,` +
|
||||||
`"Time":` + string(expectedSerializedNow) +
|
`"Time":` + string(expectedSerializedNow) +
|
||||||
`},` +
|
`},` +
|
||||||
`{` +
|
`{` +
|
||||||
@ -123,6 +124,7 @@ func TestExporter_ExportSpan(t *testing.T) {
|
|||||||
`"Value":{"Type":"FLOAT64","Value":123.456}` +
|
`"Value":{"Type":"FLOAT64","Value":123.456}` +
|
||||||
`}` +
|
`}` +
|
||||||
`],` +
|
`],` +
|
||||||
|
`"DroppedAttributeCount":0,` +
|
||||||
`"Time":` + string(expectedSerializedNow) +
|
`"Time":` + string(expectedSerializedNow) +
|
||||||
`}` +
|
`}` +
|
||||||
`],` +
|
`],` +
|
||||||
|
@ -41,6 +41,7 @@ const (
|
|||||||
keySpanKind = "span.kind"
|
keySpanKind = "span.kind"
|
||||||
keyStatusCode = "otel.status_code"
|
keyStatusCode = "otel.status_code"
|
||||||
keyStatusMessage = "otel.status_description"
|
keyStatusMessage = "otel.status_description"
|
||||||
|
keyDroppedAttributeCount = "otel.event.dropped_attributes_count"
|
||||||
keyEventName = "event"
|
keyEventName = "event"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -301,6 +302,9 @@ func spanSnapshotToThrift(ss *export.SpanSnapshot) *gen.Span {
|
|||||||
if a.Name != "" {
|
if a.Name != "" {
|
||||||
nTags++
|
nTags++
|
||||||
}
|
}
|
||||||
|
if a.DroppedAttributeCount != 0 {
|
||||||
|
nTags++
|
||||||
|
}
|
||||||
fields := make([]*gen.Tag, 0, nTags)
|
fields := make([]*gen.Tag, 0, nTags)
|
||||||
if a.Name != "" {
|
if a.Name != "" {
|
||||||
// If an event contains an attribute with the same key, it needs
|
// If an event contains an attribute with the same key, it needs
|
||||||
@ -313,6 +317,9 @@ func spanSnapshotToThrift(ss *export.SpanSnapshot) *gen.Span {
|
|||||||
fields = append(fields, tag)
|
fields = append(fields, tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if a.DroppedAttributeCount != 0 {
|
||||||
|
fields = append(fields, getInt64Tag(keyDroppedAttributeCount, int64(a.DroppedAttributeCount)))
|
||||||
|
}
|
||||||
logs = append(logs, &gen.Log{
|
logs = append(logs, &gen.Log{
|
||||||
Timestamp: a.Time.UnixNano() / 1000,
|
Timestamp: a.Time.UnixNano() / 1000,
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
|
@ -356,6 +356,7 @@ func Test_spanSnapshotToThrift(t *testing.T) {
|
|||||||
linkSpanID, _ := trace.SpanIDFromHex("0102030405060709")
|
linkSpanID, _ := trace.SpanIDFromHex("0102030405060709")
|
||||||
|
|
||||||
eventNameValue := "event-test"
|
eventNameValue := "event-test"
|
||||||
|
eventDropped := int64(10)
|
||||||
keyValue := "value"
|
keyValue := "value"
|
||||||
statusCodeValue := int64(1)
|
statusCodeValue := int64(1)
|
||||||
doubleValue := 123.456
|
doubleValue := 123.456
|
||||||
@ -432,7 +433,12 @@ func Test_spanSnapshotToThrift(t *testing.T) {
|
|||||||
attribute.Int64("int", intValue),
|
attribute.Int64("int", intValue),
|
||||||
},
|
},
|
||||||
MessageEvents: []trace.Event{
|
MessageEvents: []trace.Event{
|
||||||
{Name: eventNameValue, Attributes: []attribute.KeyValue{attribute.String("k1", keyValue)}, Time: now},
|
{
|
||||||
|
Name: eventNameValue,
|
||||||
|
Attributes: []attribute.KeyValue{attribute.String("k1", keyValue)},
|
||||||
|
DroppedAttributeCount: int(eventDropped),
|
||||||
|
Time: now,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
StatusCode: codes.Error,
|
StatusCode: codes.Error,
|
||||||
StatusMessage: statusMessage,
|
StatusMessage: statusMessage,
|
||||||
@ -482,6 +488,11 @@ func Test_spanSnapshotToThrift(t *testing.T) {
|
|||||||
VStr: &keyValue,
|
VStr: &keyValue,
|
||||||
VType: gen.TagType_STRING,
|
VType: gen.TagType_STRING,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Key: keyDroppedAttributeCount,
|
||||||
|
VLong: &eventDropped,
|
||||||
|
VType: gen.TagType_LONG,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -68,7 +68,7 @@ type SpanSnapshot struct {
|
|||||||
StatusCode codes.Code
|
StatusCode codes.Code
|
||||||
StatusMessage string
|
StatusMessage string
|
||||||
|
|
||||||
// DroppedAttributeCount contains dropped attributes for the span itself, events and links.
|
// DroppedAttributeCount contains dropped attributes for the span itself.
|
||||||
DroppedAttributeCount int
|
DroppedAttributeCount int
|
||||||
DroppedMessageEventCount int
|
DroppedMessageEventCount int
|
||||||
DroppedLinkCount int
|
DroppedLinkCount int
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
@ -75,9 +74,6 @@ type ReadWriteSpan interface {
|
|||||||
// span is an implementation of the OpenTelemetry Span API representing the
|
// span is an implementation of the OpenTelemetry Span API representing the
|
||||||
// individual component of a trace.
|
// individual component of a trace.
|
||||||
type span struct {
|
type span struct {
|
||||||
// droppedAttributeCount contains dropped attributes for the events and links.
|
|
||||||
droppedAttributeCount int64
|
|
||||||
|
|
||||||
// mu protects the contents of this span.
|
// mu protects the contents of this span.
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
|
||||||
@ -292,17 +288,19 @@ func (s *span) addEvent(name string, o ...trace.EventOption) {
|
|||||||
c := trace.NewEventConfig(o...)
|
c := trace.NewEventConfig(o...)
|
||||||
|
|
||||||
// Discard over limited attributes
|
// Discard over limited attributes
|
||||||
|
var discarded int
|
||||||
if len(c.Attributes) > s.spanLimits.AttributePerEventCountLimit {
|
if len(c.Attributes) > s.spanLimits.AttributePerEventCountLimit {
|
||||||
s.addDroppedAttributeCount(len(c.Attributes) - s.spanLimits.AttributePerEventCountLimit)
|
discarded = len(c.Attributes) - s.spanLimits.AttributePerEventCountLimit
|
||||||
c.Attributes = c.Attributes[:s.spanLimits.AttributePerEventCountLimit]
|
c.Attributes = c.Attributes[:s.spanLimits.AttributePerEventCountLimit]
|
||||||
}
|
}
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
s.messageEvents.add(trace.Event{
|
s.messageEvents.add(trace.Event{
|
||||||
Name: name,
|
Name: name,
|
||||||
Attributes: c.Attributes,
|
Attributes: c.Attributes,
|
||||||
Time: c.Timestamp,
|
DroppedAttributeCount: discarded,
|
||||||
|
Time: c.Timestamp,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +421,7 @@ func (s *span) addLink(link trace.Link) {
|
|||||||
|
|
||||||
// Discard over limited attributes
|
// Discard over limited attributes
|
||||||
if len(link.Attributes) > s.spanLimits.AttributePerLinkCountLimit {
|
if len(link.Attributes) > s.spanLimits.AttributePerLinkCountLimit {
|
||||||
s.addDroppedAttributeCount(len(link.Attributes) - s.spanLimits.AttributePerLinkCountLimit)
|
link.DroppedAttributeCount = len(link.Attributes) - s.spanLimits.AttributePerLinkCountLimit
|
||||||
link.Attributes = link.Attributes[:s.spanLimits.AttributePerLinkCountLimit]
|
link.Attributes = link.Attributes[:s.spanLimits.AttributePerLinkCountLimit]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,10 +447,9 @@ func (s *span) Snapshot() *export.SpanSnapshot {
|
|||||||
sd.StatusCode = s.statusCode
|
sd.StatusCode = s.statusCode
|
||||||
sd.StatusMessage = s.statusMessage
|
sd.StatusMessage = s.statusMessage
|
||||||
|
|
||||||
sd.DroppedAttributeCount = int(s.droppedAttributeCount)
|
|
||||||
if s.attributes.evictList.Len() > 0 {
|
if s.attributes.evictList.Len() > 0 {
|
||||||
sd.Attributes = s.attributes.toKeyValue()
|
sd.Attributes = s.attributes.toKeyValue()
|
||||||
sd.DroppedAttributeCount += s.attributes.droppedCount
|
sd.DroppedAttributeCount = s.attributes.droppedCount
|
||||||
}
|
}
|
||||||
if len(s.messageEvents.queue) > 0 {
|
if len(s.messageEvents.queue) > 0 {
|
||||||
sd.MessageEvents = s.interfaceArrayToMessageEventArray()
|
sd.MessageEvents = s.interfaceArrayToMessageEventArray()
|
||||||
@ -502,10 +499,6 @@ func (s *span) addChild() {
|
|||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *span) addDroppedAttributeCount(delta int) {
|
|
||||||
atomic.AddInt64(&s.droppedAttributeCount, int64(delta))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*span) private() {}
|
func (*span) private() {}
|
||||||
|
|
||||||
func startSpanInternal(ctx context.Context, tr *tracer, name string, o *trace.SpanConfig) *span {
|
func startSpanInternal(ctx context.Context, tr *tracer, name string, o *trace.SpanConfig) *span {
|
||||||
|
@ -1491,10 +1491,10 @@ func TestAddEventsWithMoreAttributesThanLimit(t *testing.T) {
|
|||||||
attribute.Bool("key1", true),
|
attribute.Bool("key1", true),
|
||||||
attribute.String("key2", "value2"),
|
attribute.String("key2", "value2"),
|
||||||
},
|
},
|
||||||
|
DroppedAttributeCount: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SpanKind: trace.SpanKindInternal,
|
SpanKind: trace.SpanKindInternal,
|
||||||
DroppedAttributeCount: 2,
|
|
||||||
InstrumentationLibrary: instrumentation.Library{Name: "AddSpanEventWithOverLimitedAttributes"},
|
InstrumentationLibrary: instrumentation.Library{Name: "AddSpanEventWithOverLimitedAttributes"},
|
||||||
}
|
}
|
||||||
if diff := cmpDiff(got, want); diff != "" {
|
if diff := cmpDiff(got, want); diff != "" {
|
||||||
@ -1536,10 +1536,17 @@ func TestAddLinksWithMoreAttributesThanLimit(t *testing.T) {
|
|||||||
Parent: sc.WithRemote(true),
|
Parent: sc.WithRemote(true),
|
||||||
Name: "span0",
|
Name: "span0",
|
||||||
Links: []trace.Link{
|
Links: []trace.Link{
|
||||||
{SpanContext: sc1, Attributes: []attribute.KeyValue{k1v1}},
|
{
|
||||||
{SpanContext: sc2, Attributes: []attribute.KeyValue{k2v2}},
|
SpanContext: sc1,
|
||||||
|
Attributes: []attribute.KeyValue{k1v1},
|
||||||
|
DroppedAttributeCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SpanContext: sc2,
|
||||||
|
Attributes: []attribute.KeyValue{k2v2},
|
||||||
|
DroppedAttributeCount: 2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
DroppedAttributeCount: 3,
|
|
||||||
SpanKind: trace.SpanKindInternal,
|
SpanKind: trace.SpanKindInternal,
|
||||||
InstrumentationLibrary: instrumentation.Library{Name: "Links"},
|
InstrumentationLibrary: instrumentation.Library{Name: "Links"},
|
||||||
}
|
}
|
||||||
|
@ -547,6 +547,10 @@ type Event struct {
|
|||||||
// Attributes describe the aspects of the event.
|
// Attributes describe the aspects of the event.
|
||||||
Attributes []attribute.KeyValue
|
Attributes []attribute.KeyValue
|
||||||
|
|
||||||
|
// DroppedAttributeCount is the number of attributes that were not
|
||||||
|
// recorded due to configured limits being reached.
|
||||||
|
DroppedAttributeCount int
|
||||||
|
|
||||||
// Time at which this event was recorded.
|
// Time at which this event was recorded.
|
||||||
Time time.Time
|
Time time.Time
|
||||||
}
|
}
|
||||||
@ -567,8 +571,15 @@ type Event struct {
|
|||||||
// form. A Link is used to keep reference to the original SpanContext and
|
// form. A Link is used to keep reference to the original SpanContext and
|
||||||
// track the relationship.
|
// track the relationship.
|
||||||
type Link struct {
|
type Link struct {
|
||||||
|
// SpanContext of the linked Span.
|
||||||
SpanContext
|
SpanContext
|
||||||
|
|
||||||
|
// Attributes describe the aspects of the link.
|
||||||
Attributes []attribute.KeyValue
|
Attributes []attribute.KeyValue
|
||||||
|
|
||||||
|
// DroppedAttributeCount is the number of attributes that were not
|
||||||
|
// recorded due to configured limits being reached.
|
||||||
|
DroppedAttributeCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpanKind is the role a Span plays in a Trace.
|
// SpanKind is the role a Span plays in a Trace.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user