Skip to content

Conversation

jelmd
Copy link
Contributor

@jelmd jelmd commented Mar 21, 2025

fixes #85

@f41gh7 f41gh7 requested review from Copilot and f41gh7 July 27, 2025 12:37
Copy link

@Copilot 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 improves performance of Linux process metrics collection by pre-opening process files and using direct system calls instead of repeated file operations. The changes aim to reduce file I/O overhead and add comprehensive test coverage for the metrics functionality.

  • Replaces repeated file reads with pre-opened file descriptors and syscall.Pread
  • Adds comprehensive test suite with test data files for various process metrics
  • Updates error handling to use warnings instead of errors and removes atomic logging

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

File Description
process_metrics_linux.go Core performance improvements with pre-opened FDs and syscall optimization
process_metrics_linux_test.go Complete rewrite adding comprehensive test coverage with mock data
testdata/linux.* Test data files providing mock /proc filesystem data for testing
testdata/limits Removed old test file, replaced with linux-specific variants
Comments suppressed due to low confidence (2)

process_metrics_linux.go:92

  • Global variable name 'STAT_START' doesn't follow Go naming conventions. It should be 'statStart' (camelCase) since it's not exported.
var STAT_START = 0

process_metrics_linux.go:93

  • Global variable name 'NO_OUTPUT' doesn't follow Go naming conventions and appears unused. It should be 'noOutput' (camelCase) or removed if unused.
var NO_OUTPUT = false

if onTest {
cwd, err := os.Getwd()
if err != nil {
panic("Unknwon current working directory: " + err.Error())
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

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

There is a spelling error in the panic message. 'Unknwon' should be 'Unknown'.

Suggested change
panic("Unknwon current working directory: " + err.Error())
panic("Unknown current working directory: " + err.Error())

Copilot uses AI. Check for mistakes.

return nil
}
value *= 1024
value <<= 10
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

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

[nitpick] Using bit shift operator <<= 10 instead of *= 1024 makes the code less readable. While functionally equivalent, the multiplication is more explicit about converting from kB to bytes.

Suggested change
value <<= 10
value *= 1024

Copilot uses AI. Check for mistakes.

pm_file[FD_STAT] = f
pm_fd[FD_STAT] = int(f.Fd())
n, err := syscall.Pread(pm_fd[FD_STAT],
(*(*[unsafe.Sizeof(data) - 1]byte)(unsafe.Pointer(&data)))[:], 0)
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

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

Using unsafe.Pointer to convert byte array for syscall could be dangerous. Consider using a safer approach or add bounds checking to ensure the slice doesn't exceed the array size.

Suggested change
(*(*[unsafe.Sizeof(data) - 1]byte)(unsafe.Pointer(&data)))[:], 0)
data[:], 0)

Copilot uses AI. Check for mistakes.

return
}
n, err := syscall.Pread(pm_fd[FD_STAT],
(*(*[unsafe.Sizeof(data) - 1]byte)(unsafe.Pointer(&data)))[:], 0)
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

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

Similar unsafe pointer usage as in init2(). The unsafe conversion should be validated or replaced with a safer alternative.

Suggested change
(*(*[unsafe.Sizeof(data) - 1]byte)(unsafe.Pointer(&data)))[:], 0)
data[:], 0)

Copilot uses AI. Check for mistakes.


func getOpenFDsCount(path string) (uint64, error) {
f, err := os.Open(path)
/** return 0 on error, the number of open files otherwise */
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

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

Comment uses non-standard Go documentation format. Should use standard Go comment format: '// getOpenFDsCount returns 0 on error, the number of open files otherwise'

Suggested change
/** return 0 on error, the number of open files otherwise */
// getOpenFDsCount returns 0 on error, the number of open files otherwise.

Copilot uses AI. Check for mistakes.


func getMaxFilesLimit(path string) (uint64, error) {
data, err := ioutil.ReadFile(path)
/* returns 0 on error, -1 for unlimited, the limit otherwise */
Copy link

Copilot AI Jul 27, 2025

Choose a reason for hiding this comment

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

Comment uses non-standard Go documentation format. Should use standard Go comment format: '// getMaxFilesLimit returns 0 on error, -1 for unlimited, the limit otherwise'

Suggested change
/* returns 0 on error, -1 for unlimited, the limit otherwise */
// getMaxFilesLimit returns 0 on error, -1 for unlimited, the limit otherwise.

Copilot uses AI. Check for mistakes.

@valyala
Copy link
Contributor

valyala commented Aug 3, 2025

I doubt this change is needed at all - see this comment.

)

// Testfiles in the same order as above.
var testfiles = [FD_COUNT]string{
Copy link
Contributor

Choose a reason for hiding this comment

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

It isn't a good idea to mix the code needed for tests with the production code. Could you move this code into process_metrics_linux_test.go?

}

/*
process metrics related file descriptors for files we always need, and
Copy link
Contributor

Choose a reason for hiding this comment

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

All the comments in Go source code must consistently start with // . The only exception is if the file contains a big multi-line comment. Also it looks like the comment formatting is broken here.

type ProcFd uint32

const (
FD_LIMITS ProcFd = iota
Copy link
Contributor

Choose a reason for hiding this comment

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

Private constants in Go code must use camelCase naming instead of CAPITAL_SNAKE_CASE.

do not want to open/close all the time
*/
var pm_fd [FD_COUNT]int
Copy link
Contributor

Choose a reason for hiding this comment

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

Private variables in Go must use camelCase naming instead of snake_case

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.

better performance for process_* metrics on linux

2 participants