Skip to content

Conversation

@kongfei605
Copy link
Collaborator

No description provided.

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

Copilot AI left a comment

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])
}
Copy link

Copilot AI Dec 24, 2025

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
}
Copy link

Copilot AI Dec 24, 2025

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 ...
Copy link

Copilot AI Dec 24, 2025

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"
}
Copy link

Copilot AI Dec 24, 2025

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",
},
}
Copy link

Copilot AI Dec 24, 2025

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
Copy link

Copilot AI Dec 24, 2025

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"`
Copy link

Copilot AI Dec 24, 2025

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)
Copy link

Copilot AI Dec 24, 2025

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
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.

1 participant