Rename resource labels to attributes (#970)
This commit is contained in:
parent
0aa70d123f
commit
91d2132f62
|
|
@ -25,24 +25,24 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||
|
||||
/**
|
||||
* Provides a framework for detection of resource information from the environment variable
|
||||
* "OTEL_RESOURCE_LABELS".
|
||||
* "OTEL_RESOURCE_ATTRIBUTES".
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@ThreadSafe
|
||||
public final class EnvVarResource {
|
||||
private static final String OTEL_RESOURCE_LABELS_ENV = "OTEL_RESOURCE_LABELS";
|
||||
private static final String LABEL_LIST_SPLITTER = ",";
|
||||
private static final String LABEL_KEY_VALUE_SPLITTER = "=";
|
||||
private static final String OTEL_RESOURCE_ATTRIBUTES_ENV = "OTEL_RESOURCE_ATTRIBUTES";
|
||||
private static final String ATTRIBUTE_LIST_SPLITTER = ",";
|
||||
private static final String ATTRIBUTE_KEY_VALUE_SPLITTER = "=";
|
||||
|
||||
private static final Resource ENV_VAR_RESOURCE =
|
||||
Resource.create(parseResourceLabels(System.getenv(OTEL_RESOURCE_LABELS_ENV)));
|
||||
Resource.create(parseResourceAttributes(System.getenv(OTEL_RESOURCE_ATTRIBUTES_ENV)));
|
||||
|
||||
private EnvVarResource() {}
|
||||
|
||||
/**
|
||||
* Returns a {@link Resource}. This resource information is loaded from the OTEL_RESOURCE_LABELS
|
||||
* environment variable.
|
||||
* Returns a {@link Resource}. This resource information is loaded from the
|
||||
* OTEL_RESOURCE_ATTRIBUTES environment variable.
|
||||
*
|
||||
* @return a {@code Resource}.
|
||||
* @since 0.1.0
|
||||
|
|
@ -52,30 +52,31 @@ public final class EnvVarResource {
|
|||
}
|
||||
|
||||
/*
|
||||
* Creates a label map from the OTEL_RESOURCE_LABELS environment variable.
|
||||
* Creates an attribute map from the OTEL_RESOURCE_ATTRIBUTES environment variable.
|
||||
*
|
||||
* <p>OTEL_RESOURCE_LABELS: A comma-separated list of labels describing the source in more detail,
|
||||
* e.g. “key1=val1,key2=val2”. Domain names and paths are accepted as label keys. Values may be
|
||||
* quoted or unquoted in general. If a value contains whitespaces, =, or " characters, it must
|
||||
* always be quoted.
|
||||
* <p>OTEL_RESOURCE_ATTRIBUTES: A comma-separated list of attributes describing the source in more
|
||||
* detail, e.g. “key1=val1,key2=val2”. Domain names and paths are accepted as attribute keys.
|
||||
* Values may be quoted or unquoted in general.
|
||||
* If a value contains whitespaces, =, or " characters, it must always be quoted.
|
||||
*/
|
||||
private static Map<String, AttributeValue> parseResourceLabels(@Nullable String rawEnvLabels) {
|
||||
if (rawEnvLabels == null) {
|
||||
private static Map<String, AttributeValue> parseResourceAttributes(
|
||||
@Nullable String rawEnvAttributes) {
|
||||
if (rawEnvAttributes == null) {
|
||||
return Collections.emptyMap();
|
||||
} else {
|
||||
Map<String, AttributeValue> labels = new HashMap<>();
|
||||
String[] rawLabels = rawEnvLabels.split(LABEL_LIST_SPLITTER, -1);
|
||||
for (String rawLabel : rawLabels) {
|
||||
String[] keyValuePair = rawLabel.split(LABEL_KEY_VALUE_SPLITTER, -1);
|
||||
Map<String, AttributeValue> attributes = new HashMap<>();
|
||||
String[] rawAttributes = rawEnvAttributes.split(ATTRIBUTE_LIST_SPLITTER, -1);
|
||||
for (String rawAttribute : rawAttributes) {
|
||||
String[] keyValuePair = rawAttribute.split(ATTRIBUTE_KEY_VALUE_SPLITTER, -1);
|
||||
if (keyValuePair.length != 2) {
|
||||
continue;
|
||||
}
|
||||
String key = keyValuePair[0].trim();
|
||||
AttributeValue value =
|
||||
AttributeValue.stringAttributeValue(keyValuePair[1].trim().replaceAll("^\"|\"$", ""));
|
||||
labels.put(key, value);
|
||||
attributes.put(key, value);
|
||||
}
|
||||
return Collections.unmodifiableMap(labels);
|
||||
return Collections.unmodifiableMap(attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,26 +58,26 @@ public abstract class Resource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a map of labels that describe the resource.
|
||||
* Returns a map of attributes that describe the resource.
|
||||
*
|
||||
* @return a map of labels.
|
||||
* @return a map of attributes.
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public abstract Map<String, AttributeValue> getLabels();
|
||||
public abstract Map<String, AttributeValue> getAttributes();
|
||||
|
||||
/**
|
||||
* Returns a {@link Resource}.
|
||||
*
|
||||
* @param labels a map of labels that describe the resource.
|
||||
* @param attributes a map of attributes that describe the resource.
|
||||
* @return a {@code Resource}.
|
||||
* @throws NullPointerException if {@code labels} is null.
|
||||
* @throws IllegalArgumentException if label key or label value is not a valid printable ASCII
|
||||
* string or exceed {@link #MAX_LENGTH} characters.
|
||||
* @throws NullPointerException if {@code attributes} is null.
|
||||
* @throws IllegalArgumentException if attribute key or attribute value is not a valid printable
|
||||
* ASCII string or exceed {@link #MAX_LENGTH} characters.
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public static Resource create(Map<String, AttributeValue> labels) {
|
||||
checkLabels(Utils.checkNotNull(labels, "labels"));
|
||||
return new AutoValue_Resource(Collections.unmodifiableMap(new LinkedHashMap<>(labels)));
|
||||
public static Resource create(Map<String, AttributeValue> attributes) {
|
||||
checkAttributes(Utils.checkNotNull(attributes, "attributes"));
|
||||
return new AutoValue_Resource(Collections.unmodifiableMap(new LinkedHashMap<>(attributes)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,19 +93,19 @@ public abstract class Resource {
|
|||
return this;
|
||||
}
|
||||
|
||||
Map<String, AttributeValue> mergedLabelMap = new LinkedHashMap<>(other.getLabels());
|
||||
// Labels from resource overwrite labels from otherResource.
|
||||
for (Entry<String, AttributeValue> entry : this.getLabels().entrySet()) {
|
||||
mergedLabelMap.put(entry.getKey(), entry.getValue());
|
||||
Map<String, AttributeValue> mergedAttributeMap = new LinkedHashMap<>(other.getAttributes());
|
||||
// Attributes from resource overwrite attributes from otherResource.
|
||||
for (Entry<String, AttributeValue> entry : this.getAttributes().entrySet()) {
|
||||
mergedAttributeMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return new AutoValue_Resource(Collections.unmodifiableMap(mergedLabelMap));
|
||||
return new AutoValue_Resource(Collections.unmodifiableMap(mergedAttributeMap));
|
||||
}
|
||||
|
||||
private static void checkLabels(Map<String, AttributeValue> labels) {
|
||||
for (Entry<String, AttributeValue> entry : labels.entrySet()) {
|
||||
private static void checkAttributes(Map<String, AttributeValue> attributes) {
|
||||
for (Entry<String, AttributeValue> entry : attributes.entrySet()) {
|
||||
Utils.checkArgument(
|
||||
isValidAndNotEmpty(entry.getKey()), "Label key" + ERROR_MESSAGE_INVALID_CHARS);
|
||||
Utils.checkNotNull(entry.getValue(), "Label value" + ERROR_MESSAGE_INVALID_VALUE);
|
||||
isValidAndNotEmpty(entry.getKey()), "Attribute key" + ERROR_MESSAGE_INVALID_CHARS);
|
||||
Utils.checkNotNull(entry.getValue(), "Attribute value" + ERROR_MESSAGE_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@
|
|||
* <p>One environment variables is used to populate resource information:
|
||||
*
|
||||
* <ul>
|
||||
* <li>OTEL_RESOURCE_LABELS: A comma-separated list of labels describing the source in more
|
||||
* detail, e.g. “key1=val1,key2=val2”. The allowed character set is appropriately constrained.
|
||||
* <li>OTEL_RESOURCE_ATTRIBUTES: A comma-separated list of attributes describing the source in
|
||||
* more detail, e.g. “key1=val1,key2=val2”. The allowed character set is appropriately
|
||||
* constrained.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Label keys, and label values MUST contain only printable ASCII (codes between 32 and 126,
|
||||
* inclusive) and less than 256 characters. Type and label keys MUST have a length greater than
|
||||
* zero. They SHOULD start with a domain name and separate hierarchies with / characters, e.g.
|
||||
* <p>Attribute keys, and attribute values MUST contain only printable ASCII (codes between 32 and
|
||||
* 126, inclusive) and less than 256 characters. Type and attribute keys MUST have a length greater
|
||||
* than zero. They SHOULD start with a domain name and separate hierarchies with / characters, e.g.
|
||||
* k8s.io/namespace/name.
|
||||
*/
|
||||
package io.opentelemetry.sdk.resources;
|
||||
|
|
|
|||
|
|
@ -42,86 +42,86 @@ public class ResourceTest {
|
|||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Map<String, AttributeValue> labelMap1 = new HashMap<>();
|
||||
labelMap1.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
labelMap1.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Map<String, AttributeValue> labelMap2 = new HashMap<>();
|
||||
labelMap2.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
labelMap2.put("b", AttributeValue.stringAttributeValue("3"));
|
||||
labelMap2.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
resource1 = Resource.create(labelMap1);
|
||||
resource2 = Resource.create(labelMap2);
|
||||
Map<String, AttributeValue> attributeMap1 = new HashMap<>();
|
||||
attributeMap1.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
attributeMap1.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Map<String, AttributeValue> attributeMap2 = new HashMap<>();
|
||||
attributeMap2.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
attributeMap2.put("b", AttributeValue.stringAttributeValue("3"));
|
||||
attributeMap2.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
resource1 = Resource.create(attributeMap1);
|
||||
resource2 = Resource.create(attributeMap2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create() {
|
||||
Map<String, AttributeValue> labelMap = new HashMap<>();
|
||||
labelMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
labelMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Resource resource = Resource.create(labelMap);
|
||||
assertThat(resource.getLabels()).isNotNull();
|
||||
assertThat(resource.getLabels().size()).isEqualTo(2);
|
||||
assertThat(resource.getLabels()).isEqualTo(labelMap);
|
||||
Map<String, AttributeValue> attributeMap = new HashMap<>();
|
||||
attributeMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
attributeMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Resource resource = Resource.create(attributeMap);
|
||||
assertThat(resource.getAttributes()).isNotNull();
|
||||
assertThat(resource.getAttributes().size()).isEqualTo(2);
|
||||
assertThat(resource.getAttributes()).isEqualTo(attributeMap);
|
||||
|
||||
Resource resource1 = Resource.create(Collections.<String, AttributeValue>emptyMap());
|
||||
assertThat(resource1.getLabels()).isNotNull();
|
||||
assertThat(resource1.getLabels()).isEmpty();
|
||||
assertThat(resource1.getAttributes()).isNotNull();
|
||||
assertThat(resource1.getAttributes()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceEquals() {
|
||||
Map<String, AttributeValue> labelMap1 = new HashMap<>();
|
||||
labelMap1.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
labelMap1.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Map<String, AttributeValue> labelMap2 = new HashMap<>();
|
||||
labelMap2.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
labelMap2.put("b", AttributeValue.stringAttributeValue("3"));
|
||||
labelMap2.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
Map<String, AttributeValue> attributeMap1 = new HashMap<>();
|
||||
attributeMap1.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
attributeMap1.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Map<String, AttributeValue> attributeMap2 = new HashMap<>();
|
||||
attributeMap2.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
attributeMap2.put("b", AttributeValue.stringAttributeValue("3"));
|
||||
attributeMap2.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
new EqualsTester()
|
||||
.addEqualityGroup(Resource.create(labelMap1), Resource.create(labelMap1))
|
||||
.addEqualityGroup(Resource.create(labelMap2))
|
||||
.addEqualityGroup(Resource.create(attributeMap1), Resource.create(attributeMap1))
|
||||
.addEqualityGroup(Resource.create(attributeMap2))
|
||||
.testEquals();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeResources() {
|
||||
Map<String, AttributeValue> expectedLabelMap = new HashMap<>();
|
||||
expectedLabelMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedLabelMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
expectedLabelMap.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
Map<String, AttributeValue> expectedAttributeMap = new HashMap<>();
|
||||
expectedAttributeMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedAttributeMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
expectedAttributeMap.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
|
||||
Resource resource = DEFAULT_RESOURCE.merge(resource1).merge(resource2);
|
||||
assertThat(resource.getLabels()).isEqualTo(expectedLabelMap);
|
||||
assertThat(resource.getAttributes()).isEqualTo(expectedAttributeMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeResources_Resource1() {
|
||||
Map<String, AttributeValue> expectedLabelMap = new HashMap<>();
|
||||
expectedLabelMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedLabelMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Map<String, AttributeValue> expectedAttributeMap = new HashMap<>();
|
||||
expectedAttributeMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedAttributeMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
|
||||
Resource resource = DEFAULT_RESOURCE.merge(resource1);
|
||||
assertThat(resource.getLabels()).isEqualTo(expectedLabelMap);
|
||||
assertThat(resource.getAttributes()).isEqualTo(expectedAttributeMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeResources_Resource1_Null() {
|
||||
Map<String, AttributeValue> expectedLabelMap = new HashMap<>();
|
||||
expectedLabelMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedLabelMap.put("b", AttributeValue.stringAttributeValue("3"));
|
||||
expectedLabelMap.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
Map<String, AttributeValue> expectedAttributeMap = new HashMap<>();
|
||||
expectedAttributeMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedAttributeMap.put("b", AttributeValue.stringAttributeValue("3"));
|
||||
expectedAttributeMap.put("c", AttributeValue.stringAttributeValue("4"));
|
||||
|
||||
Resource resource = DEFAULT_RESOURCE.merge(null).merge(resource2);
|
||||
assertThat(resource.getLabels()).isEqualTo(expectedLabelMap);
|
||||
assertThat(resource.getAttributes()).isEqualTo(expectedAttributeMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeResources_Resource2_Null() {
|
||||
Map<String, AttributeValue> expectedLabelMap = new HashMap<>();
|
||||
expectedLabelMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedLabelMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
Map<String, AttributeValue> expectedAttributeMap = new HashMap<>();
|
||||
expectedAttributeMap.put("a", AttributeValue.stringAttributeValue("1"));
|
||||
expectedAttributeMap.put("b", AttributeValue.stringAttributeValue("2"));
|
||||
|
||||
Resource resource = DEFAULT_RESOURCE.merge(resource1).merge(null);
|
||||
assertThat(resource.getLabels()).isEqualTo(expectedLabelMap);
|
||||
assertThat(resource.getAttributes()).isEqualTo(expectedAttributeMap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -550,9 +550,9 @@ public class RecordEventsReadableSpanTest {
|
|||
TraceConfig traceConfig = TraceConfig.getDefault();
|
||||
SpanProcessor spanProcessor = NoopSpanProcessor.getInstance();
|
||||
TestClock clock = TestClock.create();
|
||||
Map<String, AttributeValue> labels = new HashMap<>();
|
||||
labels.put("foo", AttributeValue.stringAttributeValue("bar"));
|
||||
Resource resource = Resource.create(labels);
|
||||
Map<String, AttributeValue> attribute = new HashMap<>();
|
||||
attribute.put("foo", AttributeValue.stringAttributeValue("bar"));
|
||||
Resource resource = Resource.create(attribute);
|
||||
Map<String, AttributeValue> attributes = TestUtils.generateRandomAttributes();
|
||||
AttributesWithCapacity attributesWithCapacity = new AttributesWithCapacity(32);
|
||||
attributesWithCapacity.putAllAttributes(attributes);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class Ec2ResourceTest {
|
|||
@Test
|
||||
public void shouldReturnResourceWithOnlyCloudProviderLabelIfNotRunningOnEc2() {
|
||||
Resource resource = Ec2Resource.getResourceFromInfoAndHost(null, null);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.CLOUD_PROVIDER).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.CLOUD_PROVIDER).getStringValue())
|
||||
.isEqualTo(Ec2Resource.CLOUD_PROVIDER_AWS.getStringValue());
|
||||
}
|
||||
|
||||
|
|
@ -70,23 +70,23 @@ public class Ec2ResourceTest {
|
|||
devpayProductCodes);
|
||||
String hostname = "ip-172-31-30-166.ec2.internal";
|
||||
Resource resource = Ec2Resource.getResourceFromInfoAndHost(instanceInfo, hostname);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.CLOUD_PROVIDER).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.CLOUD_PROVIDER).getStringValue())
|
||||
.isEqualTo(Ec2Resource.CLOUD_PROVIDER_AWS.getStringValue());
|
||||
assertThat(resource.getLabels().get(ResourceConstants.CLOUD_ACCOUNT).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.CLOUD_ACCOUNT).getStringValue())
|
||||
.isEqualTo(accountId);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.CLOUD_REGION).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.CLOUD_REGION).getStringValue())
|
||||
.isEqualTo(region);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.CLOUD_ZONE).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.CLOUD_ZONE).getStringValue())
|
||||
.isEqualTo(availabilityZone);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.HOST_ID).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.HOST_ID).getStringValue())
|
||||
.isEqualTo(instanceId);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.HOST_NAME).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.HOST_NAME).getStringValue())
|
||||
.isEqualTo(privateIp);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.HOST_TYPE).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.HOST_TYPE).getStringValue())
|
||||
.isEqualTo(instanceType);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.HOST_HOSTNAME).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.HOST_HOSTNAME).getStringValue())
|
||||
.isEqualTo(hostname);
|
||||
assertThat(resource.getLabels().get(ResourceConstants.HOST_IMAGE_ID).getStringValue())
|
||||
assertThat(resource.getAttributes().get(ResourceConstants.HOST_IMAGE_ID).getStringValue())
|
||||
.isEqualTo(imageId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue