terraform/vendor/github.com/newrelic/go-agent/internal/utilization/utilization.go

141 lines
3.3 KiB
Go

// Package utilization implements the Utilization spec, available at
// https://source.datanerd.us/agents/agent-specs/blob/master/Utilization.md
package utilization
import (
"runtime"
"github.com/newrelic/go-agent/internal/logger"
"github.com/newrelic/go-agent/internal/sysinfo"
)
const metadataVersion = 2
// Config controls the behavior of utilization information capture.
type Config struct {
DetectAWS bool
DetectDocker bool
LogicalProcessors int
TotalRAMMIB int
BillingHostname string
}
type override struct {
LogicalProcessors *int `json:"logical_processors,omitempty"`
TotalRAMMIB *int `json:"total_ram_mib,omitempty"`
BillingHostname string `json:"hostname,omitempty"`
}
// Data contains utilization system information.
type Data struct {
MetadataVersion int `json:"metadata_version"`
LogicalProcessors int `json:"logical_processors"`
RAMMib *uint64 `json:"total_ram_mib"`
Hostname string `json:"hostname"`
Vendors *vendors `json:"vendors,omitempty"`
Config *override `json:"config,omitempty"`
}
var (
sampleRAMMib = uint64(1024)
// SampleData contains sample utilization data useful for testing.
SampleData = Data{
MetadataVersion: metadataVersion,
LogicalProcessors: 16,
RAMMib: &sampleRAMMib,
Hostname: "my-hostname",
}
)
type vendor struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Zone string `json:"zone,omitempty"`
}
type vendors struct {
AWS *vendor `json:"aws,omitempty"`
Docker *vendor `json:"docker,omitempty"`
}
func overrideFromConfig(config Config) *override {
ov := &override{}
if 0 != config.LogicalProcessors {
x := config.LogicalProcessors
ov.LogicalProcessors = &x
}
if 0 != config.TotalRAMMIB {
x := config.TotalRAMMIB
ov.TotalRAMMIB = &x
}
ov.BillingHostname = config.BillingHostname
if "" == ov.BillingHostname &&
nil == ov.LogicalProcessors &&
nil == ov.TotalRAMMIB {
ov = nil
}
return ov
}
// Gather gathers system utilization data.
func Gather(config Config, lg logger.Logger) *Data {
uDat := Data{
MetadataVersion: metadataVersion,
Vendors: &vendors{},
LogicalProcessors: runtime.NumCPU(),
}
if config.DetectDocker {
id, err := sysinfo.DockerID()
if err != nil &&
err != sysinfo.ErrDockerUnsupported &&
err != sysinfo.ErrDockerNotFound {
lg.Warn("error gathering Docker information", map[string]interface{}{
"error": err.Error(),
})
} else if id != "" {
uDat.Vendors.Docker = &vendor{ID: id}
}
}
if config.DetectAWS {
aws, err := getAWS()
if nil == err {
uDat.Vendors.AWS = aws
} else if isAWSValidationError(err) {
lg.Warn("AWS validation error", map[string]interface{}{
"error": err.Error(),
})
}
}
if uDat.Vendors.AWS == nil && uDat.Vendors.Docker == nil {
uDat.Vendors = nil
}
host, err := sysinfo.Hostname()
if nil == err {
uDat.Hostname = host
} else {
lg.Warn("error getting hostname", map[string]interface{}{
"error": err.Error(),
})
}
bts, err := sysinfo.PhysicalMemoryBytes()
if nil == err {
mib := sysinfo.BytesToMebibytes(bts)
uDat.RAMMib = &mib
} else {
lg.Warn("error getting memory", map[string]interface{}{
"error": err.Error(),
})
}
uDat.Config = overrideFromConfig(config)
return &uDat
}