Skip to content
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

[pkg/inframetadata] Add support for host.cpu attributes #174

Merged
merged 2 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .chloggen/mx-psi_cpu-model.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component (e.g. pkg/quantile)
component: pkg/inframetadata

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add support for host.cpu resource attributes

# The PR related to this change
issues: [174]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
6 changes: 6 additions & 0 deletions pkg/inframetadata/gohai/gohai.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ func (p *Payload) Platform() map[string]string {
return p.Gohai.Gohai.Platform.(map[string]string)
}

// CPU returns a reference to the Gohai payload 'cpu' map.
func (p *Payload) CPU() map[string]string {
return p.Gohai.Gohai.CPU.(map[string]string)
}

// gohaiSerializer implements json.Marshaler and json.Unmarshaler on top of a gohai payload
type gohaiMarshaler struct {
Gohai *Gohai
Expand Down Expand Up @@ -81,6 +86,7 @@ func NewEmpty() Payload {
Gohai: gohaiMarshaler{
Gohai: &Gohai{
Platform: map[string]string{},
CPU: map[string]string{},
},
},
}
Expand Down
35 changes: 34 additions & 1 deletion pkg/inframetadata/internal/hostmap/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
conventions "go.opentelemetry.io/collector/semconv/v1.18.0"
)

// Custom attributes not in the OpenTelemetry specification
// Platform related OpenTelemetry Semantic Conventions for resource attributes.
// These are NOT in the specification and will be submitted for approval.
const (
attributeKernelName = "os.kernel.name"
attributeKernelRelease = "os.kernel.release"
Expand Down Expand Up @@ -39,3 +40,35 @@ var platformAttributesMap map[string]string = map[string]string{
fieldPlatformKernelRelease: attributeKernelRelease,
fieldPlatformKernelVersion: attributeKernelVersion,
}

// CPU related OpenTelemetry Semantic Conventions for resource attributes.
// TODO: Replace by conventions constants once available.
const (
attributeHostCPUVendorID = "host.cpu.vendor.id"
attributeHostCPUModelName = "host.cpu.model.name"
attributeHostCPUFamily = "host.cpu.family"
attributeHostCPUModelID = "host.cpu.model.id"
attributeHostCPUStepping = "host.cpu.stepping"
attributeHostCPUCacheL2Size = "host.cpu.cache.l2.size"
)

// This set of constants represent fields in the Gohai payload's CPU field.
const (
fieldCPUVendorID = "vendor_id"
fieldCPUModelName = "model_name"
fieldCPUCacheSize = "cache_size"
fieldCPUFamily = "family"
fieldCPUModel = "model"
fieldCPUStepping = "stepping"
)

// cpuAttributesMap defines the mapping between Gohai fieldCPU fields
// and resource attribute names (semantic conventions or not).
var cpuAttributesMap map[string]string = map[string]string{
fieldCPUVendorID: attributeHostCPUVendorID,
fieldCPUModelName: attributeHostCPUModelName,
fieldCPUCacheSize: attributeHostCPUCacheL2Size,
fieldCPUFamily: attributeHostCPUFamily,
fieldCPUModel: attributeHostCPUModelID,
fieldCPUStepping: attributeHostCPUStepping,
}
27 changes: 24 additions & 3 deletions pkg/inframetadata/internal/hostmap/hostmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ func New() *HostMap {
}
}

// strField gets a string-typed field from a resource attribute map.
// strField gets a field as string from a resource attribute map.
// It can handle fields of type "Str" and "Int".
// It returns:
// - The field's value, if available
// - Whether the field was present in the map
Expand All @@ -43,10 +44,18 @@ func strField(m pcommon.Map, key string) (string, bool, error) {
// Field not available, don't update but don't fail either
return "", false, nil
}
if val.Type() != pcommon.ValueTypeStr {

var value string
switch val.Type() {
case pcommon.ValueTypeStr:
value = val.Str()
case pcommon.ValueTypeInt:
mx-psi marked this conversation as resolved.
Show resolved Hide resolved
value = val.AsString()
default:
return "", false, fmt.Errorf("%q has type %q, expected type \"Str\" instead", key, val.Type())
}
return val.Str(), true, nil

return value, true, nil
}

