Skip to content

Commit

Permalink
WIP: add instrumentation to plugins
Browse files Browse the repository at this point in the history
Signed-off-by: Laura Brehm <laurabrehm@hey.com>
  • Loading branch information
laurazard committed May 6, 2024
1 parent e81b835 commit d607756
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
16 changes: 16 additions & 0 deletions cli-plugins/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ func RunPlugin(dockerCli *command.DockerCli, plugin *cobra.Command, meta manager
opts = append(opts, withPluginClientConn(plugin.Name()))
}
err = tcmd.Initialize(opts...)
ogRunE := cmd.RunE
if ogRunE == nil {
ogRun := cmd.Run
//nolint:unparam // necessary because error will always be nil here
ogRunE = func(cmd *cobra.Command, args []string) error {
ogRun(cmd, args)
return nil
}
cmd.Run = nil
}
cmd.RunE = func(cmd *cobra.Command, args []string) error {
stopInstrumentation := dockerCli.StartInstrumentation(ctx, cmd)
err := ogRunE(cmd, args)
stopInstrumentation(err)
return err
}
})
return err
}
Expand Down
19 changes: 14 additions & 5 deletions cli/command/telemetry_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ func BaseCommandAttributes(cmd *cobra.Command, streams Streams) []attribute.KeyV
// Note: this should be the last func to wrap/modify the PersistentRunE/RunE funcs before command execution.
//
// can also be used for spans!
func (cli *DockerCli) InstrumentCobraCommands(cmd *cobra.Command, mp metric.MeterProvider) {
meter := getDefaultMeter(mp)
func (cli *DockerCli) InstrumentCobraCommands(ctx context.Context, cmd *cobra.Command) {
// If PersistentPreRunE is nil, make it execute PersistentPreRun and return nil by default
ogPersistentPreRunE := cmd.PersistentPreRunE
if ogPersistentPreRunE == nil {
Expand Down Expand Up @@ -55,17 +54,27 @@ func (cli *DockerCli) InstrumentCobraCommands(cmd *cobra.Command, mp metric.Mete
}
cmd.RunE = func(cmd *cobra.Command, args []string) error {
// start the timer as the first step of every cobra command
baseAttrs := BaseCommandAttributes(cmd, cli)
stopCobraCmdTimer := startCobraCommandTimer(cmd, meter, baseAttrs)
stopInstrumentation := cli.StartInstrumentation(ctx, cmd)
cmdErr := ogRunE(cmd, args)
stopCobraCmdTimer(cmdErr)
stopInstrumentation(cmdErr)
return cmdErr
}

return ogPersistentPreRunE(cmd, args)
}
}

// StartInstrumentation instruments CLI commands with the individual metrics and spans configured.
// It's the main command OTel utlility, and new command-related metrics should be added to it.
// It should be called immediately before command execution, and returns a stopInstrumentation function
// that must be called with the error resulting from the command execution.
func (cli *DockerCli) StartInstrumentation(ctx context.Context, cmd *cobra.Command) (stopInstrumentation func(error)) {
mp := cli.MeterProvider(ctx)
meter := getDefaultMeter(mp)
baseAttrs := BaseCommandAttributes(cmd, cli)
return startCobraCommandTimer(cmd, meter, baseAttrs)
}

func startCobraCommandTimer(cmd *cobra.Command, meter metric.Meter, attrs []attribute.KeyValue) func(err error) {
ctx := cmd.Context()
durationCounter, _ := meter.Float64Counter(
Expand Down
3 changes: 2 additions & 1 deletion cmd/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,9 @@ func runDocker(ctx context.Context, dockerCli *command.DockerCli) error {

mp := dockerCli.MeterProvider(ctx)
defer mp.Shutdown(ctx)

otel.SetMeterProvider(mp)
dockerCli.InstrumentCobraCommands(cmd, mp)
dockerCli.InstrumentCobraCommands(ctx, cmd)

var envs []string
args, os.Args, envs, err = processAliases(dockerCli, cmd, args, os.Args)
Expand Down

0 comments on commit d607756

Please sign in to comment.