Skip to content
Closed
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
10 changes: 10 additions & 0 deletions instrumentation/resources/library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ Implemented attributes:
- `process.runtime.version`
- `process.runtime.description`

### Service Instance ID

Implementation: `io.opentelemetry.instrumentation.resources.ServiceInstanceIdResource`

Specification: <https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/resource/semantic_conventions#service-experimental>

Implemented attributes:

- `service.instance.id`

## Platforms

This package currently does not run on Android. It has been verified on OpenJDK and should work on
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Map;
import java.util.UUID;

/**
* In the spirit of <a
* href="https://docs.google.com/document/d/1BenPf9vsZHCf4JpHWGQBydKZAA4XdH38wuMD7JQnz9A/edit?pli=1#heading=h.lyyq7xqgpsj9">this
* proposal</a>
*/
public class ServiceInstanceIdResource {

public static final String RESOURCE_ATTRIBUTES = "otel.resource.attributes";
public static final String RANDOM_INSTANCE_ID = UUID.randomUUID().toString();

private ServiceInstanceIdResource() {}

public static Resource getResource(ConfigProperties config) {
Map<String, String> resourceAttributes = config.getMap(RESOURCE_ATTRIBUTES);
String k8s = k8sServiceInstanceId(resourceAttributes);
String value = k8s != null ? k8s : RANDOM_INSTANCE_ID;
return Resource.create(
Attributes.of(ResourceAttributes.SERVICE_INSTANCE_ID, value),
ResourceAttributes.SCHEMA_URL);
}

private static String k8sServiceInstanceId(Map<String, String> resource) {
String podName = resource.get(ResourceAttributes.K8S_POD_NAME.getKey());
String containerName = resource.get(ResourceAttributes.K8S_CONTAINER_NAME.getKey());
return podName != null && containerName != null ? podName + "/" + containerName : null;
}
Comment on lines +36 to +40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec doesn't really say anything about using k8s attributes to construct the serviceId (also k8s attributes are usually added by the collector processors, these might simply not be accessible here)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

/** {@link ResourceProvider} for automatically configuring {@link ServiceInstanceIdResource}. */
@AutoService(ResourceProvider.class)
public final class ServiceInstanceIdResourceProvider implements ConditionalResourceProvider {

@Override
public Resource createResource(ConfigProperties config) {
return ServiceInstanceIdResource.getResource(config);
}

@Override
public boolean shouldApply(ConfigProperties config, Resource existing) {
return !config
.getMap(ServiceInstanceIdResource.RESOURCE_ATTRIBUTES)
.containsKey(ResourceAttributes.SERVICE_INSTANCE_ID.getKey());
}
Comment on lines +23 to +29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't really be needed, the EnvironmentResource always comes last and it can override that anyway.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Named.named;

import com.google.common.collect.ImmutableMap;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class ServiceInstanceIdResourceTest {

private static class Parameter {
public final Map<String, String> resource;
public final String want;

public Parameter(Map<String, String> resource, String want) {
this.resource = resource;
this.want = want;
}
}

@ParameterizedTest(name = "{index}: {0}")
@MethodSource
void serviceInstanceId(Parameter parameter) {
Resource r =
ServiceInstanceIdResource.getResource(
DefaultConfigProperties.createForTest(
ImmutableMap.of(
ServiceInstanceIdResource.RESOURCE_ATTRIBUTES,
parameter.resource.entrySet().stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining(",")))));
assertThat(r.getAttribute(ResourceAttributes.SERVICE_INSTANCE_ID)).matches(parameter.want);
}

public static Stream<Arguments> serviceInstanceId() {
return Stream.of(
Arguments.of(
named(
"service instance id is not set, but pod name and container name are",
new Parameter(
ImmutableMap.of(
ResourceAttributes.K8S_POD_NAME.getKey(),
"pod-12345",
ResourceAttributes.K8S_CONTAINER_NAME.getKey(),
"container-42"),
"pod-12345/container-42"))),
Arguments.of(
named(
"fall back to random service instance id",
new Parameter(
ImmutableMap.of(ResourceAttributes.K8S_POD_NAME.getKey(), "pod-12345"),
"........-....-....-....-............"))));
}
}