Skip to content

feat(procstat): add sudo and custom path support#1382

Merged
kongfei605 merged 1 commit into
flashcatcloud:mainfrom
kongfei605:feat_sudo
Dec 24, 2025
Merged

feat(procstat): add sudo and custom path support#1382
kongfei605 merged 1 commit into
flashcatcloud:mainfrom
kongfei605:feat_sudo

Conversation

@kongfei605

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings December 24, 2025 09:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for executing jstat with sudo privileges and custom binary paths in the procstat input plugin. The implementation allows users to configure privilege escalation and specify non-standard jstat locations for Java process monitoring.

Key Changes:

  • Added UseSudo and PathJstat configuration fields to control jstat execution
  • Refactored execJstat to support sudo command wrapping and custom binary paths
  • Improved error reporting with detailed exit codes and stderr output
  • Added unit tests to verify command construction with various configurations

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
inputs/procstat/procstat.go Adds UseSudo and PathJstat fields, refactors execJstat method to support sudo and custom paths, introduces testable command execution via global variables, improves error handling
inputs/procstat/procstat_test.go Adds unit tests for execJstat command construction covering default, sudo, and custom path scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +72 to +75
assert.Equal(t, tt.expectedCmd, capturedCmd)
if tt.useSudo {
assert.Equal(t, tt.pathJstat, capturedArgs[0])
}

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

The test only validates the command name captured in sudo mode but doesn't verify the complete argument list in all cases. The test should assert all expected arguments for each test case. For example, in the "Default" and "Custom Path" cases, the arguments should include "-gc" and "1234". In the "Sudo Enabled" case, all arguments including "jstat", "-gc", and "1234" should be verified. Consider adding an expectedArgs field to the test struct and verifying it for all test cases.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +17
execLookPath = exec.LookPath
}()
execLookPath = func(file string) (string, error) {
return file, nil
}

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

The execLookPath variable is mocked but never used in the current implementation of execJstat. Since the new implementation doesn't call exec.LookPath anymore (it uses PathJstat directly), this mock setup is unnecessary and should be removed.

Suggested change
execLookPath = exec.LookPath
}()
execLookPath = func(file string) (string, error) {
return file, nil
}
}()

Copilot uses AI. Check for mistakes.
pathJstat string
pid PID
expectedCmd string
// expectedArgs ...

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

The commented line "expectedArgs ..." suggests incomplete test implementation. Either remove this comment if the field is not needed, or implement complete argument validation for all test cases.

Suggested change
// expectedArgs ...

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +66
if ins.PathJstat == "" {
ins.PathJstat = "jstat"
}

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

The test duplicates the default initialization logic from the Init method. The test manually sets PathJstat to "jstat" if empty, which duplicates logic that should be in the Init method. Consider calling ins.Init() instead to ensure the test reflects the actual initialization behavior.

Suggested change
if ins.PathJstat == "" {
ins.PathJstat = "jstat"
}
ins.Init()

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +48
tests := []struct {
name string
useSudo bool
pathJstat string
pid PID
expectedCmd string
// expectedArgs ...
}{
{
name: "Default",
useSudo: false,
pathJstat: "jstat",
pid: 1234,
expectedCmd: "jstat",
},
{
name: "Sudo Enabled",
useSudo: true,
pathJstat: "jstat",
pid: 1234,
expectedCmd: "sudo",
},
{
name: "Custom Path",
useSudo: false,
pathJstat: "/usr/bin/jstat",
pid: 1234,
expectedCmd: "/usr/bin/jstat",
},
}

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

Test coverage missing: The test doesn't cover the combination of UseSudo with a custom path (e.g., UseSudo=true with PathJstat="/usr/bin/jstat"). This is an important scenario to test since it represents a realistic use case.

Copilot uses AI. Check for mistakes.
)

var execCommand = exec.Command
var execLookPath = exec.LookPath

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

The execLookPath variable is declared but never used in the current implementation. Since execJstat no longer calls exec.LookPath, this variable should be removed unless there are plans to validate the jstat path before execution.

Suggested change
var execLookPath = exec.LookPath

Copilot uses AI. Check for mistakes.
GatherPerPid bool `toml:"gather_per_pid"`
GatherMoreMetrics []string `toml:"gather_more_metrics"`

UseSudo bool `toml:"use_sudo"`

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

Missing documentation: The new configuration fields UseSudo and PathJstat should have documentation comments explaining their purpose, usage, and any security considerations (especially for UseSudo). This is important for users configuring the plugin.

Suggested change
UseSudo bool `toml:"use_sudo"`
// UseSudo controls whether external tools such as jstat are executed via
// "sudo". Enable this only if the monitored commands require elevated
// privileges and you have configured sudoers appropriately (for example,
// to allow passwordless execution of the required binaries). Misuse or
// misconfiguration of sudo can introduce security risks.
UseSudo bool `toml:"use_sudo"`
// PathJstat optionally specifies the absolute path to the jstat binary to
// use when collecting JVM-related metrics. If left empty, the plugin will
// search for jstat in the system PATH.

Copilot uses AI. Check for mistakes.
Comment on lines +563 to +566
bin := ins.PathJstat
args := []string{}
if ins.UseSudo {
args = append(args, ins.PathJstat)

Copilot AI Dec 24, 2025

Copy link

Choose a reason for hiding this comment

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

Security concern: When UseSudo is enabled, the custom PathJstat is passed directly to sudo without validation. This could allow arbitrary command execution if PathJstat contains malicious input (e.g., "../../../bin/malicious"). Consider validating that PathJstat is an absolute path or exists in a safe location, or use exec.LookPath to resolve the binary path before constructing the sudo command.

Suggested change
bin := ins.PathJstat
args := []string{}
if ins.UseSudo {
args = append(args, ins.PathJstat)
jstatPath := ins.PathJstat
if jstatPath == "" {
jstatPath = "jstat"
}
resolvedJstatPath, err := execLookPath(jstatPath)
if err != nil {
return nil, fmt.Errorf("failed to locate jstat binary '%s': %w", jstatPath, err)
}
bin := resolvedJstatPath
args := []string{}
if ins.UseSudo {
args = append(args, resolvedJstatPath)

Copilot uses AI. Check for mistakes.
@kongfei605 kongfei605 merged commit bcf60e2 into flashcatcloud:main Dec 24, 2025
9 checks passed
@kongfei605 kongfei605 deleted the feat_sudo branch December 24, 2025 09:36
laiwei pushed a commit to laiwei/categraf that referenced this pull request Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants