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

Add otel support #4556

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions cli/command/manifest/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel/trace"
)

func newRmManifestListCommand(dockerCli command.Cli) *cobra.Command {
Expand All @@ -24,10 +25,13 @@ func newRmManifestListCommand(dockerCli command.Cli) *cobra.Command {
}

func runRm(ctx context.Context, dockerCli command.Cli, targets []string) error {
span := trace.SpanFromContext(ctx)

var errs []string
for _, target := range targets {
targetRef, refErr := normalizeReference(target)
if refErr != nil {
span.RecordError(refErr)
errs = append(errs, refErr.Error())
continue
}
Expand Down
4 changes: 4 additions & 0 deletions cli/command/registry/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/docker/registry"
"github.com/spf13/cobra"
"go.opentelemetry.io/otel/trace"
)

// NewLogoutCommand creates a new `docker logout` command
Expand Down Expand Up @@ -52,10 +53,13 @@ func runLogout(ctx context.Context, dockerCli command.Cli, serverAddress string)
regsToLogout = append(regsToLogout, hostnameAddress, "http://"+hostnameAddress, "https://"+hostnameAddress)
}

span := trace.SpanFromContext(ctx)

fmt.Fprintf(dockerCli.Out(), "Removing login credentials for %s\n", hostnameAddress)
errs := make(map[string]error)
for _, r := range regsToLogout {
if err := dockerCli.ConfigFile().GetCredentialsStore(r).Erase(r); err != nil {
span.RecordError(err)
errs[r] = err
}
}
Expand Down
52 changes: 51 additions & 1 deletion cmd/docker/docker.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"fmt"
"os"
"os/exec"
Expand All @@ -15,10 +16,14 @@ import (
"github.com/docker/cli/cli/version"
"github.com/docker/docker/api/types/versions"
"github.com/moby/buildkit/util/appcontext"
"github.com/moby/buildkit/util/tracing/detect"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
)

func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand {
Expand All @@ -40,7 +45,25 @@ func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand {
return fmt.Errorf("docker: '%s' is not a docker command.\nSee 'docker --help'", args[0])
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return isSupported(cmd, dockerCli)
if err := isSupported(cmd, dockerCli); err != nil {
return err
}

name := cmd.Name()
for p := cmd.Parent(); p != nil && p != cmd.Root(); p = p.Parent() {
name = p.Name() + " " + name
}

ctx, _ := otel.Tracer("").Start(cmd.Context(), name)
cmd.SetContext(ctx)
dockerCli.WithContext(ctx)

return nil
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
// TODO: There doesn't seem to be a way to determine if the command returned an an error
// so we can set the span status here.
trace.SpanFromContext(cmd.Context()).End()
},
Version: fmt.Sprintf("%s, build %s", version.Version, version.GitCommit),
DisableFlagsInUseLine: true,
Expand All @@ -54,6 +77,10 @@ func newDockerCommand(dockerCli *command.DockerCli) *cli.TopLevelCommand {
cmd.SetOut(dockerCli.Out())
cmd.SetErr(dockerCli.Err())

// Cobra's context may be nil in some cases, so initialize it here.
ctx := context.TODO()
cmd.SetContext(ctx)

opts, helpCmd = cli.SetupRootCommand(cmd)
registerCompletionFuncForGlobalFlags(dockerCli, cmd)
cmd.Flags().BoolP("version", "v", false, "Print version information and quit")
Expand Down Expand Up @@ -227,6 +254,29 @@ func runDocker(dockerCli *command.DockerCli) error {
return err
}

// Buildkit's detect package currently follows the old otel spec which defaulted to gRPC.
// Since the spec changed to default to http/protobuf.
// If these env vars are not set then we set them to the new default so detect will give us the expected protocol.
// This is the same as on the dockerd side.
// This can be removed after buildkit's detect package is updated.
if os.Getenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL") == "" && os.Getenv("OTEL_EXPORTER_OTLP_PROTOCOL") == "" {
os.Setenv("OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "http/protobuf")
}
if v := os.Getenv("OTEL_SERVICE_NAME"); v == "" {
os.Setenv("OTEL_SERVICE_NAME", cmd.Root().Name())
}

tp, err := detect.TracerProvider()
if err != nil {
logrus.WithError(err).Debug("Failed to initialize tracing")
}

otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
if tp != nil {
otel.SetTracerProvider(tp)
defer detect.Shutdown(context.Background())
}

var envs []string
args, os.Args, envs, err = processAliases(dockerCli, cmd, args, os.Args)
if err != nil {
Expand Down
15 changes: 13 additions & 2 deletions vendor.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ require (
gotest.tools/v3 v3.5.0
)

require (
go.opentelemetry.io/otel v1.4.1
go.opentelemetry.io/otel/trace v1.4.1
)
Comment on lines +50 to +53
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These ended up in the wrong block

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😱 ☁️


require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
Expand All @@ -60,6 +66,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.16.3 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
Expand All @@ -75,10 +82,14 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
go.etcd.io/etcd/raft/v3 v3.5.6 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0 // indirect
go.opentelemetry.io/otel v1.4.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1 // indirect
go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect
go.opentelemetry.io/otel/metric v0.27.0 // indirect
go.opentelemetry.io/otel/trace v1.4.1 // indirect
go.opentelemetry.io/otel/sdk v1.4.1 // indirect
go.opentelemetry.io/proto/otlp v0.12.0 // indirect
golang.org/x/crypto v0.2.0 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.10.0 // indirect
Expand Down
Loading