Skip to content

Commit

Permalink
[cmd/builder] Add --verbose flag to log go subcommands output (#8715)
Browse files Browse the repository at this point in the history
**Description:** 

Log output from `go` subcommands being ran as part of an ocb build if passing the `--verbose` flag
  • Loading branch information
mx-psi authored Nov 6, 2023
1 parent c1ec4f3 commit 00c6dec
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 20 deletions.
25 changes: 25 additions & 0 deletions .chloggen/mx-psi_logging-builder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: cmd/builder

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Add --verbose flag to log `go` subcommands output that are ran as part of a build"

# One or more tracking issues or pull requests related to the change
issues: [8715]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
1 change: 1 addition & 0 deletions cmd/builder/internal/builder/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Config struct {
SkipCompilation bool `mapstructure:"-"`
SkipGetModules bool `mapstructure:"-"`
LDFlags string `mapstructure:"-"`
Verbose bool `mapstructure:"-"`

Distribution Distribution `mapstructure:"dist"`
Exporters []Module `mapstructure:"exporters"`
Expand Down
50 changes: 30 additions & 20 deletions cmd/builder/internal/builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,35 @@ import (
"time"

"go.uber.org/zap"
"go.uber.org/zap/zapio"
)

var (
// ErrGoNotFound is returned when a Go binary hasn't been found
ErrGoNotFound = errors.New("go binary not found")
)

func runGoCommand(cfg Config, args ...string) error {
cfg.Logger.Info("Running go subcommand.", zap.Any("arguments", args))
// #nosec G204 -- cfg.Distribution.Go is trusted to be a safe path and the caller is assumed to have carried out necessary input validation
cmd := exec.Command(cfg.Distribution.Go, args...)
cmd.Dir = cfg.Distribution.OutputPath

if cfg.Verbose {
writer := &zapio.Writer{Log: cfg.Logger}
defer func() { _ = writer.Close() }()
cmd.Stdout = writer
cmd.Stderr = writer
return cmd.Run()
}

if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("go subcommand failed with args '%v': %w. Output:\n%s", args, err, out)
}

return nil
}

// GenerateAndCompile will generate the source files based on the given configuration, update go mod, and will compile into a binary
func GenerateAndCompile(cfg Config) error {
if err := Generate(cfg); err != nil {
Expand Down Expand Up @@ -93,11 +115,8 @@ func Compile(cfg Config) error {
if cfg.Distribution.BuildTags != "" {
args = append(args, "-tags", cfg.Distribution.BuildTags)
}
// #nosec G204 -- cfg.Distribution.Go is trusted to be a safe path and the caller is assumed to have carried out necessary input validation
cmd := exec.Command(cfg.Distribution.Go, args...)
cmd.Dir = cfg.Distribution.OutputPath
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to compile the OpenTelemetry Collector distribution: %w. Output:\n%s", err, out)
if err := runGoCommand(cfg, args...); err != nil {
return fmt.Errorf("failed to compile the OpenTelemetry Collector distribution: %w", err)
}
cfg.Logger.Info("Compiled", zap.String("binary", fmt.Sprintf("%s/%s", cfg.Distribution.OutputPath, cfg.Distribution.Name)))

Expand All @@ -112,18 +131,12 @@ func GetModules(cfg Config) error {
}

// ambiguous import: found package cloud.google.com/go/compute/metadata in multiple modules
// #nosec G204 -- cfg.Distribution.Go is trusted to be a safe path
cmd := exec.Command(cfg.Distribution.Go, "get", "cloud.google.com/go")
cmd.Dir = cfg.Distribution.OutputPath
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to go get: %w. Output:\n%s", err, out)
if err := runGoCommand(cfg, "get", "cloud.google.com/go"); err != nil {
return fmt.Errorf("failed to go get: %w", err)
}

// #nosec G204 -- cfg.Distribution.Go is trusted to be a safe path
cmd = exec.Command(cfg.Distribution.Go, "mod", "tidy", "-compat=1.20")
cmd.Dir = cfg.Distribution.OutputPath
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("failed to update go.mod: %w. Output:\n%s", err, out)
if err := runGoCommand(cfg, "mod", "tidy", "-compat=1.20"); err != nil {
return fmt.Errorf("failed to update go.mod: %w", err)
}

cfg.Logger.Info("Getting go modules")
Expand All @@ -132,11 +145,8 @@ func GetModules(cfg Config) error {
retries := 3
failReason := "unknown"
for i := 1; i <= retries; i++ {
// #nosec G204
cmd := exec.Command(cfg.Distribution.Go, "mod", "download")
cmd.Dir = cfg.Distribution.OutputPath
if out, err := cmd.CombinedOutput(); err != nil {
failReason = fmt.Sprintf("%s. Output:\n%s", err, out)
if err := runGoCommand(cfg, "mod", "download"); err != nil {
failReason = err.Error()
cfg.Logger.Info("Failed modules download", zap.String("retry", fmt.Sprintf("%d/%d", i, retries)))
time.Sleep(5 * time.Second)
continue
Expand Down
2 changes: 2 additions & 0 deletions cmd/builder/internal/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
distributionOutputPathFlag = "output-path"
distributionGoFlag = "go"
distributionModuleFlag = "module"
verboseFlag = "verbose"
)

var (
Expand Down Expand Up @@ -82,6 +83,7 @@ configuration is provided, ocb will generate a default Collector.
cmd.Flags().BoolVar(&cfg.SkipGenerate, skipGenerateFlag, false, "Whether builder should skip generating go code (default false)")
cmd.Flags().BoolVar(&cfg.SkipCompilation, skipCompilationFlag, false, "Whether builder should only generate go code with no compile of the collector (default false)")
cmd.Flags().BoolVar(&cfg.SkipGetModules, skipGetModulesFlag, false, "Whether builder should skip updating go.mod and retrieve Go module list (default false)")
cmd.Flags().BoolVar(&cfg.Verbose, verboseFlag, false, "Whether builder should print verbose output (default false)")
cmd.Flags().StringVar(&cfg.LDFlags, ldflagsFlag, "", `ldflags to include in the "go build" command`)
cmd.Flags().StringVar(&cfg.Distribution.Name, distributionNameFlag, "otelcol-custom", "The executable name for the OpenTelemetry Collector distribution")
if err := cmd.Flags().MarkDeprecated(distributionNameFlag, "use config distribution::name"); err != nil {
Expand Down

0 comments on commit 00c6dec

Please sign in to comment.