Skip to content

Commit

Permalink
chore: add flag
Browse files Browse the repository at this point in the history
  • Loading branch information
VihasMakwana committed Nov 26, 2024
1 parent ffce161 commit d7c3ff5
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 10 deletions.
21 changes: 16 additions & 5 deletions metric/cpu/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ The below code implements a "metrics tracker" that gives us the ability to
calculate CPU percentages, as we average usage across a time period.
*/

type option struct {
usePerformanceCounter bool
}

type OptionFunc func(*option)

func WithPerformanceCounter() OptionFunc {
return func(o *option) {
o.usePerformanceCounter = true
}
}

// Monitor is used to monitor the overall CPU usage of the system over time.
type Monitor struct {
lastSample CPUMetrics
Expand All @@ -98,8 +110,8 @@ func New(hostfs resolve.Resolver) *Monitor {

// Fetch collects a new sample of the CPU usage metrics.
// This will overwrite the currently stored samples.
func (m *Monitor) Fetch() (Metrics, error) {
metric, err := Get(m.Hostfs)
func (m *Monitor) Fetch(opts ...OptionFunc) (Metrics, error) {
metric, err := Get(m.Hostfs, opts...)
if err != nil {
return Metrics{}, fmt.Errorf("error fetching CPU metrics: %w", err)
}
Expand All @@ -112,9 +124,8 @@ func (m *Monitor) Fetch() (Metrics, error) {

// FetchCores collects a new sample of CPU usage metrics per-core
// This will overwrite the currently stored samples.
func (m *Monitor) FetchCores() ([]Metrics, error) {

metric, err := Get(m.Hostfs)
func (m *Monitor) FetchCores(opts ...OptionFunc) ([]Metrics, error) {
metric, err := Get(m.Hostfs, opts...)
if err != nil {
return nil, fmt.Errorf("error fetching CPU metrics: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion metric/cpu/metrics_aix.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func tick2msec(val uint64) uint64 {
}

// Get returns a metrics object for CPU data
func Get(_ resolve.Resolver) (CPUMetrics, error) {
func Get(_ resolve.Resolver, _ ...OptionFunc) (CPUMetrics, error) {

totals, err := getCPUTotals()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion metric/cpu/metrics_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
)

// Get is the Darwin implementation of Get
func Get(_ resolve.Resolver) (CPUMetrics, error) {
func Get(_ resolve.Resolver, _ ...OptionFunc) (CPUMetrics, error) {
// We're using the gopsutil library here.
// The code used by both gosigar and go-sysinfo appears to be
// the same code as gopsutil, including copy-pasted comments.
Expand Down
2 changes: 1 addition & 1 deletion metric/cpu/metrics_openbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import (
)

// Get is the OpenBSD implementation of get
func Get(_ resolve.Resolver) (CPUMetrics, error) {
func Get(_ resolve.Resolver, _ ...OptionFunc) (CPUMetrics, error) {

// see man 2 sysctl
loadGlobal := [C.CPUSTATES]C.long{
Expand Down
2 changes: 1 addition & 1 deletion metric/cpu/metrics_procfs_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
)

// Get returns a metrics object for CPU data
func Get(procfs resolve.Resolver) (CPUMetrics, error) {
func Get(procfs resolve.Resolver, _ ...OptionFunc) (CPUMetrics, error) {
path := procfs.ResolveHostFS("/proc/stat")
fd, err := os.Open(path)
defer func() {
Expand Down
45 changes: 44 additions & 1 deletion metric/cpu/metrics_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/elastic/elastic-agent-libs/helpers/windows/pdh"
"github.com/elastic/elastic-agent-libs/opt"
"github.com/elastic/elastic-agent-system-metrics/metric/system/resolve"
"github.com/elastic/gosigar/sys/windows"
)

var (
Expand All @@ -41,7 +42,14 @@ var (
var query, qError = buildQuery()

// Get fetches Windows CPU system times
func Get(_ resolve.Resolver) (CPUMetrics, error) {
func Get(_ resolve.Resolver, opts ...OptionFunc) (CPUMetrics, error) {
op := option{}
for _, o := range opts {
o(&op)
}
if !op.usePerformanceCounter {
return defaultGet()
}
globalMetrics := CPUMetrics{}
if qError != nil {
return globalMetrics, qError
Expand Down Expand Up @@ -107,3 +115,38 @@ func buildQuery() (pdh.Query, error) {
}
return q, nil
}

func defaultGet() (CPUMetrics, error) {
idle, kernel, user, err := windows.GetSystemTimes()
if err != nil {
return CPUMetrics{}, fmt.Errorf("call to GetSystemTimes failed: %w", err)
}

globalMetrics := CPUMetrics{}
//convert from duration to ticks
idleMetric := uint64(idle / time.Millisecond)
sysMetric := uint64(kernel / time.Millisecond)
userMetrics := uint64(user / time.Millisecond)
globalMetrics.totals.Idle = opt.UintWith(idleMetric)
globalMetrics.totals.Sys = opt.UintWith(sysMetric)
globalMetrics.totals.User = opt.UintWith(userMetrics)

// get per-cpu data
cpus, err := windows.NtQuerySystemProcessorPerformanceInformation()
if err != nil {
return CPUMetrics{}, fmt.Errorf("catll to NtQuerySystemProcessorPerformanceInformation failed: %w", err)
}
globalMetrics.list = make([]CPU, 0, len(cpus))
for _, cpu := range cpus {
idleMetric := uint64(cpu.IdleTime / time.Millisecond)
sysMetric := uint64(cpu.KernelTime / time.Millisecond)
userMetrics := uint64(cpu.UserTime / time.Millisecond)
globalMetrics.list = append(globalMetrics.list, CPU{
Idle: opt.UintWith(idleMetric),
Sys: opt.UintWith(sysMetric),
User: opt.UintWith(userMetrics),
})
}

return globalMetrics, nil
}

0 comments on commit d7c3ff5

Please sign in to comment.