From 74ba33f1f95b7f6dd4ea5c58f3206b627baf545a Mon Sep 17 00:00:00 2001 From: ChrsMark Date: Fri, 8 Sep 2023 13:01:12 +0300 Subject: [PATCH] [processor/resourcedetection] Add support for host cpuinfo attributes **Description:** : Added support for host's cpuinfo attributes as part of the system resourcedetection. This information is retrieved from /proc/cpuinfo. **Link to tracking Issue:** #26532 Signed-off-by: ChrsMark --- .chloggen/add_host_cpuinfo.yaml | 27 ++++++++++++ .../resourcedetectionprocessor/README.md | 6 +++ processor/resourcedetectionprocessor/go.mod | 8 ++++ processor/resourcedetectionprocessor/go.sum | 22 ++++++++++ .../internal/metadata/generated_config.go | 34 ++++++++++++--- .../metadata/generated_config_test.go | 32 +++++++++----- .../internal/metadata/generated_resource.go | 42 +++++++++++++++++++ .../metadata/generated_resource_test.go | 38 ++++++++++++++++- .../internal/metadata/testdata/config.yaml | 24 +++++++++++ .../internal/system/metadata.yaml | 24 +++++++++++ .../internal/system/system.go | 34 +++++++++++++++ 11 files changed, 275 insertions(+), 16 deletions(-) create mode 100644 .chloggen/add_host_cpuinfo.yaml diff --git a/.chloggen/add_host_cpuinfo.yaml b/.chloggen/add_host_cpuinfo.yaml new file mode 100644 index 000000000000..0f628ed7fffe --- /dev/null +++ b/.chloggen/add_host_cpuinfo.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: processor/resourcedetection + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Added support for host's cpuinfo attributes. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [26532] + +# (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: In Linux and Darwin all fields are populated. In Windows only family, vendor.id and model.name are populated. + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/processor/resourcedetectionprocessor/README.md b/processor/resourcedetectionprocessor/README.md index 7fc00ffd543d..eff4e1e3181e 100644 --- a/processor/resourcedetectionprocessor/README.md +++ b/processor/resourcedetectionprocessor/README.md @@ -48,6 +48,12 @@ Queries the host machine to retrieve the following resource attributes: * host.arch * host.name * host.id + * host.cpu.vendor.id + * host.cpu.family + * host.cpu.model.id + * host.cpu.model.name + * host.cpu.stepping + * host.cpu.cache.l2.size * os.description * os.type diff --git a/processor/resourcedetectionprocessor/go.mod b/processor/resourcedetectionprocessor/go.mod index 3838c4aa30a5..9bf765c68419 100644 --- a/processor/resourcedetectionprocessor/go.mod +++ b/processor/resourcedetectionprocessor/go.mod @@ -10,6 +10,7 @@ require ( github.com/hashicorp/consul/api v1.24.0 github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.85.0 github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.85.0 + github.com/shirou/gopsutil/v3 v3.23.7 github.com/stretchr/testify v1.8.4 go.opentelemetry.io/collector/component v0.85.0 go.opentelemetry.io/collector/config/confighttp v0.85.0 @@ -44,6 +45,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -65,6 +67,7 @@ require ( github.com/klauspost/compress v1.16.7 // indirect github.com/knadh/koanf v1.5.0 // indirect github.com/knadh/koanf/v2 v2.0.1 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect @@ -80,8 +83,13 @@ require ( github.com/opencontainers/image-spec v1.0.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/rs/cors v1.10.0 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/stretchr/objx v0.5.0 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector v0.85.0 // indirect go.opentelemetry.io/collector/config/configauth v0.85.0 // indirect diff --git a/processor/resourcedetectionprocessor/go.sum b/processor/resourcedetectionprocessor/go.sum index 779008f78fd0..fd67a8fb733d 100644 --- a/processor/resourcedetectionprocessor/go.sum +++ b/processor/resourcedetectionprocessor/go.sum @@ -99,6 +99,8 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -252,6 +254,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -327,6 +331,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= @@ -355,6 +361,12 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4= +github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -377,11 +389,17 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= @@ -505,6 +523,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -520,6 +539,7 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -537,6 +557,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config.go index 3abbed5b3b13..cb568878dcce 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config.go @@ -9,11 +9,17 @@ type ResourceAttributeConfig struct { // ResourceAttributesConfig provides config for resourcedetectionprocessor/system resource attributes. type ResourceAttributesConfig struct { - HostArch ResourceAttributeConfig `mapstructure:"host.arch"` - HostID ResourceAttributeConfig `mapstructure:"host.id"` - HostName ResourceAttributeConfig `mapstructure:"host.name"` - OsDescription ResourceAttributeConfig `mapstructure:"os.description"` - OsType ResourceAttributeConfig `mapstructure:"os.type"` + HostArch ResourceAttributeConfig `mapstructure:"host.arch"` + HostCPUCacheL2Size ResourceAttributeConfig `mapstructure:"host.cpu.cache.l2.size"` + HostCPUFamily ResourceAttributeConfig `mapstructure:"host.cpu.family"` + HostCPUModelID ResourceAttributeConfig `mapstructure:"host.cpu.model.id"` + HostCPUModelName ResourceAttributeConfig `mapstructure:"host.cpu.model.name"` + HostCPUStepping ResourceAttributeConfig `mapstructure:"host.cpu.stepping"` + HostCPUVendorID ResourceAttributeConfig `mapstructure:"host.cpu.vendor.id"` + HostID ResourceAttributeConfig `mapstructure:"host.id"` + HostName ResourceAttributeConfig `mapstructure:"host.name"` + OsDescription ResourceAttributeConfig `mapstructure:"os.description"` + OsType ResourceAttributeConfig `mapstructure:"os.type"` } func DefaultResourceAttributesConfig() ResourceAttributesConfig { @@ -21,6 +27,24 @@ func DefaultResourceAttributesConfig() ResourceAttributesConfig { HostArch: ResourceAttributeConfig{ Enabled: false, }, + HostCPUCacheL2Size: ResourceAttributeConfig{ + Enabled: false, + }, + HostCPUFamily: ResourceAttributeConfig{ + Enabled: false, + }, + HostCPUModelID: ResourceAttributeConfig{ + Enabled: false, + }, + HostCPUModelName: ResourceAttributeConfig{ + Enabled: false, + }, + HostCPUStepping: ResourceAttributeConfig{ + Enabled: false, + }, + HostCPUVendorID: ResourceAttributeConfig{ + Enabled: false, + }, HostID: ResourceAttributeConfig{ Enabled: false, }, diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config_test.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config_test.go index afa17c54c8a9..343eef8d19fb 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config_test.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_config_test.go @@ -25,21 +25,33 @@ func TestResourceAttributesConfig(t *testing.T) { { name: "all_set", want: ResourceAttributesConfig{ - HostArch: ResourceAttributeConfig{Enabled: true}, - HostID: ResourceAttributeConfig{Enabled: true}, - HostName: ResourceAttributeConfig{Enabled: true}, - OsDescription: ResourceAttributeConfig{Enabled: true}, - OsType: ResourceAttributeConfig{Enabled: true}, + HostArch: ResourceAttributeConfig{Enabled: true}, + HostCPUCacheL2Size: ResourceAttributeConfig{Enabled: true}, + HostCPUFamily: ResourceAttributeConfig{Enabled: true}, + HostCPUModelID: ResourceAttributeConfig{Enabled: true}, + HostCPUModelName: ResourceAttributeConfig{Enabled: true}, + HostCPUStepping: ResourceAttributeConfig{Enabled: true}, + HostCPUVendorID: ResourceAttributeConfig{Enabled: true}, + HostID: ResourceAttributeConfig{Enabled: true}, + HostName: ResourceAttributeConfig{Enabled: true}, + OsDescription: ResourceAttributeConfig{Enabled: true}, + OsType: ResourceAttributeConfig{Enabled: true}, }, }, { name: "none_set", want: ResourceAttributesConfig{ - HostArch: ResourceAttributeConfig{Enabled: false}, - HostID: ResourceAttributeConfig{Enabled: false}, - HostName: ResourceAttributeConfig{Enabled: false}, - OsDescription: ResourceAttributeConfig{Enabled: false}, - OsType: ResourceAttributeConfig{Enabled: false}, + HostArch: ResourceAttributeConfig{Enabled: false}, + HostCPUCacheL2Size: ResourceAttributeConfig{Enabled: false}, + HostCPUFamily: ResourceAttributeConfig{Enabled: false}, + HostCPUModelID: ResourceAttributeConfig{Enabled: false}, + HostCPUModelName: ResourceAttributeConfig{Enabled: false}, + HostCPUStepping: ResourceAttributeConfig{Enabled: false}, + HostCPUVendorID: ResourceAttributeConfig{Enabled: false}, + HostID: ResourceAttributeConfig{Enabled: false}, + HostName: ResourceAttributeConfig{Enabled: false}, + OsDescription: ResourceAttributeConfig{Enabled: false}, + OsType: ResourceAttributeConfig{Enabled: false}, }, }, } diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go index b28dc2be6b0c..15cb068bc720 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go @@ -28,6 +28,48 @@ func (rb *ResourceBuilder) SetHostArch(val string) { } } +// SetHostCPUCacheL2Size sets provided value as "host.cpu.cache.l2.size" attribute. +func (rb *ResourceBuilder) SetHostCPUCacheL2Size(val int64) { + if rb.config.HostCPUCacheL2Size.Enabled { + rb.res.Attributes().PutInt("host.cpu.cache.l2.size", val) + } +} + +// SetHostCPUFamily sets provided value as "host.cpu.family" attribute. +func (rb *ResourceBuilder) SetHostCPUFamily(val int64) { + if rb.config.HostCPUFamily.Enabled { + rb.res.Attributes().PutInt("host.cpu.family", val) + } +} + +// SetHostCPUModelID sets provided value as "host.cpu.model.id" attribute. +func (rb *ResourceBuilder) SetHostCPUModelID(val int64) { + if rb.config.HostCPUModelID.Enabled { + rb.res.Attributes().PutInt("host.cpu.model.id", val) + } +} + +// SetHostCPUModelName sets provided value as "host.cpu.model.name" attribute. +func (rb *ResourceBuilder) SetHostCPUModelName(val string) { + if rb.config.HostCPUModelName.Enabled { + rb.res.Attributes().PutStr("host.cpu.model.name", val) + } +} + +// SetHostCPUStepping sets provided value as "host.cpu.stepping" attribute. +func (rb *ResourceBuilder) SetHostCPUStepping(val int64) { + if rb.config.HostCPUStepping.Enabled { + rb.res.Attributes().PutInt("host.cpu.stepping", val) + } +} + +// SetHostCPUVendorID sets provided value as "host.cpu.vendor.id" attribute. +func (rb *ResourceBuilder) SetHostCPUVendorID(val string) { + if rb.config.HostCPUVendorID.Enabled { + rb.res.Attributes().PutStr("host.cpu.vendor.id", val) + } +} + // SetHostID sets provided value as "host.id" attribute. func (rb *ResourceBuilder) SetHostID(val string) { if rb.config.HostID.Enabled { diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go index c3400645e1eb..77de906301f9 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource_test.go @@ -14,6 +14,12 @@ func TestResourceBuilder(t *testing.T) { cfg := loadResourceAttributesConfig(t, test) rb := NewResourceBuilder(cfg) rb.SetHostArch("host.arch-val") + rb.SetHostCPUCacheL2Size(22) + rb.SetHostCPUFamily(15) + rb.SetHostCPUModelID(17) + rb.SetHostCPUModelName("host.cpu.model.name-val") + rb.SetHostCPUStepping(17) + rb.SetHostCPUVendorID("host.cpu.vendor.id-val") rb.SetHostID("host.id-val") rb.SetHostName("host.name-val") rb.SetOsDescription("os.description-val") @@ -26,7 +32,7 @@ func TestResourceBuilder(t *testing.T) { case "default": assert.Equal(t, 2, res.Attributes().Len()) case "all_set": - assert.Equal(t, 5, res.Attributes().Len()) + assert.Equal(t, 11, res.Attributes().Len()) case "none_set": assert.Equal(t, 0, res.Attributes().Len()) return @@ -39,6 +45,36 @@ func TestResourceBuilder(t *testing.T) { if ok { assert.EqualValues(t, "host.arch-val", val.Str()) } + val, ok = res.Attributes().Get("host.cpu.cache.l2.size") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, 22, val.Int()) + } + val, ok = res.Attributes().Get("host.cpu.family") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, 15, val.Int()) + } + val, ok = res.Attributes().Get("host.cpu.model.id") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, 17, val.Int()) + } + val, ok = res.Attributes().Get("host.cpu.model.name") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "host.cpu.model.name-val", val.Str()) + } + val, ok = res.Attributes().Get("host.cpu.stepping") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, 17, val.Int()) + } + val, ok = res.Attributes().Get("host.cpu.vendor.id") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "host.cpu.vendor.id-val", val.Str()) + } val, ok = res.Attributes().Get("host.id") assert.Equal(t, test == "all_set", ok) if ok { diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/testdata/config.yaml b/processor/resourcedetectionprocessor/internal/system/internal/metadata/testdata/config.yaml index 83e04b4548f7..94a441d4590e 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/testdata/config.yaml +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/testdata/config.yaml @@ -3,6 +3,18 @@ all_set: resource_attributes: host.arch: enabled: true + host.cpu.cache.l2.size: + enabled: true + host.cpu.family: + enabled: true + host.cpu.model.id: + enabled: true + host.cpu.model.name: + enabled: true + host.cpu.stepping: + enabled: true + host.cpu.vendor.id: + enabled: true host.id: enabled: true host.name: @@ -15,6 +27,18 @@ none_set: resource_attributes: host.arch: enabled: false + host.cpu.cache.l2.size: + enabled: false + host.cpu.family: + enabled: false + host.cpu.model.id: + enabled: false + host.cpu.model.name: + enabled: false + host.cpu.stepping: + enabled: false + host.cpu.vendor.id: + enabled: false host.id: enabled: false host.name: diff --git a/processor/resourcedetectionprocessor/internal/system/metadata.yaml b/processor/resourcedetectionprocessor/internal/system/metadata.yaml index f34204318193..8cc1b760097a 100644 --- a/processor/resourcedetectionprocessor/internal/system/metadata.yaml +++ b/processor/resourcedetectionprocessor/internal/system/metadata.yaml @@ -23,3 +23,27 @@ resource_attributes: description: The host.arch type: string enabled: false + host.cpu.vendor.id: + description: The host.cpu.vendor.id + type: string + enabled: false + host.cpu.family: + description: The host.cpu.family + type: int + enabled: false + host.cpu.model.id: + description: The host.cpu.model.id + type: int + enabled: false + host.cpu.model.name: + description: The host.cpu.model.name + type: string + enabled: false + host.cpu.stepping: + description: The host.cpu.stepping + type: int + enabled: false + host.cpu.cache.l2.size: + description: The host.cpu.cache.l2.size + type: int + enabled: false diff --git a/processor/resourcedetectionprocessor/internal/system/system.go b/processor/resourcedetectionprocessor/internal/system/system.go index 0366b6288709..9b6fa25bc64c 100644 --- a/processor/resourcedetectionprocessor/internal/system/system.go +++ b/processor/resourcedetectionprocessor/internal/system/system.go @@ -7,7 +7,9 @@ import ( "context" "errors" "fmt" + "strconv" + "github.com/shirou/gopsutil/v3/cpu" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor" conventions "go.opentelemetry.io/collector/semconv/v1.6.1" @@ -74,6 +76,11 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return pcommon.NewResource(), "", fmt.Errorf("failed getting OS description: %w", err) } + cpuInfo, err := cpu.Info() + if err != nil { + return pcommon.NewResource(), "", fmt.Errorf("failed getting host cpuinfo: %w", err) + } + for _, source := range d.cfg.HostnameSources { getHostFromSource := hostnameSourcesMap[source] hostname, err = getHostFromSource(d) @@ -89,6 +96,12 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem } d.rb.SetHostArch(hostArch) d.rb.SetOsDescription(osDescription) + if len(cpuInfo) > 0 { + err = setHostCPUInfo(d, cpuInfo[0]) + if err != nil { + d.logger.Warn("failed to get host cpuinfo", zap.Error(err)) + } + } return d.rb.Emit(), conventions.SchemaURL, nil } d.logger.Debug(err.Error()) @@ -130,3 +143,24 @@ func reverseLookupHost(d *Detector) (string, error) { } return hostname, nil } + +func setHostCPUInfo(d *Detector, cpuInfo cpu.InfoStat) error { + d.logger.Debug("getting host's cpuinfo", zap.String("coreID", cpuInfo.CoreID)) + d.rb.SetHostCPUVendorID(cpuInfo.VendorID) + family, err := strconv.ParseInt(cpuInfo.Family, 10, 64) + if err != nil { + return fmt.Errorf("failed to convert cpuinfo family to integer: %w", err) + } + d.rb.SetHostCPUFamily(family) + + model, err := strconv.ParseInt(cpuInfo.Model, 10, 64) + if err != nil { + return fmt.Errorf("failed to convert cpuinfo model to integer: %w", err) + } + d.rb.SetHostCPUModelID(model) + + d.rb.SetHostCPUModelName(cpuInfo.ModelName) + d.rb.SetHostCPUStepping(int64(cpuInfo.Stepping)) + d.rb.SetHostCPUCacheL2Size(int64(cpuInfo.CacheSize)) + return nil +}