Skip to content

Commit

Permalink
[probes.external] Log command's stderr in 'ONCE' mode (#304)
Browse files Browse the repository at this point in the history
We already do that in the 'SERVER' mode.
  • Loading branch information
koncha99 committed Mar 2, 2023
1 parent 4f729ce commit 6adf445
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 19 deletions.
16 changes: 10 additions & 6 deletions probes/external/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type Probe struct {
dataChan chan *metrics.EventMetrics

// This is used for overriding run command logic for testing.
runCommandFunc func(ctx context.Context, cmd string, args []string) ([]byte, error)
runCommandFunc func(ctx context.Context, cmd string, args []string) ([]byte, []byte, error)

// default payload metrics that we clone from to build per-target payload
// metrics.
Expand Down Expand Up @@ -559,29 +559,33 @@ func (p *Probe) runOnceProbe(ctx context.Context) {
result.total++
startTime := time.Now()

var b []byte
var stdout, stderr []byte
var err error
if p.runCommandFunc != nil {
b, err = p.runCommandFunc(ctx, p.cmdName, args)
stdout, stderr, err = p.runCommandFunc(ctx, p.cmdName, args)
} else {
b, err = p.runCommand(ctx, p.cmdName, args)
stdout, stderr, err = p.runCommand(ctx, p.cmdName, args)
}

success := true
if err != nil {
success = false
if exitErr, ok := err.(*exec.ExitError); ok {
p.l.Errorf("external probe process died with the status: %s. Stderr: %s", exitErr.Error(), exitErr.Stderr)
p.l.Errorf("external probe process died with the status: %s. Stderr: %s", exitErr.Error(), stderr)
} else {
p.l.Errorf("Error executing the external program. Err: %v", err)
}
} else {
if len(stderr) != 0 {
p.l.Warningf("Stderr: %s", stderr)
}
}

p.processProbeResult(&probeStatus{
target: target.Name,
success: success,
latency: time.Since(startTime),
payload: string(b),
payload: string(stdout),
}, result)
}(target, p.results[target.Name])
}
Expand Down
8 changes: 4 additions & 4 deletions probes/external/external_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,11 @@ func TestProbeOnceMode(t *testing.T) {
tgts := []string{"target1", "target2"}

// Set runCommand to a function that runs successfully and returns a pyload.
p.runCommandFunc = func(ctx context.Context, cmd string, cmdArgs []string) ([]byte, error) {
p.runCommandFunc = func(ctx context.Context, cmd string, cmdArgs []string) ([]byte, []byte, error) {
var resp []string
resp = append(resp, fmt.Sprintf("cmd \"%s\"", cmd))
resp = append(resp, fmt.Sprintf("num-args %d", len(cmdArgs)))
return []byte(strings.Join(resp, "\n")), nil
return []byte(strings.Join(resp, "\n")), nil, nil
}

total, success := make(map[string]int64), make(map[string]int64)
Expand All @@ -359,8 +359,8 @@ func TestProbeOnceMode(t *testing.T) {
runAndVerifyProbe(t, p, tgts, total, success)

// Try with failing command now
p.runCommandFunc = func(ctx context.Context, cmd string, cmdArgs []string) ([]byte, error) {
return nil, fmt.Errorf("error executing %s", cmd)
p.runCommandFunc = func(ctx context.Context, cmd string, cmdArgs []string) ([]byte, []byte, error) {
return nil, nil, fmt.Errorf("error executing %s", cmd)
}

for _, tgt := range tgts {
Expand Down
10 changes: 3 additions & 7 deletions probes/external/runcmd_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ import (
"time"
)

func (p *Probe) runCommand(ctx context.Context, cmd string, args []string) ([]byte, error) {
func (p *Probe) runCommand(ctx context.Context, cmd string, args []string) ([]byte, []byte, error) {
c := exec.Command(cmd, args...)
c.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
var stdout, stderr bytes.Buffer
c.Stdout, c.Stderr = &stdout, &stderr

if err := c.Start(); err != nil {
return stdout.Bytes(), err
return stdout.Bytes(), stderr.Bytes(), err
}

// This goroutine is similar to the one started by exec.Start if command is
Expand Down Expand Up @@ -73,9 +73,5 @@ func (p *Probe) runCommand(ctx context.Context, cmd string, args []string) ([]by
}
}()

if exitErr, ok := err.(*exec.ExitError); ok {
exitErr.Stderr = stderr.Bytes()
}

return stdout.Bytes(), err
return stdout.Bytes(), stderr.Bytes(), err
}
9 changes: 7 additions & 2 deletions probes/external/runcmd_nonlinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@
package external

import (
"bytes"
"context"
"os/exec"
)

func (p *Probe) runCommand(ctx context.Context, cmd string, args []string) ([]byte, error) {
return exec.CommandContext(ctx, cmd, args...).Output()
func (p *Probe) runCommand(ctx context.Context, cmd string, args []string) ([]byte, []byte, error) {
c := exec.CommandContext(ctx, cmd, args...)
var stdout, stderr bytes.Buffer
c.Stdout, c.Stderr = &stdout, &stderr
err := c.Run()
return stdout.Bytes(), stderr.Bytes(), err
}

0 comments on commit 6adf445

Please sign in to comment.