Skip to content

Commit 77a44e3

Browse files
Remove io.pivotal.cfenv
To avoid version conflicts, this dependency was removed. The logic was rewritten to only use the JsonParser provided by Jackson from the OTel Java Agent. The resource provider is now built on the community version of the CF resources and can even emit the attributes following the official semantic conventions by configuration. Signed-off-by: Karsten Schnitter <[email protected]>
1 parent 58d1eb3 commit 77a44e3

28 files changed

+778
-418
lines changed

cf-java-logging-support-opentelemetry-agent-extension/dependency-reduced-pom.xml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
<configuration>
2323
<filters>
2424
<filter>
25-
<artifact>io.pivotal.cfenv:java-cfenv</artifact>
25+
<artifact>io.opentelemetry.contrib:opentelemetry-cloudfoundry-resources</artifact>
2626
<includes>
27-
<include>io/pivotal/cfenv/**</include>
27+
<include>io/opentelemetry/contrib/cloudfoundry/resources/CloudFoundryResource.class</include>
2828
</includes>
2929
</filter>
3030
</filters>
3131
<artifactSet>
3232
<excludes>
3333
<exclude>io.opentelemetry</exclude>
34+
<exclude>io.opentelemetry.semconv</exclude>
3435
<exclude>com.fasterxml.jackson.core</exclude>
3536
<exclude>com.squareup.okhttp3</exclude>
3637
<exclude>com.squareup.okio</exclude>
@@ -70,6 +71,24 @@
7071
<version>1.31.0</version>
7172
<scope>compile</scope>
7273
</dependency>
74+
<dependency>
75+
<groupId>com.fasterxml.jackson.core</groupId>
76+
<artifactId>jackson-core</artifactId>
77+
<version>2.18.2</version>
78+
<scope>compile</scope>
79+
</dependency>
80+
<dependency>
81+
<groupId>uk.org.webcompere</groupId>
82+
<artifactId>system-stubs-junit4</artifactId>
83+
<version>2.1.8</version>
84+
<scope>test</scope>
85+
<exclusions>
86+
<exclusion>
87+
<artifactId>system-stubs-core</artifactId>
88+
<groupId>uk.org.webcompere</groupId>
89+
</exclusion>
90+
</exclusions>
91+
</dependency>
7392
<dependency>
7493
<groupId>org.slf4j</groupId>
7594
<artifactId>slf4j-api</artifactId>

cf-java-logging-support-opentelemetry-agent-extension/pom.xml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,20 @@
5555
<artifactId>opentelemetry-exporter-otlp</artifactId>
5656
</dependency>
5757
<dependency>
58-
<groupId>io.pivotal.cfenv</groupId>
59-
<artifactId>java-cfenv</artifactId>
60-
<version>2.5.0</version>
58+
<groupId>io.opentelemetry.contrib</groupId>
59+
<artifactId>opentelemetry-cloudfoundry-resources</artifactId>
60+
<version>1.46.0-alpha</version>
61+
</dependency>
62+
<dependency>
63+
<groupId>com.fasterxml.jackson.core</groupId>
64+
<artifactId>jackson-core</artifactId>
65+
<version>${jackson-jr.version}</version>
66+
</dependency>
67+
<dependency>
68+
<groupId>uk.org.webcompere</groupId>
69+
<artifactId>system-stubs-junit4</artifactId>
70+
<version>2.1.8</version>
71+
<scope>test</scope>
6172
</dependency>
6273
</dependencies>
6374

@@ -76,15 +87,18 @@
7687
<configuration>
7788
<filters>
7889
<filter>
79-
<artifact>io.pivotal.cfenv:java-cfenv</artifact>
90+
<artifact>io.opentelemetry.contrib:opentelemetry-cloudfoundry-resources</artifact>
8091
<includes>
81-
<include>io/pivotal/cfenv/**</include>
92+
<include>
93+
io/opentelemetry/contrib/cloudfoundry/resources/CloudFoundryResource.class
94+
</include>
8295
</includes>
8396
</filter>
8497
</filters>
8598
<artifactSet>
8699
<excludes>
87100
<exclude>io.opentelemetry</exclude>
101+
<exclude>io.opentelemetry.semconv</exclude>
88102
<exclude>com.fasterxml.jackson.core</exclude>
89103
<exclude>com.squareup.okhttp3</exclude>
90104
<exclude>com.squareup.okio</exclude>
@@ -106,4 +120,4 @@
106120
</plugin>
107121
</plugins>
108122
</build>
109-
</project>
123+
</project>

cf-java-logging-support-opentelemetry-agent-extension/src/main/java/com/sap/hcf/cf/logging/opentelemetry/agent/ext/CloudFoundryResourceProvider.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,16 @@
22

33
import com.sap.hcf.cf.logging.opentelemetry.agent.ext.attributes.CloudFoundryResourceCustomizer;
44
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
5-
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
65
import io.opentelemetry.sdk.resources.Resource;
7-
import io.pivotal.cfenv.core.CfEnv;
86

9-
public class CloudFoundryResourceProvider implements ResourceProvider {
7+
public class CloudFoundryResourceProvider
8+
extends io.opentelemetry.contrib.cloudfoundry.resources.CloudFoundryResourceProvider {
109

11-
private final CloudFoundryResourceCustomizer customizer;
12-
13-
public CloudFoundryResourceProvider() {
14-
this(new CfEnv());
15-
}
16-
17-
public CloudFoundryResourceProvider(CfEnv cfEnv) {
18-
this.customizer = new CloudFoundryResourceCustomizer(cfEnv);
19-
}
10+
private final CloudFoundryResourceCustomizer customizer = new CloudFoundryResourceCustomizer();
2011

2112
@Override
2213
public Resource createResource(ConfigProperties configProperties) {
23-
return customizer.apply(null, configProperties);
14+
Resource original = super.createResource(configProperties);
15+
return customizer.apply(original, configProperties);
2416
}
2517
}

cf-java-logging-support-opentelemetry-agent-extension/src/main/java/com/sap/hcf/cf/logging/opentelemetry/agent/ext/CloudLoggingConfigurationCustomizerProvider.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,18 @@
33
import com.sap.hcf.cf.logging.opentelemetry.agent.ext.binding.CloudLoggingBindingPropertiesSupplier;
44
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
55
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
6-
import io.pivotal.cfenv.core.CfEnv;
76

87
import java.util.logging.Logger;
98

109
public class CloudLoggingConfigurationCustomizerProvider implements AutoConfigurationCustomizerProvider {
1110

1211
private static final Logger LOG = Logger.getLogger(CloudLoggingConfigurationCustomizerProvider.class.getName());
1312
private static final String VERSION = "3.8.4";
14-
private static final CfEnv cfEnv = new CfEnv();
1513

1614
@Override
1715
public void customize(AutoConfigurationCustomizer autoConfiguration) {
1816
LOG.info("Initializing SAP BTP Observability extension " + VERSION);
19-
autoConfiguration
20-
.addPropertiesSupplier(new CloudLoggingBindingPropertiesSupplier());
17+
autoConfiguration.addPropertiesSupplier(new CloudLoggingBindingPropertiesSupplier());
2118

2219
// ConfigurableLogRecordExporterProvider
2320
}
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,36 @@
11
package com.sap.hcf.cf.logging.opentelemetry.agent.ext.attributes;
22

3+
import io.opentelemetry.api.common.AttributeKey;
34
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
45
import io.opentelemetry.sdk.resources.Resource;
56
import io.opentelemetry.sdk.resources.ResourceBuilder;
6-
import io.pivotal.cfenv.core.CfApplication;
7-
import io.pivotal.cfenv.core.CfEnv;
87

9-
import java.util.Optional;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.function.BiConsumer;
1011
import java.util.function.BiFunction;
1112
import java.util.logging.Logger;
1213

1314
public class CloudFoundryResourceCustomizer implements BiFunction<Resource, ConfigProperties, Resource> {
1415

15-
private static final String OTEL_JAVAAGENT_EXTENSION_SAP_CF_RESOURCE_ENABLED = "otel.javaagent.extension.sap.cf.resource.enabled";
16+
private static final String OTEL_JAVAAGENT_EXTENSION_SAP_CF_RESOURCE_ENABLED =
17+
"otel.javaagent.extension.sap.cf.resource.enabled";
18+
19+
private static final String OTEL_JAVAAGENT_EXTENTION_CF_RESOURCE_FORMAT =
20+
"otel.javaagent.extension.sap.cf.resource.format";
1621
private static final Logger LOG = Logger.getLogger(CloudFoundryResourceCustomizer.class.getName());
17-
private final CfEnv cfEnv;
1822

19-
public CloudFoundryResourceCustomizer(CfEnv cfEnv) {
20-
this.cfEnv = cfEnv;
21-
}
23+
private static final Map<String, String> SAP_CF_RESOURCE_ATTRIBUTES = new HashMap<String, String>() {{
24+
put("cloudfoundry.app.id", "sap.cf.app_id");
25+
put("cloudfoundry.app.instance.id", "sap.cf.instance_id");
26+
put("cloudfoundry.app.name", "sap.cf.app_name");
27+
put("cloudfoundry.org.id", "sap.cf.org_id");
28+
put("cloudfoundry.org.name", "sap.cf.org_name");
29+
put("cloudfoundry.process.id", "sap.cf.process.id");
30+
put("cloudfoundry.process.type", "sap.cf.process.type");
31+
put("cloudfoundry.space.id", "sap.cf.space_id");
32+
put("cloudfoundry.space.name", "sap.cf.space_name");
33+
}};
2234

2335
@Override
2436
public Resource apply(Resource resource, ConfigProperties configProperties) {
@@ -27,32 +39,62 @@ public Resource apply(Resource resource, ConfigProperties configProperties) {
2739
LOG.config("CF resource attributes are disabled by configuration.");
2840
return Resource.empty();
2941
}
30-
if (!cfEnv.isInCf()) {
42+
43+
if (resource == null || resource.getAttributes().isEmpty()) {
3144
LOG.config("Not running in CF. Cannot obtain CF resource attributes.");
32-
return Resource.empty();
45+
return resource;
46+
}
47+
48+
String format = configProperties.getString(OTEL_JAVAAGENT_EXTENTION_CF_RESOURCE_FORMAT, "SAP");
49+
if (!format.equalsIgnoreCase("SAP")) {
50+
return resource;
51+
}
52+
53+
ResourceBuilder builder = Resource.builder();
54+
resource.getAttributes().asMap().forEach(addAttribute(builder));
55+
String appId = resource.getAttribute(AttributeKey.stringKey("cloudfoundry.app.id"));
56+
builder.put("sap.cf.source_id", appId);
57+
String appName = resource.getAttribute(AttributeKey.stringKey("cloudfoundry.app.name"));
58+
String serviceName = resource.getAttribute(AttributeKey.stringKey("service.name"));
59+
if (serviceName == null) {
60+
builder.put("service.name", appName);
3361
}
34-
CfApplication cfApp = cfEnv.getApp();
35-
ResourceBuilder rb = Resource.builder();
36-
rb.put("service.name", cfApp.getApplicationName());
37-
rb.put("sap.cf.source_id", cfApp.getApplicationId());
38-
rb.put("sap.cf.instance_id", cfApp.getInstanceIndex());
39-
rb.put("sap.cf.app_id", cfApp.getApplicationId());
40-
rb.put("sap.cf.app_name", cfApp.getApplicationName());
41-
rb.put("sap.cf.space_id", cfApp.getSpaceId());
42-
rb.put("sap.cf.space_name", cfApp.getSpaceName());
43-
rb.put("sap.cf.org_id", getString(cfApp, "organization_id"));
44-
rb.put("sap.cf.org_name", getString(cfApp, "organization_name"));
45-
rb.put("sap.cf.process.id", getString(cfApp, "process_id"));
46-
rb.put("sap.cf.process.type", getString(cfApp, "process_type"));
47-
return rb.build();
62+
return builder.build();
63+
}
64+
65+
private BiConsumer<AttributeKey<?>, Object> addAttribute(ResourceBuilder builder) {
66+
return (k, v) -> {
67+
switch (k.getType()) {
68+
case BOOLEAN:
69+
builder.put(rename(k), (boolean) v);
70+
break;
71+
case BOOLEAN_ARRAY:
72+
builder.put(rename(k), (boolean[]) v);
73+
break;
74+
case DOUBLE:
75+
builder.put(rename(k), (double) v);
76+
break;
77+
case DOUBLE_ARRAY:
78+
builder.put(rename(k), (double[]) v);
79+
break;
80+
case LONG:
81+
builder.put(rename(k), (long) v);
82+
break;
83+
case LONG_ARRAY:
84+
builder.put(rename(k), (long[]) v);
85+
break;
86+
case STRING:
87+
builder.put(rename(k), (String) v);
88+
break;
89+
case STRING_ARRAY:
90+
builder.put(rename(k), (String[]) v);
91+
break;
92+
}
93+
};
4894
}
4995

50-
private String getString(CfApplication cfApp, String key) {
51-
return Optional.ofNullable(cfApp)
52-
.map(CfApplication::getMap)
53-
.map(m -> m.get(key))
54-
.filter(String.class::isInstance)
55-
.map(String.class::cast)
56-
.orElse("");
96+
private String rename(AttributeKey<?> key) {
97+
String name = key.getKey();
98+
return SAP_CF_RESOURCE_ATTRIBUTES.getOrDefault(name, name);
5799
}
58100
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.sap.hcf.cf.logging.opentelemetry.agent.ext.binding;
2+
3+
import java.util.Map;
4+
import java.util.TreeMap;
5+
6+
public class CloudFoundryCredentials {
7+
8+
private final Map<String, String> properties;
9+
10+
private CloudFoundryCredentials(Builder builder) {
11+
this.properties = builder.properties;
12+
}
13+
14+
public String getString(String key) {
15+
return properties.get(key);
16+
}
17+
18+
public static Builder builder() {
19+
return new Builder();
20+
}
21+
22+
public static class Builder {
23+
24+
private final Map<String, String> properties = new TreeMap<>();
25+
26+
private Builder() {
27+
}
28+
29+
public CloudFoundryCredentials build() {
30+
return new CloudFoundryCredentials(this);
31+
}
32+
33+
public Builder add(String key, String value) {
34+
if (isNotBlank(key) && isNotBlank(value)) {
35+
properties.put(key, value);
36+
}
37+
return this;
38+
}
39+
40+
private boolean isNotBlank(String string) {
41+
return string != null && !string.trim().isEmpty();
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)