Skip to content

Commit c26518e

Browse files
authored
[processor/resourcedetection] Add back host.name on GKE (#12355)
* [processor/resourcedetection] Add back `host.name` on GKE Before the detectors were unified, the `host.name` attribute could be fetched on GKE if using the `gce` detector, so this just restores back the ability to have this attribute. * Make GCEHostname call fallible
1 parent 8782bd5 commit c26518e

File tree

3 files changed

+89
-24
lines changed

3 files changed

+89
-24
lines changed

processor/resourcedetectionprocessor/internal/gcp/gcp.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"go.opentelemetry.io/collector/pdata/pcommon"
2525
conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
2626
"go.uber.org/multierr"
27+
"go.uber.org/zap"
2728

2829
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal"
2930
)
@@ -43,11 +44,15 @@ const (
4344
// * Google App Engine (GAE).
4445
// * Cloud Run.
4546
// * Cloud Functions.
46-
func NewDetector(_ component.ProcessorCreateSettings, _ internal.DetectorConfig) (internal.Detector, error) {
47-
return &detector{detector: gcp.NewDetector()}, nil
47+
func NewDetector(set component.ProcessorCreateSettings, _ internal.DetectorConfig) (internal.Detector, error) {
48+
return &detector{
49+
logger: set.Logger,
50+
detector: gcp.NewDetector(),
51+
}, nil
4852
}
4953

5054
type detector struct {
55+
logger *zap.Logger
5156
detector gcpDetector
5257
}
5358

@@ -56,7 +61,7 @@ func (d *detector) Detect(context.Context) (resource pcommon.Resource, schemaURL
5661
if !metadata.OnGCE() {
5762
return res, "", nil
5863
}
59-
b := &resourceBuilder{attrs: res.Attributes()}
64+
b := &resourceBuilder{logger: d.logger, attrs: res.Attributes()}
6065
b.attrs.InsertString(conventions.AttributeCloudProvider, conventions.AttributeCloudProviderGCP)
6166
b.add(conventions.AttributeCloudAccountID, d.detector.ProjectID)
6267

@@ -66,6 +71,8 @@ func (d *detector) Detect(context.Context) (resource pcommon.Resource, schemaURL
6671
b.addZoneOrRegion(d.detector.GKEAvailabilityZoneOrRegion)
6772
b.add(conventions.AttributeK8SClusterName, d.detector.GKEClusterName)
6873
b.add(conventions.AttributeHostID, d.detector.GKEHostID)
74+
// GCEHostname is fallible on GKE, since it's not available when using workload identity.
75+
b.addFallible(conventions.AttributeHostName, d.detector.GCEHostName)
6976
case gcp.CloudRun:
7077
b.attrs.InsertString(conventions.AttributeCloudPlatform, conventions.AttributeCloudPlatformGCPCloudRun)
7178
b.add(conventions.AttributeFaaSName, d.detector.FaaSName)
@@ -106,8 +113,9 @@ func (d *detector) Detect(context.Context) (resource pcommon.Resource, schemaURL
106113
// resourceBuilder simplifies constructing resources using GCP detection
107114
// library functions.
108115
type resourceBuilder struct {
109-
errs []error
110-
attrs pcommon.Map
116+
logger *zap.Logger
117+
errs []error
118+
attrs pcommon.Map
111119
}
112120

113121
func (r *resourceBuilder) add(key string, detect func() (string, error)) {
@@ -118,6 +126,15 @@ func (r *resourceBuilder) add(key string, detect func() (string, error)) {
118126
}
119127
}
120128

129+
// addFallible adds a detect function whose failures should be ignored
130+
func (r *resourceBuilder) addFallible(key string, detect func() (string, error)) {
131+
if v, err := detect(); err == nil {
132+
r.attrs.InsertString(key, v)
133+
} else {
134+
r.logger.Info("Fallible detector failed. This attribute will not be available.", zap.String("key", key), zap.Error(err))
135+
}
136+
}
137+
121138
// zoneAndRegion functions are expected to return zone, region, err.
122139
func (r *resourceBuilder) addZoneAndRegion(detect func() (string, string, error)) {
123140
if zone, region, err := detect(); err == nil {

processor/resourcedetectionprocessor/internal/gcp/gcp_test.go

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"go.opentelemetry.io/collector/component/componenttest"
2525
"go.opentelemetry.io/collector/pdata/pcommon"
2626
conventions "go.opentelemetry.io/collector/semconv/v1.6.1"
27+
"go.uber.org/zap"
2728

2829
"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal"
2930
)
@@ -40,31 +41,54 @@ func TestDetect(t *testing.T) {
4041
}{
4142
{
4243
desc: "zonal GKE cluster",
43-
detector: &detector{detector: &fakeGCPDetector{
44+
detector: newTestDetector(&fakeGCPDetector{
4445
projectID: "my-project",
4546
cloudPlatform: gcp.GKE,
47+
gceHostName: "my-gke-node-1234",
4648
gkeHostID: "1472385723456792345",
4749
gkeClusterName: "my-cluster",
4850
gkeAvailabilityZone: "us-central1-c",
49-
}},
51+
}),
5052
expectedResource: internal.NewResource(map[string]interface{}{
5153
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
5254
conventions.AttributeCloudAccountID: "my-project",
5355
conventions.AttributeCloudPlatform: conventions.AttributeCloudPlatformGCPKubernetesEngine,
5456
conventions.AttributeK8SClusterName: "my-cluster",
5557
conventions.AttributeCloudAvailabilityZone: "us-central1-c",
5658
conventions.AttributeHostID: "1472385723456792345",
59+
conventions.AttributeHostName: "my-gke-node-1234",
5760
}),
5861
},
5962
{
6063
desc: "regional GKE cluster",
61-
detector: &detector{detector: &fakeGCPDetector{
64+
detector: newTestDetector(&fakeGCPDetector{
65+
projectID: "my-project",
66+
cloudPlatform: gcp.GKE,
67+
gceHostName: "my-gke-node-1234",
68+
gkeHostID: "1472385723456792345",
69+
gkeClusterName: "my-cluster",
70+
gkeRegion: "us-central1",
71+
}),
72+
expectedResource: internal.NewResource(map[string]interface{}{
73+
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
74+
conventions.AttributeCloudAccountID: "my-project",
75+
conventions.AttributeCloudPlatform: conventions.AttributeCloudPlatformGCPKubernetesEngine,
76+
conventions.AttributeK8SClusterName: "my-cluster",
77+
conventions.AttributeCloudRegion: "us-central1",
78+
conventions.AttributeHostID: "1472385723456792345",
79+
conventions.AttributeHostName: "my-gke-node-1234",
80+
}),
81+
},
82+
{
83+
desc: "regional GKE cluster with workload identity",
84+
detector: newTestDetector(&fakeGCPDetector{
6285
projectID: "my-project",
6386
cloudPlatform: gcp.GKE,
87+
gceHostNameErr: fmt.Errorf("metadata endpoint is concealed"),
6488
gkeHostID: "1472385723456792345",
6589
gkeClusterName: "my-cluster",
6690
gkeRegion: "us-central1",
67-
}},
91+
}),
6892
expectedResource: internal.NewResource(map[string]interface{}{
6993
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
7094
conventions.AttributeCloudAccountID: "my-project",
@@ -76,15 +100,15 @@ func TestDetect(t *testing.T) {
76100
},
77101
{
78102
desc: "GCE",
79-
detector: &detector{detector: &fakeGCPDetector{
103+
detector: newTestDetector(&fakeGCPDetector{
80104
projectID: "my-project",
81105
cloudPlatform: gcp.GCE,
82106
gceHostID: "1472385723456792345",
83107
gceHostName: "my-gke-node-1234",
84108
gceHostType: "n1-standard1",
85109
gceAvailabilityZone: "us-central1-c",
86110
gceRegion: "us-central1",
87-
}},
111+
}),
88112
expectedResource: internal.NewResource(map[string]interface{}{
89113
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
90114
conventions.AttributeCloudAccountID: "my-project",
@@ -98,14 +122,14 @@ func TestDetect(t *testing.T) {
98122
},
99123
{
100124
desc: "Cloud Run",
101-
detector: &detector{detector: &fakeGCPDetector{
125+
detector: newTestDetector(&fakeGCPDetector{
102126
projectID: "my-project",
103127
cloudPlatform: gcp.CloudRun,
104128
faaSID: "1472385723456792345",
105129
faaSCloudRegion: "us-central1",
106130
faaSName: "my-service",
107131
faaSVersion: "123456",
108-
}},
132+
}),
109133
expectedResource: internal.NewResource(map[string]interface{}{
110134
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
111135
conventions.AttributeCloudAccountID: "my-project",
@@ -118,14 +142,14 @@ func TestDetect(t *testing.T) {
118142
},
119143
{
120144
desc: "Cloud Functions",
121-
detector: &detector{detector: &fakeGCPDetector{
145+
detector: newTestDetector(&fakeGCPDetector{
122146
projectID: "my-project",
123147
cloudPlatform: gcp.CloudFunctions,
124148
faaSID: "1472385723456792345",
125149
faaSCloudRegion: "us-central1",
126150
faaSName: "my-service",
127151
faaSVersion: "123456",
128-
}},
152+
}),
129153
expectedResource: internal.NewResource(map[string]interface{}{
130154
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
131155
conventions.AttributeCloudAccountID: "my-project",
@@ -138,15 +162,15 @@ func TestDetect(t *testing.T) {
138162
},
139163
{
140164
desc: "App Engine Standard",
141-
detector: &detector{detector: &fakeGCPDetector{
165+
detector: newTestDetector(&fakeGCPDetector{
142166
projectID: "my-project",
143167
cloudPlatform: gcp.AppEngineStandard,
144168
appEngineServiceInstance: "1472385723456792345",
145169
appEngineAvailabilityZone: "us-central1-c",
146170
appEngineRegion: "us-central1",
147171
appEngineServiceName: "my-service",
148172
appEngineServiceVersion: "123456",
149-
}},
173+
}),
150174
expectedResource: internal.NewResource(map[string]interface{}{
151175
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
152176
conventions.AttributeCloudAccountID: "my-project",
@@ -160,15 +184,15 @@ func TestDetect(t *testing.T) {
160184
},
161185
{
162186
desc: "App Engine Flex",
163-
detector: &detector{detector: &fakeGCPDetector{
187+
detector: newTestDetector(&fakeGCPDetector{
164188
projectID: "my-project",
165189
cloudPlatform: gcp.AppEngineFlex,
166190
appEngineServiceInstance: "1472385723456792345",
167191
appEngineAvailabilityZone: "us-central1-c",
168192
appEngineRegion: "us-central1",
169193
appEngineServiceName: "my-service",
170194
appEngineServiceVersion: "123456",
171-
}},
195+
}),
172196
expectedResource: internal.NewResource(map[string]interface{}{
173197
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
174198
conventions.AttributeCloudAccountID: "my-project",
@@ -182,20 +206,20 @@ func TestDetect(t *testing.T) {
182206
},
183207
{
184208
desc: "Unknown Platform",
185-
detector: &detector{detector: &fakeGCPDetector{
209+
detector: newTestDetector(&fakeGCPDetector{
186210
projectID: "my-project",
187211
cloudPlatform: gcp.UnknownPlatform,
188-
}},
212+
}),
189213
expectedResource: internal.NewResource(map[string]interface{}{
190214
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
191215
conventions.AttributeCloudAccountID: "my-project",
192216
}),
193217
},
194218
{
195219
desc: "error",
196-
detector: &detector{detector: &fakeGCPDetector{
220+
detector: newTestDetector(&fakeGCPDetector{
197221
err: fmt.Errorf("failed to get metadata"),
198-
}},
222+
}),
199223
expectErr: true,
200224
expectedResource: internal.NewResource(map[string]interface{}{
201225
conventions.AttributeCloudProvider: conventions.AttributeCloudProviderGCP,
@@ -217,6 +241,13 @@ func TestDetect(t *testing.T) {
217241
}
218242
}
219243

244+
func newTestDetector(gcpDetector *fakeGCPDetector) *detector {
245+
return &detector{
246+
logger: zap.NewNop(),
247+
detector: gcpDetector,
248+
}
249+
}
250+
220251
// fakeGCPDetector implements gcpDetector and uses fake values.
221252
type fakeGCPDetector struct {
222253
err error
@@ -240,6 +271,7 @@ type fakeGCPDetector struct {
240271
gceHostType string
241272
gceHostID string
242273
gceHostName string
274+
gceHostNameErr error
243275
}
244276

245277
func (f *fakeGCPDetector) ProjectID() (string, error) {
@@ -372,7 +404,7 @@ func (f *fakeGCPDetector) GCEHostName() (string, error) {
372404
if f.err != nil {
373405
return "", f.err
374406
}
375-
return f.gceHostName, nil
407+
return f.gceHostName, f.gceHostNameErr
376408
}
377409

378410
func TestDeduplicateDetectors(t *testing.T) {

unreleased/mx-psi_gke-detector.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: bug_fix
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
5+
component: resourcedetectionprocessor
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: Add back `host.name` attribute when running on GKE
9+
10+
# One or more tracking issues related to the change
11+
issues: [12354]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext:

0 commit comments

Comments
 (0)