-
Notifications
You must be signed in to change notification settings - Fork 55
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 4 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,83 @@ | ||
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 &CPUMemStat{} | ||
}) | ||
RegisterClientMetric("cpumem", func() interface{} { | ||
return &CPUMemStat{} | ||
}) | ||
} | ||
|
||
// CPUMemStat measures CPU usage and Memory usage and record in the metric logs. | ||
type CPUMemStat struct { | ||
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 renaming it to just |
||
mods *modules.Modules | ||
} | ||
|
||
// InitModule gives the module access to the other modules. | ||
func (c *CPUMemStat) 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 |
||
// Percent with 0 interval returns 0 usage when called first time. | ||
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 this comment should be more descriptive. Maybe:
|
||
_, err := cpu.Percent(0, false) | ||
if err != nil { | ||
c.mods.Logger().Info("Unable to fetch the CPU usage") | ||
} | ||
} | ||
|
||
// getCPUsage Method returns the average CPU per core and the number of cores, including logical ones. | ||
func (c *CPUMemStat) getCPUsage() (float64, uint32) { | ||
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 would rename this method to |
||
// 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 *CPUMemStat) 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 *CPUMemStat) 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.
|
||
cpusage, cores := c.getCPUsage() | ||
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. Make sure to use |
||
availablemem, memusage := c.getMemoryPercentage() | ||
event := &types.CPUMemoryStats{ | ||
Event: types.NewReplicaEvent(uint32(c.mods.ID()), now), | ||
CPUsagePercentage: cpusage, | ||
Cores: uint32(cores), | ||
MemoryUsagePercentage: memusage, | ||
AvailableMemory: availablemem, | ||
} | ||
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.