Skip to content

Commit 36c3e50

Browse files
authored
Update mappings for generic_task and generic_node (#272)
* Add mapping for faas.name for generic_task * Add resource mapping for generic_node * Ignore 'unknown_service' value for service.name
1 parent f1b653c commit 36c3e50

File tree

2 files changed

+206
-12
lines changed

2 files changed

+206
-12
lines changed

shared/resourcemapping/src/main/java/com/google/cloud/opentelemetry/resource/ResourceTranslator.java

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
import io.opentelemetry.semconv.ResourceAttributes;
2121
import java.util.Arrays;
2222
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Objects;
2325
import java.util.Optional;
2426

2527
/** Translates from OpenTelemetry Resource into Google Cloud's notion of resource. */
2628
public class ResourceTranslator {
29+
30+
private static String UNKNOWN_SERVICE_PREFIX = "unknown_service";
31+
2732
private ResourceTranslator() {}
2833

2934
@com.google.auto.value.AutoValue
@@ -39,10 +44,24 @@ public void fill(Resource resource, GcpResource.Builder builder) {
3944
for (AttributeKey<?> key : getOtelKeys()) {
4045
Object value = resource.getAttribute(key);
4146
if (value != null) {
42-
builder.addResourceLabels(getLabelName(), value.toString());
47+
String stringValue = value.toString();
48+
// for monitored resource types that have service.name, ignore it
49+
// if its unknown_service in favor of a valid value in faas.name.
50+
// if faas.name is also empty/unset use the ignored value from before.
51+
if (key.equals(ResourceAttributes.SERVICE_NAME)
52+
&& stringValue.startsWith(UNKNOWN_SERVICE_PREFIX)) {
53+
continue;
54+
}
55+
builder.addResourceLabels(getLabelName(), stringValue);
4356
return;
4457
}
4558
}
59+
if (getOtelKeys().contains(ResourceAttributes.SERVICE_NAME)
60+
&& Objects.nonNull(resource.getAttribute(ResourceAttributes.SERVICE_NAME))) {
61+
builder.addResourceLabels(
62+
getLabelName(), resource.getAttribute(ResourceAttributes.SERVICE_NAME));
63+
return;
64+
}
4665
fallbackLiteral().ifPresent(value -> builder.addResourceLabels(getLabelName(), value));
4766
}
4867

@@ -103,18 +122,33 @@ public static AttributeMapping create(
103122
ResourceAttributes.CLOUD_AVAILABILITY_ZONE, ResourceAttributes.CLOUD_REGION),
104123
"global"),
105124
AttributeMapping.create("namespace", ResourceAttributes.SERVICE_NAMESPACE, ""),
106-
AttributeMapping.create("job", ResourceAttributes.SERVICE_NAME, ""),
125+
AttributeMapping.create(
126+
"job",
127+
Arrays.asList(ResourceAttributes.SERVICE_NAME, ResourceAttributes.FAAS_NAME),
128+
""),
107129
AttributeMapping.create(
108130
"task_id",
109131
Arrays.asList(
110132
ResourceAttributes.SERVICE_INSTANCE_ID, ResourceAttributes.FAAS_INSTANCE),
111133
""));
134+
private static List<AttributeMapping> GENERIC_NODE_LABELS =
135+
Arrays.asList(
136+
AttributeMapping.create(
137+
"location",
138+
Arrays.asList(
139+
ResourceAttributes.CLOUD_AVAILABILITY_ZONE, ResourceAttributes.CLOUD_REGION),
140+
"global"),
141+
AttributeMapping.create("namespace", ResourceAttributes.SERVICE_NAMESPACE, ""),
142+
AttributeMapping.create(
143+
"node_id",
144+
Arrays.asList(ResourceAttributes.HOST_ID, ResourceAttributes.HOST_NAME),
145+
""));
112146

