add current tracing context detection and exec propagation

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit bc9a83144c83e9fd78007b7bfe92e8082c59d40e)
v0.9
Tonis Tiigi 2021-06-08 20:01:18 -07:00
parent 1c037fd52f
commit 69a8caa3be
5 changed files with 145 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/moby/buildkit/executor"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/util/network"
traceexec "github.com/moby/buildkit/util/tracing/exec"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors"
@ -76,6 +77,8 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou
hostname = meta.Hostname
}
meta.Env = append(meta.Env, traceexec.Environ(ctx)...)
opts = append(opts,
oci.WithProcessArgs(meta.Args...),
oci.WithEnv(meta.Env),

View File

@ -22,7 +22,12 @@ func Context() context.Context {
const exitLimit = 3
retries := 0
ctx, cancel := context.WithCancel(context.Background())
ctx := context.Background()
for _, f := range inits {
ctx = f(ctx)
}
ctx, cancel := context.WithCancel(ctx)
appContextCache = ctx
go func() {

View File

@ -0,0 +1,14 @@
package appcontext
import (
"context"
)
type Initializer func(context.Context) context.Context
var inits []Initializer
// Register stores a new context initializer that runs on app context creation
func Register(f Initializer) {
inits = append(inits, f)
}

54
util/tracing/env/traceenv.go vendored Normal file
View File

@ -0,0 +1,54 @@
package detect
import (
"context"
"os"
"github.com/moby/buildkit/util/appcontext"
"go.opentelemetry.io/otel/propagation"
)
const (
traceparentHeader = "traceparent"
tracestateHeader = "tracestate"
)
func init() {
appcontext.Register(initContext)
}
func initContext(ctx context.Context) context.Context {
// previously defined in https://github.com/open-telemetry/opentelemetry-swift/blob/4ea467ed4b881d7329bf2254ca7ed7f2d9d6e1eb/Sources/OpenTelemetrySdk/Trace/Propagation/EnvironmentContextPropagator.swift#L14-L15
parent := os.Getenv("OTEL_TRACE_PARENT")
state := os.Getenv("OTEL_TRACE_STATE")
if parent == "" {
return ctx
}
tc := propagation.TraceContext{}
return tc.Extract(ctx, &textMap{parent: parent, state: state})
}
type textMap struct {
parent string
state string
}
func (tm *textMap) Get(key string) string {
switch key {
case traceparentHeader:
return tm.parent
case tracestateHeader:
return tm.state
default:
return ""
}
}
func (tm *textMap) Set(key string, value string) {
}
func (tm *textMap) Keys() []string {
return []string{traceparentHeader, tracestateHeader}
}

View File

@ -0,0 +1,68 @@
package detect
import (
"context"
"go.opentelemetry.io/otel/propagation"
)
const (
traceparentHeader = "traceparent"
tracestateHeader = "tracestate"
)
// Environ returns list of environment variables that need to be sent to the child process
// in order for it to pick up cross-process tracing from same state.
func Environ(ctx context.Context) []string {
var tm textMap
tc := propagation.TraceContext{}
tc.Inject(ctx, &tm)
var env []string
// previously defined in https://github.com/open-telemetry/opentelemetry-swift/blob/4ea467ed4b881d7329bf2254ca7ed7f2d9d6e1eb/Sources/OpenTelemetrySdk/Trace/Propagation/EnvironmentContextPropagator.swift#L14-L15
if tm.parent != "" {
env = append(env, "OTEL_TRACE_PARENT="+tm.parent)
}
if tm.state != "" {
env = append(env, "OTEL_TRACE_STATE="+tm.state)
}
return env
}
type textMap struct {
parent string
state string
}
func (tm *textMap) Get(key string) string {
switch key {
case traceparentHeader:
return tm.parent
case tracestateHeader:
return tm.state
default:
return ""
}
}
func (tm *textMap) Set(key string, value string) {
switch key {
case traceparentHeader:
tm.parent = value
case tracestateHeader:
tm.state = value
}
}
func (tm *textMap) Keys() []string {
var k []string
if tm.parent != "" {
k = append(k, traceparentHeader)
}
if tm.state != "" {
k = append(k, tracestateHeader)
}
return k
}