mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-01-30 08:39:29 +00:00
125 lines
2.9 KiB
Go
125 lines
2.9 KiB
Go
|
// Copyright The OpenTelemetry Authors
|
||
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
|
||
|
package sdk
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"time"
|
||
|
|
||
|
"go.opentelemetry.io/otel/trace"
|
||
|
"go.opentelemetry.io/otel/trace/noop"
|
||
|
|
||
|
"go.opentelemetry.io/auto/sdk/internal/telemetry"
|
||
|
)
|
||
|
|
||
|
type tracer struct {
|
||
|
noop.Tracer
|
||
|
|
||
|
name, schemaURL, version string
|
||
|
}
|
||
|
|
||
|
var _ trace.Tracer = tracer{}
|
||
|
|
||
|
func (t tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
||
|
var psc trace.SpanContext
|
||
|
sampled := true
|
||
|
span := new(span)
|
||
|
|
||
|
// Ask eBPF for sampling decision and span context info.
|
||
|
t.start(ctx, span, &psc, &sampled, &span.spanContext)
|
||
|
|
||
|
span.sampled.Store(sampled)
|
||
|
|
||
|
ctx = trace.ContextWithSpan(ctx, span)
|
||
|
|
||
|
if sampled {
|
||
|
// Only build traces if sampled.
|
||
|
cfg := trace.NewSpanStartConfig(opts...)
|
||
|
span.traces, span.span = t.traces(name, cfg, span.spanContext, psc)
|
||
|
}
|
||
|
|
||
|
return ctx, span
|
||
|
}
|
||
|
|
||
|
// Expected to be implemented in eBPF.
|
||
|
//
|
||
|
//go:noinline
|
||
|
func (t *tracer) start(
|
||
|
ctx context.Context,
|
||
|
spanPtr *span,
|
||
|
psc *trace.SpanContext,
|
||
|
sampled *bool,
|
||
|
sc *trace.SpanContext,
|
||
|
) {
|
||
|
start(ctx, spanPtr, psc, sampled, sc)
|
||
|
}
|
||
|
|
||
|
// start is used for testing.
|
||
|
var start = func(context.Context, *span, *trace.SpanContext, *bool, *trace.SpanContext) {}
|
||
|
|
||
|
func (t tracer) traces(name string, cfg trace.SpanConfig, sc, psc trace.SpanContext) (*telemetry.Traces, *telemetry.Span) {
|
||
|
span := &telemetry.Span{
|
||
|
TraceID: telemetry.TraceID(sc.TraceID()),
|
||
|
SpanID: telemetry.SpanID(sc.SpanID()),
|
||
|
Flags: uint32(sc.TraceFlags()),
|
||
|
TraceState: sc.TraceState().String(),
|
||
|
ParentSpanID: telemetry.SpanID(psc.SpanID()),
|
||
|
Name: name,
|
||
|
Kind: spanKind(cfg.SpanKind()),
|
||
|
}
|
||
|
|
||
|
span.Attrs, span.DroppedAttrs = convCappedAttrs(maxSpan.Attrs, cfg.Attributes())
|
||
|
|
||
|
links := cfg.Links()
|
||
|
if limit := maxSpan.Links; limit == 0 {
|
||
|
span.DroppedLinks = uint32(len(links))
|
||
|
} else {
|
||
|
if limit > 0 {
|
||
|
n := max(len(links)-limit, 0)
|
||
|
span.DroppedLinks = uint32(n)
|
||
|
links = links[n:]
|
||
|
}
|
||
|
span.Links = convLinks(links)
|
||
|
}
|
||
|
|
||
|
if t := cfg.Timestamp(); !t.IsZero() {
|
||
|
span.StartTime = cfg.Timestamp()
|
||
|
} else {
|
||
|
span.StartTime = time.Now()
|
||
|
}
|
||
|
|
||
|
return &telemetry.Traces{
|
||
|
ResourceSpans: []*telemetry.ResourceSpans{
|
||
|
{
|
||
|
ScopeSpans: []*telemetry.ScopeSpans{
|
||
|
{
|
||
|
Scope: &telemetry.Scope{
|
||
|
Name: t.name,
|
||
|
Version: t.version,
|
||
|
},
|
||
|
Spans: []*telemetry.Span{span},
|
||
|
SchemaURL: t.schemaURL,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}, span
|
||
|
}
|
||
|
|
||
|
func spanKind(kind trace.SpanKind) telemetry.SpanKind {
|
||
|
switch kind {
|
||
|
case trace.SpanKindInternal:
|
||
|
return telemetry.SpanKindInternal
|
||
|
case trace.SpanKindServer:
|
||
|
return telemetry.SpanKindServer
|
||
|
case trace.SpanKindClient:
|
||
|
return telemetry.SpanKindClient
|
||
|
case trace.SpanKindProducer:
|
||
|
return telemetry.SpanKindProducer
|
||
|
case trace.SpanKindConsumer:
|
||
|
return telemetry.SpanKindConsumer
|
||
|
}
|
||
|
return telemetry.SpanKind(0) // undefined.
|
||
|
}
|