113147
/** Converts a Java OpenTelemetry SDK resource into a GCP resource. */
114148
public static GcpResource mapResource(Resource resource) {
115149
String platform = resource.getAttribute(ResourceAttributes.CLOUD_PLATFORM);
116150
if (platform == null) {
117-
return mapBase(resource, "generic_task", GENERIC_TASK_LABELS);
151+
return genericTaskOrNode(resource);
118152
}
119153
switch (platform) {
120154
case ResourceAttributes.CloudPlatformValues.GCP_COMPUTE_ENGINE:
@@ -126,7 +160,19 @@ public static GcpResource mapResource(Resource resource) {
126160
case ResourceAttributes.CloudPlatformValues.GCP_APP_ENGINE:
127161
return mapBase(resource, "gae_instance", GOOGLE_CLOUD_APP_ENGINE_INSTANCE_LABELS);
128162
default:
129-
return mapBase(resource, "generic_task", GENERIC_TASK_LABELS);
163+
return genericTaskOrNode(resource);
164+
}
165+
}
166+
167+
private static GcpResource genericTaskOrNode(Resource resource) {
168+
Map<AttributeKey<?>, Object> attrMap = resource.getAttributes().asMap();
169+
if ((attrMap.containsKey(ResourceAttributes.SERVICE_NAME)
170+
|| attrMap.containsKey(ResourceAttributes.FAAS_NAME))
171+
&& (attrMap.containsKey(ResourceAttributes.SERVICE_INSTANCE_ID)
172+
|| attrMap.containsKey(ResourceAttributes.FAAS_INSTANCE))) {
173+
return mapBase(resource, "generic_task", GENERIC_TASK_LABELS);
174+
} else {
175+
return mapBase(resource, "generic_node", GENERIC_NODE_LABELS);
130176
}
131177
}
132178

shared/resourcemapping/src/test/java/com/google/cloud/opentelemetry/resource/ResourceTranslatorTest.java

Lines changed: 156 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,122 @@ public void testMapResourcesWithAwsEc2Instance() {
168168
});
169169
}
170170

171+
@Test
172+
public void testMapResourcesWithGenericTaskFallback_FAASIgnored() {
173+
Map<AttributeKey<String>, String> testAttributes =
174+
java.util.stream.Stream.of(
175+
new Object[][] {
176+
{ResourceAttributes.SERVICE_NAME, "my-service-prevailed"},
177+
{ResourceAttributes.FAAS_NAME, "my-service-ignored"},
178+
{ResourceAttributes.SERVICE_NAMESPACE, "prod"},
179+
{ResourceAttributes.FAAS_INSTANCE, "1234"}
180+
})
181+
.collect(
182+
Collectors.toMap(data -> (AttributeKey<String>) data[0], data -> (String) data[1]));
183+
AttributesBuilder attrBuilder = Attributes.builder();
184+
testAttributes.forEach(attrBuilder::put);
185+
Attributes attributes = attrBuilder.build();
186+
187+
GcpResource monitoredResource =
188+
ResourceTranslator.mapResource(io.opentelemetry.sdk.resources.Resource.create(attributes));
189+
190+
assertEquals("generic_task", monitoredResource.getResourceType());
191+
192+
Map<String, String> monitoredResourceMap = monitoredResource.getResourceLabels().getLabels();
193+
assertEquals(4, monitoredResourceMap.size());
194+
195+
Map<String, String> expectedMappings =
196+
Stream.of(
197+
new Object[][] {
198+
{"job", "my-service-prevailed"},
199+
{"namespace", "prod"},
200+
{"task_id", "1234"},
201+
{"location", "global"},
202+
})
203+
.collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));
204+
expectedMappings.forEach(
205+
(key, value) -> {
206+
assertEquals(value, monitoredResourceMap.get(key));
207+
});
208+
}
209+
210+
@Test
211+
public void testMapResourcesWithGenericTaskFallback_FAASPrevailed() {
212+
Map<AttributeKey<String>, String> testAttributes =
213+
java.util.stream.Stream.of(
214+
new Object[][] {
215+
{ResourceAttributes.SERVICE_NAME, "unknown_service_foo"},
216+
{ResourceAttributes.FAAS_NAME, "my-service-faas"},
217+
{ResourceAttributes.SERVICE_NAMESPACE, "prod"},
218+
{ResourceAttributes.FAAS_INSTANCE, "1234"}
219+
})
220+
.collect(
221+
Collectors.toMap(data -> (AttributeKey<String>) data[0], data -> (String) data[1]));
222+
AttributesBuilder attrBuilder = Attributes.builder();
223+
testAttributes.forEach(attrBuilder::put);
224+
Attributes attributes = attrBuilder.build();
225+
226+
GcpResource monitoredResource =
227+
ResourceTranslator.mapResource(io.opentelemetry.sdk.resources.Resource.create(attributes));
228+
229+
assertEquals("generic_task", monitoredResource.getResourceType());
230+
231+
Map<String, String> monitoredResourceMap = monitoredResource.getResourceLabels().getLabels();
232+
assertEquals(4, monitoredResourceMap.size());
233+
234+
Map<String, String> expectedMappings =
235+
Stream.of(
236+
new Object[][] {
237+
{"job", "my-service-faas"},
238+
{"namespace", "prod"},
239+
{"task_id", "1234"},
240+
{"location", "global"},
241+
})
242+
.collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));
243+
expectedMappings.forEach(
244+
(key, value) -> {
245+
assertEquals(value, monitoredResourceMap.get(key));
246+
});
247+
}
248+
249+
@Test
250+
public void testMapResourcesWithGenericTaskFallback_UnknownService() {
251+
Map<AttributeKey<String>, String> testAttributes =
252+
java.util.stream.Stream.of(
253+
new Object[][] {
254+
{ResourceAttributes.SERVICE_NAME, "unknown_service_foo"},
255+
{ResourceAttributes.SERVICE_NAMESPACE, "prod"},
256+
{ResourceAttributes.FAAS_INSTANCE, "1234"}
257+
})
258+
.collect(
259+
Collectors.toMap(data -> (AttributeKey<String>) data[0], data -> (String) data[1]));
260+
AttributesBuilder attrBuilder = Attributes.builder();
261+
testAttributes.forEach(attrBuilder::put);
262+
Attributes attributes = attrBuilder.build();
263+
264+
GcpResource monitoredResource =
265+
ResourceTranslator.mapResource(io.opentelemetry.sdk.resources.Resource.create(attributes));
266+
267+
assertEquals("generic_task", monitoredResource.getResourceType());
268+
269+
Map<String, String> monitoredResourceMap = monitoredResource.getResourceLabels().getLabels();
270+
assertEquals(4, monitoredResourceMap.size());
271+
272+
Map<String, String> expectedMappings =
273+
Stream.of(
274+
new Object[][] {
275+
{"job", "unknown_service_foo"},
276+
{"namespace", "prod"},
277+
{"task_id", "1234"},
278+
{"location", "global"},
279+
})
280+
.collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));
281+
expectedMappings.forEach(
282+
(key, value) -> {
283+
assertEquals(value, monitoredResourceMap.get(key));
284+
});
285+
}
286+
171287
@Test
172288
public void testMapResourcesWithGlobal() {
173289
Map<AttributeKey<String>, String> testAttributes =
@@ -180,10 +296,7 @@ public void testMapResourcesWithGlobal() {
180296
.collect(
181297
Collectors.toMap(data -> (AttributeKey<String>) data[0], data -> (String) data[1]));
182298
AttributesBuilder attrBuilder = Attributes.builder();
183-
testAttributes.forEach(
184-
(key, value) -> {
185-
attrBuilder.put(key, value);
186-
});
299+
testAttributes.forEach(attrBuilder::put);
187300
Attributes attributes = attrBuilder.build();
188301

189302
GcpResource monitoredResource =
@@ -209,24 +322,59 @@ public void testMapResourcesWithGlobal() {
209322
});
210323
}
211324

