Rename resource labels to attributes (#970)

This commit is contained in:
Armin Ruech 2020-03-11 00:35:17 +01:00 committed by GitHub
parent 0aa70d123f
commit 91d2132f62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 102 deletions

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}