Skip to content

Commit d3f1582

Browse files
committed
add Azure functions resource provider
1 parent 05c5833 commit d3f1582

File tree

5 files changed

+185
-22
lines changed

5 files changed

+185
-22
lines changed

azure-resources/src/main/java/io/opentelemetry/contrib/azure/resource/AzureAppServiceResourceProvider.java

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,30 @@
1313
import io.opentelemetry.semconv.ResourceAttributes;
1414
import java.util.HashMap;
1515
import java.util.Map;
16+
import java.util.Objects;
1617
import javax.annotation.Nullable;
1718

1819
public class AzureAppServiceResourceProvider extends CloudResourceProvider {
1920

2021
static final AttributeKey<String> AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE =
2122
AttributeKey.stringKey("azure.app.service.stamp");
22-
private static final String REGION_NAME = "REGION_NAME";
23+
static final String REGION_NAME = "REGION_NAME";
2324
private static final String WEBSITE_HOME_STAMPNAME = "WEBSITE_HOME_STAMPNAME";
2425
private static final String WEBSITE_HOSTNAME = "WEBSITE_HOSTNAME";
25-
private static final String WEBSITE_INSTANCE_ID = "WEBSITE_INSTANCE_ID";
26+
static final String WEBSITE_INSTANCE_ID = "WEBSITE_INSTANCE_ID";
2627
private static final String WEBSITE_OWNER_NAME = "WEBSITE_OWNER_NAME";
2728
private static final String WEBSITE_RESOURCE_GROUP = "WEBSITE_RESOURCE_GROUP";
28-
private static final String WEBSITE_SITE_NAME = "WEBSITE_SITE_NAME";
29+
static final String WEBSITE_SITE_NAME = "WEBSITE_SITE_NAME";
2930
private static final String WEBSITE_SLOT_NAME = "WEBSITE_SLOT_NAME";
3031

31-
private static final Map<AttributeKey<String>, String> APP_SERVICE_ATTRIBUTE_ENV_VARS =
32-
new HashMap<>();
32+
private static final Map<AttributeKey<String>, String> ENV_VAR_MAPPING = new HashMap<>();
3333

3434
static {
35-
APP_SERVICE_ATTRIBUTE_ENV_VARS.put(ResourceAttributes.CLOUD_REGION, REGION_NAME);
36-
APP_SERVICE_ATTRIBUTE_ENV_VARS.put(
37-
ResourceAttributes.DEPLOYMENT_ENVIRONMENT, WEBSITE_SLOT_NAME);
38-
APP_SERVICE_ATTRIBUTE_ENV_VARS.put(ResourceAttributes.HOST_ID, WEBSITE_HOSTNAME);
39-
APP_SERVICE_ATTRIBUTE_ENV_VARS.put(ResourceAttributes.SERVICE_INSTANCE_ID, WEBSITE_INSTANCE_ID);
40-
APP_SERVICE_ATTRIBUTE_ENV_VARS.put(
41-
AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE, WEBSITE_HOME_STAMPNAME);
35+
ENV_VAR_MAPPING.put(ResourceAttributes.CLOUD_REGION, REGION_NAME);
36+
ENV_VAR_MAPPING.put(ResourceAttributes.DEPLOYMENT_ENVIRONMENT, WEBSITE_SLOT_NAME);
37+
ENV_VAR_MAPPING.put(ResourceAttributes.HOST_ID, WEBSITE_HOSTNAME);
38+
ENV_VAR_MAPPING.put(ResourceAttributes.SERVICE_INSTANCE_ID, WEBSITE_INSTANCE_ID);
39+
ENV_VAR_MAPPING.put(AZURE_APP_SERVICE_STAMP_RESOURCE_ATTRIBUTE, WEBSITE_HOME_STAMPNAME);
4240
}
4341

4442
private final Map<String, String> env;
@@ -55,24 +53,21 @@ public AzureAppServiceResourceProvider() {
5553

5654
@Override
5755
public Resource createResource(ConfigProperties config) {
58-
String name = env.get(WEBSITE_SITE_NAME);
59-
if (name == null) {
56+
AzureEnvVarPlatform detect = AzureEnvVarPlatform.detect(env);
57+
if (detect != AzureEnvVarPlatform.APP_SERVICE) {
6058
return Resource.empty();
6159
}
60+
String name = Objects.requireNonNull(env.get(WEBSITE_SITE_NAME));
6261
AttributesBuilder builder = AzureVmResourceProvider.azureAttributeBuilder();
63-
builder.put(ResourceAttributes.CLOUD_PLATFORM, "azure_app_service");
62+
builder.put(
63+
ResourceAttributes.CLOUD_PLATFORM,
64+
ResourceAttributes.CloudPlatformValues.AZURE_APP_SERVICE);
6465
builder.put(ResourceAttributes.SERVICE_NAME, name);
6566

6667
String resourceUri = resourceUri(name);
6768
if (resourceUri != null) {
6869
builder.put(ResourceAttributes.CLOUD_RESOURCE_ID, resourceUri);
69-
APP_SERVICE_ATTRIBUTE_ENV_VARS.forEach(
70-
(key, value) -> {
71-
String envValue = env.get(value);
72-
if (envValue != null) {
73-
builder.put(key, envValue);
74-
}
75-
});
70+
AzureEnvVarPlatform.addAttributesFromEnv(ENV_VAR_MAPPING, env, builder);
7671
}
7772

7873
return Resource.create(builder.build());
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.azure.resource;
7+
8+
import io.opentelemetry.api.common.AttributeKey;
9+
import io.opentelemetry.api.common.AttributesBuilder;
10+
import java.util.Map;
11+
12+
public enum AzureEnvVarPlatform {
13+
APP_SERVICE,
14+
FUNCTIONS,
15+
NONE;
16+
17+
static AzureEnvVarPlatform detect(Map<String, String> env) {
18+
String name = env.get(AzureAppServiceResourceProvider.WEBSITE_SITE_NAME);
19+
if (name == null) {
20+
return NONE;
21+
}
22+
if (env.get(AzureFunctionsResourceProvider.FUNCTIONS_VERSION) != null) {
23+
return FUNCTIONS;
24+
}
25+
return APP_SERVICE;
26+
}
27+
28+
static void addAttributesFromEnv(
29+
Map<AttributeKey<String>, String> mapping,
30+
Map<String, String> env,
31+
AttributesBuilder builder) {
32+
mapping.forEach(
33+
(key, value) -> {
34+
String envValue = env.get(value);
35+
if (envValue != null) {
36+
builder.put(key, envValue);
37+
}
38+
});
39+
}
40+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.azure.resource;
7+
8+
import io.opentelemetry.api.common.AttributeKey;
9+
import io.opentelemetry.api.common.AttributesBuilder;
10+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
11+
import io.opentelemetry.sdk.resources.Resource;
12+
import io.opentelemetry.semconv.ResourceAttributes;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
16+
public class AzureFunctionsResourceProvider extends CloudResourceProvider {
17+
18+
static final String FUNCTIONS_VERSION = "FUNCTIONS_EXTENSION_VERSION";
19+
private static final String FUNCTIONS_MEM_LIMIT = "WEBSITE_MEMORY_LIMIT_MB";
20+
21+
private static final Map<AttributeKey<String>, String> ENV_VAR_MAPPING = new HashMap<>();
22+
23+
static {
24+
ENV_VAR_MAPPING.put(
25+
ResourceAttributes.CLOUD_REGION, AzureAppServiceResourceProvider.REGION_NAME);
26+
ENV_VAR_MAPPING.put(
27+
ResourceAttributes.FAAS_NAME, AzureAppServiceResourceProvider.WEBSITE_SITE_NAME);
28+
ENV_VAR_MAPPING.put(ResourceAttributes.FAAS_VERSION, FUNCTIONS_VERSION);
29+
ENV_VAR_MAPPING.put(
30+
ResourceAttributes.FAAS_INSTANCE, AzureAppServiceResourceProvider.WEBSITE_INSTANCE_ID);
31+
}
32+
33+
private final Map<String, String> env;
34+
35+
// SPI
36+
public AzureFunctionsResourceProvider() {
37+
this(System.getenv());
38+
}
39+
40+
// Visible for testing
41+
AzureFunctionsResourceProvider(Map<String, String> env) {
42+
this.env = env;
43+
}
44+
45+
@Override
46+
public Resource createResource(ConfigProperties config) {
47+
AzureEnvVarPlatform detect = AzureEnvVarPlatform.detect(env);
48+
if (detect != AzureEnvVarPlatform.FUNCTIONS) {
49+
return Resource.empty();
50+
}
51+
52+
AttributesBuilder builder = AzureVmResourceProvider.azureAttributeBuilder();
53+
builder.put(
54+
ResourceAttributes.CLOUD_PLATFORM, ResourceAttributes.CloudPlatformValues.AZURE_FUNCTIONS);
55+
56+
String limit = env.get(FUNCTIONS_MEM_LIMIT);
57+
if (limit != null) {
58+
builder.put(ResourceAttributes.FAAS_MAX_MEMORY, Long.parseLong(limit));
59+
}
60+
61+
AzureEnvVarPlatform.addAttributesFromEnv(ENV_VAR_MAPPING, env, builder);
62+
63+
return Resource.create(builder.build());
64+
}
65+
}

azure-resources/src/test/java/io/opentelemetry/contrib/azure/resource/AzureAppServiceResourceProviderTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ void noWebsite() {
8080
createResource(map).isEmpty();
8181
}
8282

83+
@Test
84+
void isFunction() {
85+
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
86+
map.put("FUNCTIONS_EXTENSION_VERSION", "3.0");
87+
88+
createResource(map).isEmpty();
89+
}
90+
8391
@NotNull
8492
private static AttributesAssert createResource(Map<String, String> map) {
8593
return OpenTelemetryAssertions.assertThat(
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.azure.resource;
7+
8+
import com.google.common.collect.ImmutableMap;
9+
import io.opentelemetry.sdk.testing.assertj.AttributesAssert;
10+
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
11+
import io.opentelemetry.semconv.ResourceAttributes;
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
import org.jetbrains.annotations.NotNull;
15+
import org.junit.jupiter.api.Test;
16+
17+
class AzureFunctionsResourceProviderTest {
18+
private static final String TEST_WEBSITE_SITE_NAME = "TEST_WEBSITE_SITE_NAME";
19+
private static final String TEST_REGION_NAME = "TEST_REGION_NAME";
20+
private static final String TEST_FUNCTION_VERSION = "TEST_VERSION";
21+
private static final String TEST_WEBSITE_INSTANCE_ID = "TEST_WEBSITE_INSTANCE_ID";
22+
private static final String TEST_MEM_LIMIT = "1024";
23+
private static final ImmutableMap<String, String> DEFAULT_ENV_VARS =
24+
ImmutableMap.of(
25+
"WEBSITE_SITE_NAME", TEST_WEBSITE_SITE_NAME,
26+
"REGION_NAME", TEST_REGION_NAME,
27+
"WEBSITE_MEMORY_LIMIT_MB", TEST_MEM_LIMIT,
28+
"FUNCTIONS_EXTENSION_VERSION", TEST_FUNCTION_VERSION,
29+
"WEBSITE_INSTANCE_ID", TEST_WEBSITE_INSTANCE_ID);
30+
31+
@Test
32+
void defaultValues() {
33+
createResource(DEFAULT_ENV_VARS)
34+
.containsEntry(ResourceAttributes.CLOUD_PROVIDER, "azure")
35+
.containsEntry(ResourceAttributes.CLOUD_PLATFORM, "azure_functions")
36+
.containsEntry(ResourceAttributes.FAAS_NAME, TEST_WEBSITE_SITE_NAME)
37+
.containsEntry(ResourceAttributes.FAAS_VERSION, TEST_FUNCTION_VERSION)
38+
.containsEntry(ResourceAttributes.FAAS_INSTANCE, TEST_WEBSITE_INSTANCE_ID)
39+
.containsEntry(ResourceAttributes.FAAS_MAX_MEMORY, Long.parseLong(TEST_MEM_LIMIT));
40+
}
41+
42+
@Test
43+
void isNotFunction() {
44+
HashMap<String, String> map = new HashMap<>(DEFAULT_ENV_VARS);
45+
map.remove("FUNCTIONS_EXTENSION_VERSION");
46+
47+
createResource(map).isEmpty();
48+
}
49+
50+
@NotNull
51+
private static AttributesAssert createResource(Map<String, String> map) {
52+
return OpenTelemetryAssertions.assertThat(
53+
new AzureFunctionsResourceProvider(map).createResource(null).getAttributes());
54+
}
55+
}

0 commit comments

Comments
 (0)