Skip to content

Commit 7364927

Browse files
benjamin-confinobreedx-splklaurit
authored
Re-enable Agent Detection on Zos (#13730)
Co-authored-by: Jason Plumb <[email protected]> Co-authored-by: Lauri Tulmin <[email protected]>
1 parent b5492e8 commit 7364927

File tree

3 files changed

+73
-10
lines changed

3 files changed

+73
-10
lines changed

instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/CgroupV1ContainerIdExtractor.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,21 @@ final class CgroupV1ContainerIdExtractor {
2020
Logger.getLogger(CgroupV1ContainerIdExtractor.class.getName());
2121
static final Path V1_CGROUP_PATH = Paths.get("/proc/self/cgroup");
2222
private final ContainerResource.Filesystem filesystem;
23+
private final Path inputFilePath;
2324

2425
CgroupV1ContainerIdExtractor() {
25-
this(ContainerResource.FILESYSTEM_INSTANCE);
26+
this(ContainerResource.FILESYSTEM_INSTANCE, V1_CGROUP_PATH);
2627
}
2728

2829
// Exists for testing
2930
CgroupV1ContainerIdExtractor(ContainerResource.Filesystem filesystem) {
31+
this(filesystem, V1_CGROUP_PATH);
32+
}
33+
34+
// Exists for testing
35+
CgroupV1ContainerIdExtractor(ContainerResource.Filesystem filesystem, Path inputFilePath) {
3036
this.filesystem = filesystem;
37+
this.inputFilePath = inputFilePath;
3138
}
3239

3340
/**
@@ -38,10 +45,10 @@ final class CgroupV1ContainerIdExtractor {
3845
* @return containerId
3946
*/
4047
Optional<String> extractContainerId() {
41-
if (!filesystem.isReadable(V1_CGROUP_PATH)) {
48+
if (!filesystem.isReadable(inputFilePath)) {
4249
return Optional.empty();
4350
}
44-
try (Stream<String> lines = filesystem.lines(V1_CGROUP_PATH)) {
51+
try (Stream<String> lines = filesystem.lines(inputFilePath)) {
4552
return lines
4653
.filter(line -> !line.isEmpty())
4754
.map(CgroupV1ContainerIdExtractor::getIdFromLine)

instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/ContainerResource.java

+29-7
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010
import io.opentelemetry.api.common.Attributes;
1111
import io.opentelemetry.sdk.resources.Resource;
1212
import java.io.IOException;
13+
import java.nio.charset.Charset;
14+
import java.nio.charset.UnsupportedCharsetException;
1315
import java.nio.file.Files;
1416
import java.nio.file.Path;
1517
import java.util.List;
1618
import java.util.Optional;
19+
import java.util.function.Supplier;
20+
import java.util.logging.Level;
21+
import java.util.logging.Logger;
1722
import java.util.stream.Collectors;
1823
import java.util.stream.Stream;
1924

@@ -50,12 +55,6 @@ private ContainerResource() {
5055

5156
// Visible for testing
5257
Resource buildResource() {
53-
// disable container id detection on z/os
54-
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/12418
55-
String osName = System.getProperty("os.name");
56-
if (osName.equalsIgnoreCase("z/OS") || osName.equalsIgnoreCase("OS/390")) {
57-
return Resource.empty();
58-
}
5958
return getContainerId()
6059
.map(id -> Resource.create(Attributes.of(CONTAINER_ID, id)))
6160
.orElseGet(Resource::empty);
@@ -76,14 +75,37 @@ public static Resource get() {
7675

7776
// Exists for testing
7877
static class Filesystem {
78+
private static final Logger logger = Logger.getLogger(Filesystem.class.getName());
79+
80+
private final Supplier<String> osNameSupplier;
81+
82+
Filesystem() {
83+
this(() -> System.getProperty("os.name"));
84+
}
85+
86+
Filesystem(Supplier<String> osNameSupplier) {
87+
this.osNameSupplier = osNameSupplier;
88+
}
7989

8090
boolean isReadable(Path path) {
8191
return Files.isReadable(path);
8292
}
8393

8494
@MustBeClosed
8595
Stream<String> lines(Path path) throws IOException {
86-
return Files.lines(path);
96+
String osName = osNameSupplier.get();
97+
if (osName.equalsIgnoreCase("z/OS") || osName.equalsIgnoreCase("OS/390")) {
98+
try {
99+
// On z/OS the /proc tree is always encoded with IBM1047 (Canonical name: Cp1047).
100+
return Files.lines(path, Charset.forName("Cp1047"));
101+
} catch (UnsupportedCharsetException e) {
102+
// What charsets are available depends on the instance of the JVM
103+
logger.log(Level.WARNING, "Unable to find charset Cp1047", e);
104+
return Stream.empty();
105+
}
106+
} else {
107+
return Files.lines(path);
108+
}
87109
}
88110

89111
List<String> lineList(Path path) throws IOException {

instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/ContainerResourceTest.java

+34
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import static org.mockito.Mockito.when;
1212

1313
import io.opentelemetry.sdk.resources.Resource;
14+
import java.io.File;
15+
import java.io.FileOutputStream;
16+
import java.nio.charset.Charset;
17+
import java.nio.charset.StandardCharsets;
1418
import java.util.Optional;
1519
import org.junit.jupiter.api.Test;
1620
import org.junit.jupiter.api.extension.ExtendWith;
@@ -50,4 +54,34 @@ void bothVersionsFail() {
5054
Resource resource = containerResource.buildResource();
5155
assertThat(resource).isSameAs(Resource.empty());
5256
}
57+
58+
@Test
59+
void testAlternateEncoding() throws Exception {
60+
String containerId = "ac679f8a8319c8cf7d38e1adf263bc08d231f2ff81abda3915f6e8ba4d64156a";
61+
String line = "13:name=systemd:/podruntime/docker/kubepods/" + containerId + ".aaaa";
62+
Charset ibmCharset = Charset.forName("Cp1047");
63+
byte[] utf8 = line.getBytes(StandardCharsets.UTF_8);
64+
byte[] ibm = line.getBytes(ibmCharset);
65+
assertThat(ibm).isNotEqualTo(utf8);
66+
67+
String ibmAsString = new String(ibm, ibmCharset);
68+
// Different bytes, different encoding, same semantic string value
69+
assertThat(line).isEqualTo(ibmAsString);
70+
71+
// Make temp file that contains the IBM encoding
72+
File tempFile = File.createTempFile("tmp", "mountinfo");
73+
tempFile.deleteOnExit();
74+
try (FileOutputStream out = new FileOutputStream(tempFile)) {
75+
out.write(ibm);
76+
}
77+
ContainerResource.Filesystem fs =
78+
// pretend we are on z/OS to trigger the routine to detect an alternative encoding
79+
new ContainerResource.Filesystem(() -> "z/OS");
80+
CgroupV1ContainerIdExtractor extractor =
81+
new CgroupV1ContainerIdExtractor(fs, tempFile.toPath());
82+
ContainerResource testClass = new ContainerResource(extractor, null);
83+
84+
Resource resource = testClass.buildResource();
85+
assertThat(resource.getAttribute(CONTAINER_ID)).isEqualTo(containerId);
86+
}
5387
}

0 commit comments

Comments
 (0)