-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial commit for cpu stats #63
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package metrics | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/relab/hotstuff/metrics/types" | ||
"github.com/relab/hotstuff/modules" | ||
"github.com/shirou/gopsutil/v3/cpu" | ||
"github.com/shirou/gopsutil/v3/mem" | ||
) | ||
|
||
// CPUMem metics measures the percentage of cpu and memory utilization on the node. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is kind of important info for a user. As is, it will not be shown in the package documentation or elsewhere except in the source code. Please move this doc to the Note: Some typos in this text: |
||
// If multiple replicas are run on the same node, then the data may be duplicated. | ||
// This is not enabled by default, to enable this metric add "cpumem" string to --metrics option. | ||
// Since it can interfere with the performance of the protocol, do not enable this metics unless required. | ||
// Interval for measuring the cpu and memory utilization should be above 100 milliseconds, for valid data collection. | ||
// This limitation is due to the gopsutil package. | ||
func init() { | ||
RegisterReplicaMetric("cpumem", func() interface{} { | ||
return &CPUMem{} | ||
}) | ||
RegisterClientMetric("cpumem", func() interface{} { | ||
return &CPUMem{} | ||
}) | ||
} | ||
|
||
// CPUMem measures CPU usage and Memory usage and record in the metric logs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CPUMem measures CPU and memory usage and records these in the metrics logs. |
||
type CPUMem struct { | ||
mods *modules.Modules | ||
} | ||
|
||
// InitModule gives the module access to the other modules. | ||
func (c *CPUMem) InitModule(mods *modules.Modules) { | ||
c.mods = mods | ||
c.mods.EventLoop().RegisterObserver(types.TickEvent{}, func(event interface{}) { | ||
c.tick(event.(types.TickEvent)) | ||
}) | ||
c.mods.Logger().Info("CPU-Memory stats metric enabled") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CPU-Memory metric enabled |
||
// The cpu.Percent function returns the CPU usage since the last call when called with an interval of 0. | ||
// This initial call ensures that the first measurement of the CPU usage is nonzero. | ||
_, err := cpu.Percent(0, false) | ||
if err != nil { | ||
c.mods.Logger().Info("Unable to fetch the CPU usage") | ||
} | ||
} | ||
|
||
// getCPUPercentage Method returns the average CPU per core and the number of cores, including logical ones. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // getCPUPercentage returns the average CPU per core and the number of logical cores. |
||
func (c *CPUMem) getCPUPercentage() (float64, uint32) { | ||
// Counts return the number of cores as our bbchain cluster has hyper-threading enabled, | ||
// logical parameter is set to true. | ||
cores, err := cpu.Counts(true) | ||
if err != nil { | ||
return 0, 0 | ||
} | ||
usage, err := cpu.Percent(0, false) | ||
if err != nil { | ||
return 0, uint32(cores) | ||
} | ||
return usage[0], uint32(cores) | ||
} | ||
|
||
// getMemoryPercentage returns total memory available on the node and the currently utilized percentage. | ||
func (c *CPUMem) getMemoryPercentage() (uint64, float64) { | ||
v, err := mem.VirtualMemory() | ||
if err != nil { | ||
return 0, 0 | ||
} | ||
return v.Available, v.UsedPercent | ||
} | ||
|
||
// tick method is invoked periodically based on the configured measuring interval of metrics | ||
func (c *CPUMem) tick(_ types.TickEvent) { | ||
now := time.Now() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
cpu, cores := c.getCPUPercentage() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we don't need the two helper methods |
||
availableMemory, memoryUsage := c.getMemoryPercentage() | ||
event := &types.CPUMemoryStats{ | ||
Event: types.NewReplicaEvent(uint32(c.mods.ID()), now), | ||
CPUPercentage: cpu, | ||
Cores: uint32(cores), | ||
MemoryPercentage: memoryUsage, | ||
AvailableMemory: availableMemory, | ||
} | ||
c.mods.MetricsLogger().Log(event) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this file covers both
replica
andclient
CPU and memory metrics, I suggest renaming the file tocpumem.go
instead.