325+
@Test
326+
public void testMapResourcesFallbackServiceNameOnly() {
327+
Map<AttributeKey<String>, String> testAttributes =
328+
java.util.stream.Stream.of(
329+
new Object[][] {
330+
{ResourceAttributes.SERVICE_NAME, "unknown_service"},
331+
{ResourceAttributes.SERVICE_NAMESPACE, "prod"}
332+
})
333+
.collect(
334+
Collectors.toMap(data -> (AttributeKey<String>) data[0], data -> (String) data[1]));
335+
AttributesBuilder attrBuilder = Attributes.builder();
336+
testAttributes.forEach(attrBuilder::put);
337+
Attributes attributes = attrBuilder.build();
338+
339+
GcpResource monitoredResource =
340+
ResourceTranslator.mapResource(io.opentelemetry.sdk.resources.Resource.create(attributes));
341+
342+
assertEquals("generic_node", monitoredResource.getResourceType());
343+
344+
Map<String, String> monitoredResourceMap = monitoredResource.getResourceLabels().getLabels();
345+
assertEquals(3, monitoredResourceMap.size());
346+
347+
Map<String, String> expectedMappings =
348+
Stream.of(
349+
new Object[][] {
350+
{"namespace", "prod"},
351+
{"node_id", ""},
352+
{"location", "global"},
353+
})
354+
.collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));
355+
expectedMappings.forEach(
356+
(key, value) -> {
357+
assertEquals(value, monitoredResourceMap.get(key));
358+
});
359+
}
360+
212361
@Test
213362
public void testMapResourcesFallback() {
214363
Attributes attributes = Attributes.builder().build();
215364

216365
GcpResource monitoredResource =
217366
ResourceTranslator.mapResource(io.opentelemetry.sdk.resources.Resource.create(attributes));
218367

219-
assertEquals("generic_task", monitoredResource.getResourceType());
368+
assertEquals("generic_node", monitoredResource.getResourceType());
220369

221370
Map<String, String> monitoredResourceMap = monitoredResource.getResourceLabels().getLabels();
222-
assertEquals(4, monitoredResourceMap.size());
371+
assertEquals(3, monitoredResourceMap.size());
223372

224373
Map<String, String> expectedMappings =
225374
Stream.of(
226375
new Object[][] {
227-
{"job", ""},
228376
{"namespace", ""},
229-
{"task_id", ""},
377+
{"node_id", ""},
230378
{"location", "global"},
231379
})
232380
.collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));

0 commit comments

Comments
 (0)