// isAWS checks if a resource attribute map
Expand Down Expand Up @@ -157,6 +166,18 @@ func (m *HostMap) Update(host string, res pcommon.Resource) (changed bool, md pa
}
}

// Gohai - CPU
for field, attribute := range cpuAttributesMap {
strVal, ok, fieldErr := strField(res.Attributes(), attribute)
if fieldErr != nil {
err = multierr.Append(err, fieldErr)
} else if ok {
old := md.CPU()[field]
changed = changed || old != strVal
md.CPU()[field] = strVal
}
}

m.hosts[host] = md
changed = changed && found
return
Expand Down
21 changes: 17 additions & 4 deletions pkg/inframetadata/internal/hostmap/hostmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ func TestUpdate(t *testing.T) {
attributeKernelName: "GNU/Linux",
attributeKernelRelease: "5.19.0-43-generic",
attributeKernelVersion: "#44~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon May 22 13:39:36 UTC 2",
attributeHostCPUVendorID: "GenuineIntel",
attributeHostCPUFamily: 6,
attributeHostCPUModelID: 10,
attributeHostCPUModelName: "11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz",
attributeHostCPUStepping: 1,
attributeHostCPUCacheL2Size: 12288000,
},
expectedChanged: false,
},
Expand Down Expand Up @@ -73,13 +79,13 @@ func TestUpdate(t *testing.T) {
conventions.AttributeHostName: "host-1-hostname",
conventions.AttributeOSDescription: true, // wrong type
conventions.AttributeHostArch: conventions.AttributeHostArchAMD64,
attributeKernelName: 1, // wrong type
attributeKernelName: false, // wrong type
attributeKernelRelease: "5.19.0-43-generic",
},
expectedChanged: false,
expectedErrs: []string{
"\"os.description\" has type \"Bool\", expected type \"Str\" instead",
"\"os.kernel.name\" has type \"Int\", expected type \"Str\" instead",
"\"os.kernel.name\" has type \"Bool\", expected type \"Str\" instead",
},
},
{
Expand Down Expand Up @@ -132,7 +138,14 @@ func TestUpdate(t *testing.T) {
fieldPlatformKernelRelease: "5.19.0-43-generic",
fieldPlatformKernelVersion: "#82~18.04.1-Ubuntu SMP Fri Apr 16 15:10:02 UTC 2021",
})
assert.Nil(t, md.Payload.Gohai.Gohai.CPU)
assert.Equal(t, md.Payload.Gohai.Gohai.CPU, map[string]string{
fieldCPUCacheSize: "12288000",
fieldCPUFamily: "6",
fieldCPUModel: "10",
fieldCPUModelName: "11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz",
fieldCPUStepping: "1",
fieldCPUVendorID: "GenuineIntel",
})
assert.Nil(t, md.Payload.Gohai.Gohai.FileSystem)
assert.Nil(t, md.Payload.Gohai.Gohai.Memory)
assert.Nil(t, md.Payload.Gohai.Gohai.Network)
Expand All @@ -152,7 +165,7 @@ func TestUpdate(t *testing.T) {
fieldPlatformMachine: "arm64",
fieldPlatformHardwarePlatform: "arm64",
})
assert.Nil(t, md.Payload.Gohai.Gohai.CPU)
assert.Empty(t, md.Payload.Gohai.Gohai.CPU)
assert.Nil(t, md.Payload.Gohai.Gohai.FileSystem)
assert.Nil(t, md.Payload.Gohai.Gohai.Memory)
assert.Nil(t, md.Payload.Gohai.Gohai.Network)
Expand Down
Loading