Skip to content

Commit a42687d

Browse files
Add cmdline process darwin (NR-155368) (#1731)
* Fix CmdLine extraction in Darwin
1 parent 76bc810 commit a42687d

File tree

4 files changed

+96
-5
lines changed

4 files changed

+96
-5
lines changed

.github/workflows/security.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@ jobs:
6363
exit-code: '1'
6464
ignore-unfixed: true
6565
vuln-type: 'os,library'
66-
severity: "high,critical"
66+
severity: "HIGH,CRITICAL"
6767
skip-dirs: "/var"

pkg/metrics/process/harvester_darwin_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ package process
55

66
import (
77
"bytes"
8+
"math"
9+
"testing"
10+
811
"github.com/newrelic/infrastructure-agent/internal/agent/mocks"
912
"github.com/newrelic/infrastructure-agent/pkg/config"
1013
"github.com/newrelic/infrastructure-agent/pkg/log"
@@ -15,8 +18,6 @@ import (
1518
"github.com/sirupsen/logrus"
1619
"github.com/stretchr/testify/assert"
1720
"github.com/stretchr/testify/mock"
18-
"math"
19-
"testing"
2021
)
2122

2223
func Test_newHarvester(t *testing.T) {
@@ -420,6 +421,7 @@ func TestDarwinHarvester_Do_NoError(t *testing.T) {
420421
proc.ShouldReturnCPUPercent(34.45, nil)
421422
proc.ShouldReturnTimes(&cpu.TimesStat{User: 34, System: 0.45}, nil)
422423
proc.ShouldReturnUsername("some username", nil)
424+
proc.ShouldReturnCmdLine("a command", nil)
423425

424426
h := newHarvester(ctx)
425427
h.processRetriever = func(int32) (Process, error) {
@@ -438,7 +440,7 @@ func TestDarwinHarvester_Do_NoError(t *testing.T) {
438440
assert.Equal(t, 34.45, sample.CPUPercent)
439441
assert.Equal(t, 34.0, math.Round(sample.CPUUserPercent*100)/100)
440442
assert.Equal(t, 0.45, math.Round(sample.CPUSystemPercent*100)/100)
441-
assert.Equal(t, "", sample.CmdLine)
443+
assert.Equal(t, "a command", sample.CmdLine)
442444
assert.Equal(t, "some status", sample.Status)
443445
assert.Equal(t, int32(0), sample.ParentProcessID)
444446
assert.Equal(t, int32(3), sample.ThreadCount)

pkg/metrics/process/snapshot_darwin.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ package process
55
import (
66
"os"
77
"runtime"
8+
"strings"
89
"time"
910

1011
"github.com/shirou/gopsutil/v3/process"
12+
13+
"github.com/newrelic/infrastructure-agent/pkg/helpers"
1114
)
1215

1316
// darwinProcess is an implementation of the process.Snapshot interface for darwin hosts.
@@ -217,5 +220,29 @@ func (pw *darwinProcess) Command() string {
217220
// CmdLine is taken from ps. As commands can have spaces, it's difficult parse parameters
218221
// so no params for now
219222
func (pw *darwinProcess) CmdLine(withArgs bool) (string, error) {
223+
if pw.cmdLine != "" {
224+
return pw.cmdLine, nil
225+
}
226+
227+
procCmdline, err := pw.process.Cmdline()
228+
if err != nil {
229+
return "", nil
230+
}
231+
232+
if len(procCmdline) == 0 {
233+
return "", nil // zombie process
234+
}
235+
236+
// Ignoring dash on session commands
237+
if procCmdline[0] == '-' {
238+
procCmdline = procCmdline[1:]
239+
}
240+
241+
if !withArgs {
242+
parts := strings.Split(procCmdline, " ")
243+
procCmdline = parts[0]
244+
}
245+
246+
pw.cmdLine = helpers.SanitizeCommandLine(procCmdline)
220247
return pw.cmdLine, nil
221248
}

pkg/metrics/process/snapshot_darwin_test.go

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ package process
44

55
import (
66
"errors"
7+
"testing"
8+
79
"github.com/shirou/gopsutil/v3/cpu"
810
"github.com/shirou/gopsutil/v3/process"
911
"github.com/stretchr/testify/assert"
1012
"github.com/stretchr/testify/mock"
11-
"testing"
1213
)
1314

1415
func Test_collectProcStats_NameError(t *testing.T) {
@@ -367,3 +368,64 @@ func Test_calculatePercent(t *testing.T) {
367368
})
368369
}
369370
}
371+
372+
//nolint:exhaustruct
373+
func Test_Calculate_Process_CmdLine(t *testing.T) {
374+
t.Parallel()
375+
tests := []struct {
376+
name string
377+
cmdLine string
378+
args bool
379+
expected string
380+
}{
381+
{
382+
name: "empty",
383+
cmdLine: "",
384+
expected: "",
385+
},
386+
{
387+
name: "ignoring dash on session commands",
388+
cmdLine: "-zsh",
389+
expected: "zsh",
390+
},
391+
{
392+
name: "no arguments & args enabled",
393+
cmdLine: "/sbin/launchd",
394+
args: true,
395+
expected: "/sbin/launchd",
396+
},
397+
{
398+
name: "no arguments & args disabled",
399+
cmdLine: "/sbin/launchd",
400+
args: false,
401+
expected: "/sbin/launchd",
402+
},
403+
{
404+
name: "arguments & args enabled",
405+
cmdLine: "/sbin/launchd -arg_a=1 -arg_b 2",
406+
args: true,
407+
expected: "/sbin/launchd -arg_a=1 -arg_b 2",
408+
},
409+
{
410+
name: "arguments & args disabled",
411+
cmdLine: "/sbin/launchd -arg_a=1 -arg_b 2",
412+
args: false,
413+
expected: "/sbin/launchd",
414+
},
415+
}
416+
for _, tt := range tests {
417+
t.Run(tt.name, func(t *testing.T) {
418+
t.Parallel()
419+
420+
process := &ProcessMock{}
421+
process.ShouldReturnCmdLine(tt.cmdLine, nil)
422+
darwinProcess := darwinProcess{
423+
process: process,
424+
}
425+
426+
result, err := darwinProcess.CmdLine(tt.args)
427+
assert.NoError(t, err)
428+
assert.Equal(t, tt.expected, result)
429+
})
430+
}
431+
}

0 commit comments

Comments
 (0)