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

fix(go): memory allocation in filtered spans #98

Merged
merged 2 commits into from
Aug 21, 2023
Merged
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
28 changes: 28 additions & 0 deletions go/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package observe

import (
"context"
"fmt"
"log"
"time"

"github.com/tetratelabs/wazero"
trace "go.opentelemetry.io/proto/otlp/trace/v1"
)

// The primary interface that every Adapter needs to follow
Expand Down Expand Up @@ -84,6 +86,32 @@ func (b *AdapterBase) Stop(wait bool) {
}
}

// MakeOtelCallSpans recursively constructs call spans in open telemetry format
func (b *AdapterBase) MakeOtelCallSpans(event CallEvent, parentId []byte, traceId string) []*trace.Span {
name := event.FunctionName()
span := NewOtelSpan(traceId, parentId, name, event.Time, event.Time.Add(event.Duration))
span.Attributes = append(span.Attributes, NewOtelKeyValueString("function-name", fmt.Sprintf("function-call-%s", name)))

spans := []*trace.Span{span}
for _, ev := range event.Within() {
if call, ok := ev.(CallEvent); ok {
spans = append(spans, b.MakeOtelCallSpans(call, span.SpanId, traceId)...)
}
if alloc, ok := ev.(MemoryGrowEvent); ok {
last := spans[len(spans)-1]

kv := NewOtelKeyValueInt64("allocation", int64(alloc.MemoryGrowAmount()))
i, existing := GetOtelAttrFromSpan("allocation", last)
if existing != nil {
last.Attributes[i] = AddOtelKeyValueInt64(kv, existing)
} else {
last.Attributes = append(last.Attributes, kv)
}
}
}
return spans
}

// Definition of how to filter our Spans to reduce noise
type SpanFilter struct {
MinDuration time.Duration
Expand Down
10 changes: 8 additions & 2 deletions go/adapter/datadog_formatter/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package datadog_formatter

import (
"fmt"
"strconv"
"time"

"github.com/dylibso/observe-sdk/go"
observe "github.com/dylibso/observe-sdk/go"
)

type DatadogFormatter []Trace
Expand Down Expand Up @@ -46,7 +47,12 @@ func (s *Span) AddAllocation(amount uint32) {
s.Meta = make(map[string]string)
}

s.Meta["allocation"] = fmt.Sprintf("%d", amount)
existingAmount, err := strconv.Atoi(s.Meta["allocation"])
if err == nil && existingAmount > 0 {
s.Meta["allocation"] = fmt.Sprintf("%d", amount+uint32(existingAmount))
} else {
s.Meta["allocation"] = fmt.Sprintf("%d", amount)
}
}

