diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/CgroupV1ContainerIdExtractor.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/CgroupV1ContainerIdExtractor.java index ff19dc902017..dcd1f3844ad0 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/CgroupV1ContainerIdExtractor.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/CgroupV1ContainerIdExtractor.java @@ -20,14 +20,21 @@ final class CgroupV1ContainerIdExtractor { Logger.getLogger(CgroupV1ContainerIdExtractor.class.getName()); static final Path V1_CGROUP_PATH = Paths.get("/proc/self/cgroup"); private final ContainerResource.Filesystem filesystem; + private final Path inputFilePath; CgroupV1ContainerIdExtractor() { - this(ContainerResource.FILESYSTEM_INSTANCE); + this(ContainerResource.FILESYSTEM_INSTANCE, V1_CGROUP_PATH); } // Exists for testing CgroupV1ContainerIdExtractor(ContainerResource.Filesystem filesystem) { + this(filesystem, V1_CGROUP_PATH); + } + + // Exists for testing + CgroupV1ContainerIdExtractor(ContainerResource.Filesystem filesystem, Path inputFilePath) { this.filesystem = filesystem; + this.inputFilePath = inputFilePath; } /** @@ -38,10 +45,10 @@ final class CgroupV1ContainerIdExtractor { * @return containerId */ Optional extractContainerId() { - if (!filesystem.isReadable(V1_CGROUP_PATH)) { + if (!filesystem.isReadable(inputFilePath)) { return Optional.empty(); } - try (Stream lines = filesystem.lines(V1_CGROUP_PATH)) { + try (Stream lines = filesystem.lines(inputFilePath)) { return lines .filter(line -> !line.isEmpty()) .map(CgroupV1ContainerIdExtractor::getIdFromLine) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/ContainerResource.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/ContainerResource.java index db46fbb138cb..f11366fbb200 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/ContainerResource.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/ContainerResource.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.resources.Resource; import java.io.IOException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -77,7 +78,11 @@ boolean isReadable(Path path) { @MustBeClosed Stream lines(Path path) throws IOException { - return Files.lines(path); + return Files.lines(path, getDefaultCharset()); + } + + Charset getDefaultCharset() { + return Charset.defaultCharset(); } List lineList(Path path) throws IOException { diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/ContainerResourceTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/ContainerResourceTest.java index 8e826a6f2b6c..9b7ba9b9d282 100644 --- a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/ContainerResourceTest.java +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/ContainerResourceTest.java @@ -11,6 +11,10 @@ import static org.mockito.Mockito.when; import io.opentelemetry.sdk.resources.Resource; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -50,4 +54,39 @@ void bothVersionsFail() { Resource resource = containerResource.buildResource(); assertThat(resource).isSameAs(Resource.empty()); } + + @Test + void testAlternateEncoding() throws Exception { + String containerId = "ac679f8a8319c8cf7d38e1adf263bc08d231f2ff81abda3915f6e8ba4d64156a"; + String line = "13:name=systemd:/podruntime/docker/kubepods/" + containerId + ".aaaa"; + Charset ibmCharset = Charset.forName("IBM-273"); + byte[] utf8 = line.getBytes(StandardCharsets.UTF_8); + byte[] ibm = line.getBytes(ibmCharset); + assertThat(ibm).isNotEqualTo(utf8); + + String ibmAsString = new String(ibm, ibmCharset); + // Different bytes, different encoding, same semantic string value + assertThat(line).isEqualTo(ibmAsString); + + // Make temp file that contains the IBM encoding + File tempFile = File.createTempFile("tmp", "mountinfo"); + tempFile.deleteOnExit(); + try (FileOutputStream out = new FileOutputStream(tempFile)) { + out.write(ibm); + } + ContainerResource.Filesystem fs = + new ContainerResource.Filesystem() { + @Override + Charset getDefaultCharset() { + // Override to pretend our default encoding is ibm273 + return ibmCharset; + } + }; + CgroupV1ContainerIdExtractor extractor = + new CgroupV1ContainerIdExtractor(fs, tempFile.toPath()); + ContainerResource testClass = new ContainerResource(extractor, null); + + Resource resource = testClass.buildResource(); + assertThat(resource.getAttribute(CONTAINER_ID)).isEqualTo(containerId); + } }