Skip to content

Commit

Permalink
Add OpenTelemetry tracer
Browse files Browse the repository at this point in the history
Signed-off-by: peterdeme <[email protected]>

Try early return when dropping

Signed-off-by: peterdeme <[email protected]>
  • Loading branch information
peterdeme committed Nov 27, 2024
1 parent a01dbb6 commit 0d54328
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 5 deletions.
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ require (
github.com/onsi/gomega v1.32.0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/otel v1.32.0
go.opentelemetry.io/otel/sdk v1.32.0
go.opentelemetry.io/otel/trace v1.32.0
google.golang.org/grpc v1.63.2
gopkg.in/DataDog/dd-trace-go.v1 v1.62.0
)
Expand All @@ -32,6 +35,8 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.6.0-alpha.5 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand All @@ -48,10 +53,11 @@ require (
github.com/tinylib/msgp v1.1.8 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.50.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.16.1 // indirect
Expand Down
19 changes: 15 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
Expand Down Expand Up @@ -166,6 +169,14 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
Expand Down Expand Up @@ -234,8 +245,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
Expand Down
75 changes: 75 additions & 0 deletions tracing/opentelemetry/opentelemetry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package opentelemetry

import (
"fmt"

"github.com/spacelift-io/spcontext"
"github.com/spacelift-io/spcontext/tracing/internal"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)

// Tracer is an OpenTelemetry implementation of a Tracer.
type Tracer struct {
}

// OnSpanStart is called when a new span is created.
func (t *Tracer) OnSpanStart(ctx *spcontext.Context, name, resource string) *spcontext.Context {
var opts []trace.SpanStartOption
if resource != "" {
opts = append(opts, trace.WithAttributes(attribute.String("resource", resource)))
}

exitingSpan := trace.SpanFromContext(ctx)
if exitingSpan != nil && exitingSpan.SpanContext().IsValid() {
// exitingSpan.TracerProvider().Tracer()
// opts = append(opts, trace.WithLinks(trace.Link{SpanContext: exitingSpan.SpanContext()}))
ctx = spcontext.FromStdContext(trace.ContextWithSpan(ctx, exitingSpan)) // Propagate parent span context
}

newCtx, _ := otel.GetTracerProvider().Tracer("spacelift.io/tracing").Start(ctx, name, opts...)

return spcontext.FromStdContext(newCtx)
}

// OnSpanClose is called when a span is closed.
func (t *Tracer) OnSpanClose(ctx *spcontext.Context, err error, fields []any, drop, analyze bool) {
span := trace.SpanFromContext(ctx)
if span == nil || !span.SpanContext().IsValid() {
ctx.Warnf("No span in context.")
return
}

if drop {
span.SetAttributes(attribute.Bool(dropSampleKey, true))
//return
}

for key, value := range internal.DeduplicateFields(fields) {
span.SetAttributes(attribute.String(key, fmt.Sprintf("%v", value)))
}

if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "")
}

span.End(trace.WithStackTrace(err != nil))
}

// GetLogFields returns the fields which should be used in a log message in this context.
func (t *Tracer) GetLogFields(ctx *spcontext.Context) []any {
span := trace.SpanFromContext(ctx)
if span == nil {
return nil
}

spanCtx := span.SpanContext()

return []interface{}{
"otel.trace_id", spanCtx.TraceID(),
"otel.span_id", spanCtx.SpanID(),
}
}
33 changes: 33 additions & 0 deletions tracing/opentelemetry/sample.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package opentelemetry

// import (
// "go.opentelemetry.io/otel/sdk/trace"
// otelTrace "go.opentelemetry.io/otel/trace"
// )

const dropSampleKey = "drop"

// type Sampler struct {
// root trace.Sampler
// }

// func NewSampler(root trace.Sampler) *Sampler {
// return &Sampler{root: root}
// }

// func (s *Sampler) ShouldSample(p trace.SamplingParameters) trace.SamplingResult {
// for _, attr := range p.Attributes {
// if attr.Key == dropSampleKey {
// return trace.SamplingResult{
// Decision: trace.Drop,
// Tracestate: otelTrace.SpanContextFromContext(p.ParentContext).TraceState(),
// }
// }
// }

// return s.root.ShouldSample(p)
// }

// func (s *Sampler) Description() string {
// return "Spacelift Sampler"
// }

0 comments on commit 0d54328

Please sign in to comment.