func New() *DatadogFormatter {
Expand Down
24 changes: 2 additions & 22 deletions go/adapter/honeycomb/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package honeycomb
import (
"bytes"
"context"
"fmt"
"log"
"net/http"
"net/url"
"time"

observe "github.com/dylibso/observe-sdk/go"
otel "github.com/dylibso/observe-sdk/go/adapter/otel_formatter"
trace "go.opentelemetry.io/proto/otlp/trace/v1"
proto "google.golang.org/protobuf/proto"
)
Expand Down Expand Up @@ -56,7 +54,7 @@ func (h *HoneycombAdapter) Flush(evts []observe.TraceEvent) error {
for _, e := range te.Events {
switch event := e.(type) {
case observe.CallEvent: // TODO: consider renaming to FunctionCall for consistency across Rust & JS
spans := h.makeCallSpans(event, nil, traceId)
spans := h.MakeOtelCallSpans(event, nil, traceId)
if len(spans) > 0 {
allSpans = append(allSpans, spans...)
}
Expand All @@ -71,7 +69,7 @@ func (h *HoneycombAdapter) Flush(evts []observe.TraceEvent) error {
return nil
}

t := otel.NewTrace(traceId, h.Config.Dataset, allSpans)
t := observe.NewOtelTrace(traceId, h.Config.Dataset, allSpans)
if te.AdapterMeta != nil {
meta, ok := te.AdapterMeta.(map[string]string)
if ok {
Expand Down Expand Up @@ -117,21 +115,3 @@ func (h *HoneycombAdapter) Flush(evts []observe.TraceEvent) error {

return nil
}

func (h *HoneycombAdapter) makeCallSpans(event observe.CallEvent, parentId []byte, traceId string) []*trace.Span {
name := event.FunctionName()
span := otel.NewSpan(traceId, parentId, name, event.Time, event.Time.Add(event.Duration))
span.Attributes = append(span.Attributes, otel.NewKeyValueString("function-name", fmt.Sprintf("function-call-%s", name)))

spans := []*trace.Span{span}
for _, ev := range event.Within() {
if call, ok := ev.(observe.CallEvent); ok {
spans = append(spans, h.makeCallSpans(call, span.SpanId, traceId)...)
}
if alloc, ok := ev.(observe.MemoryGrowEvent); ok {
last := spans[len(spans)-1]
last.Attributes = append(last.Attributes, otel.NewKeyValueInt64("allocation", int64(alloc.MemoryGrowAmount())))
}
}
return spans
}
24 changes: 2 additions & 22 deletions go/adapter/lightstep/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package lightstep
import (
"bytes"
"context"
"fmt"
"log"
"net/http"
"net/url"
"time"

observe "github.com/dylibso/observe-sdk/go"
otel "github.com/dylibso/observe-sdk/go/adapter/otel_formatter"
trace "go.opentelemetry.io/proto/otlp/trace/v1"
proto "google.golang.org/protobuf/proto"
)
Expand Down Expand Up @@ -56,7 +54,7 @@ func (h *LightstepAdapter) Flush(evts []observe.TraceEvent) error {
for _, e := range te.Events {
switch event := e.(type) {
case observe.CallEvent: // TODO: consider renaming to FunctionCall for consistency across Rust & JS
spans := h.makeCallSpans(event, nil, traceId)
spans := h.MakeOtelCallSpans(event, nil, traceId)
if len(spans) > 0 {
allSpans = append(allSpans, spans...)
}
Expand All @@ -71,7 +69,7 @@ func (h *LightstepAdapter) Flush(evts []observe.TraceEvent) error {
return nil
}

t := otel.NewTrace(traceId, h.Config.ServiceName, allSpans)
t := observe.NewOtelTrace(traceId, h.Config.ServiceName, allSpans)
if te.AdapterMeta != nil {
meta, ok := te.AdapterMeta.(map[string]string)
if ok {
Expand Down Expand Up @@ -118,21 +116,3 @@ func (h *LightstepAdapter) Flush(evts []observe.TraceEvent) error {

return nil
}

func (h *LightstepAdapter) makeCallSpans(event observe.CallEvent, parentId []byte, traceId string) []*trace.Span {
name := event.FunctionName()
span := otel.NewSpan(traceId, parentId, name, event.Time, event.Time.Add(event.Duration))
span.Attributes = append(span.Attributes, otel.NewKeyValueString("function-name", fmt.Sprintf("function-call-%s", name)))

spans := []*trace.Span{span}
for _, ev := range event.Within() {
if call, ok := ev.(observe.CallEvent); ok {
spans = append(spans, h.makeCallSpans(call, span.SpanId, traceId)...)
}
if alloc, ok := ev.(observe.MemoryGrowEvent); ok {
last := spans[len(spans)-1]
last.Attributes = append(last.Attributes, otel.NewKeyValueInt64("allocation", int64(alloc.MemoryGrowAmount())))
}
}
return spans
}
90 changes: 0 additions & 90 deletions go/adapter/otel_formatter/format.go

This file was deleted.

24 changes: 2 additions & 22 deletions go/adapter/otel_stdout/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"log"

observe "github.com/dylibso/observe-sdk/go"
otel "github.com/dylibso/observe-sdk/go/adapter/otel_formatter"
trace "go.opentelemetry.io/proto/otlp/trace/v1"
)

Expand Down Expand Up @@ -38,7 +37,7 @@ func (o *OtelStdoutAdapter) Flush(evts []observe.TraceEvent) error {
for _, e := range te.Events {
switch event := e.(type) {
case observe.CallEvent:
spans := o.makeCallSpans(event, nil, traceId)
spans := o.MakeOtelCallSpans(event, nil, traceId)
if len(spans) > 0 {
allSpans = append(allSpans, spans...)
}
Expand All @@ -53,7 +52,7 @@ func (o *OtelStdoutAdapter) Flush(evts []observe.TraceEvent) error {
return nil
}

t := otel.NewTrace(traceId, "golang", allSpans)
t := observe.NewOtelTrace(traceId, "golang", allSpans)
b, err := json.Marshal(t.TracesData)
if err != nil {
log.Println("failed to encode CallEvent spans")
Expand All @@ -66,25 +65,6 @@ func (o *OtelStdoutAdapter) Flush(evts []observe.TraceEvent) error {
return nil
}

func (o *OtelStdoutAdapter) makeCallSpans(event observe.CallEvent, parentId []byte, traceId string) []*trace.Span {
name := event.FunctionName()
span := otel.NewSpan(traceId, parentId, name, event.Time, event.Time.Add(event.Duration))
span.Attributes = append(span.Attributes, otel.NewKeyValueString("function_name", fmt.Sprintf("function-call-%s", name)))

spans := []*trace.Span{span}
for _, ev := range event.Within() {
if call, ok := ev.(observe.CallEvent); ok {
spans = append(spans, o.makeCallSpans(call, span.SpanId, traceId)...)
}
if alloc, ok := ev.(observe.MemoryGrowEvent); ok {
last := spans[len(spans)-1]
last.Attributes = append(last.Attributes, otel.NewKeyValueInt64("allocation", int64(alloc.MemoryGrowAmount())))
}
}

return spans
}

func (o *OtelStdoutAdapter) Start(ctx context.Context) {
o.AdapterBase.Start(ctx, o)
}
Loading