-
Notifications
You must be signed in to change notification settings - Fork 217
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add CPU profile to telemetry heartbeat (#625)
# Description Adding CPU profile to heartbeat to determine user/sys cpu time over a given window ## Related Issue If this pull request is related to any issue, please mention it here. Additionally, make sure that the issue is assigned to you before submitting this pull request. ## Checklist - [ ] I have read the [contributing documentation](https://retina.sh/docs/contributing). - [ ] I signed and signed-off the commits (`git commit -S -s ...`). See [this documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification) on signing commits. - [ ] I have correctly attributed the author(s) of the code. - [ ] I have tested the changes locally. - [ ] I have followed the project's style guidelines. - [ ] I have updated the documentation, if necessary. - [ ] I have added tests, if applicable. ## Screenshots (if applicable) or Testing Completed Please add any relevant screenshots or GIFs to showcase the changes made. ## Additional Notes Add any additional notes or context about the pull request here. --- Please refer to the [CONTRIBUTING.md](../CONTRIBUTING.md) file for more information on how to contribute to this project.
- Loading branch information
Showing
10 changed files
with
165 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package telemetry | ||
|
||
type NoopPerfProfile struct{} | ||
|
||
func (n *NoopPerfProfile) GetMemoryUsage() map[string]string { | ||
return make(map[string]string) | ||
} | ||
|
||
func NewNoopPerfProfile() *NoopPerfProfile { | ||
return &NoopPerfProfile{} | ||
} | ||
|
||
func (n *NoopPerfProfile) GetCPUUsage() (map[string]string, error) { //nolint unnamed results are fine | ||
return make(map[string]string), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package telemetry | ||
|
||
type Perf interface { | ||
GetMemoryUsage() map[string]string | ||
GetCPUUsage() (map[string]string, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
//go:build unix | ||
|
||
package telemetry | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"runtime" | ||
"strconv" | ||
"sync" | ||
"syscall" | ||
) | ||
|
||
var ( | ||
microsecondBitShift = 20 | ||
ErrNotInitialized = errors.New("perf profile not initialized") | ||
) | ||
|
||
const ( | ||
userCPUSeconds = "usr_cpu_sec" | ||
sysCPUSeconds = "sys_cpu_sec" | ||
) | ||
|
||
type PerfProfile struct { | ||
perflock sync.RWMutex | ||
usage *syscall.Rusage | ||
} | ||
|
||
func NewPerfProfile() (*PerfProfile, error) { | ||
p := &PerfProfile{} | ||
var usage syscall.Rusage | ||
err := syscall.Getrusage(syscall.RUSAGE_SELF, &usage) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get rusage during init: %w", err) | ||
} | ||
p.usage = &usage | ||
|
||
return p, nil | ||
} | ||
|
||
func (p *PerfProfile) GetMemoryUsage() map[string]string { | ||
var m runtime.MemStats | ||
runtime.ReadMemStats(&m) | ||
props := map[string]string{ | ||
allocatedmem: strconv.FormatUint(bToMb(m.Alloc), 10), | ||
sysmem: strconv.FormatUint(bToMb(m.Sys), 10), | ||
goroutines: strconv.Itoa(runtime.NumGoroutine()), | ||
} | ||
return props | ||
} | ||
|
||
func (p *PerfProfile) GetCPUUsage() (map[string]string, error) { //nolint unnamed results are fine | ||
props := make(map[string]string) | ||
if p.usage == nil { | ||
return props, ErrNotInitialized | ||
} | ||
|
||
p.perflock.Lock() | ||
defer p.perflock.Unlock() | ||
var currentUsage syscall.Rusage | ||
err := syscall.Getrusage(syscall.RUSAGE_SELF, ¤tUsage) | ||
if err != nil { | ||
return props, fmt.Errorf("failed to get rusage: %w", err) | ||
} | ||
|
||
userTime := (currentUsage.Utime.Sec - p.usage.Utime.Sec) | ||
userTime += int64(currentUsage.Utime.Usec-p.usage.Utime.Usec) >> microsecondBitShift | ||
|
||
sysTime := currentUsage.Stime.Sec - p.usage.Stime.Sec | ||
sysTime += int64(currentUsage.Stime.Usec-p.usage.Stime.Usec) >> microsecondBitShift | ||
|
||
p.usage = ¤tUsage | ||
|
||
props[userCPUSeconds] = strconv.FormatInt(userTime, 10) | ||
props[sysCPUSeconds] = strconv.FormatInt(sysTime, 10) | ||
|
||
return props, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package telemetry | ||
|
||
import ( | ||
"runtime" | ||
"strconv" | ||
) | ||
|
||
type PerfProfile struct{} | ||
|
||
func (p *PerfProfile) GetMemoryUsage() map[string]string { | ||
var m runtime.MemStats | ||
runtime.ReadMemStats(&m) | ||
props := map[string]string{ | ||
allocatedmem: strconv.FormatUint(bToMb(m.Alloc), 10), | ||
sysmem: strconv.FormatUint(bToMb(m.Sys), 10), | ||
goroutines: strconv.Itoa(runtime.NumGoroutine()), | ||
} | ||
return props | ||
} | ||
|
||
func NewPerfProfile() (*PerfProfile, error) { | ||
return &PerfProfile{}, nil | ||
} | ||
|
||
func (p *PerfProfile) GetCPUUsage() (map[string]string, error) { //nolint unnamed results are fine | ||
return make(map[string]string), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters