From 07ed6b4b870093675e03d392cae393a194474188 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 21 Feb 2024 16:15:06 +0100 Subject: [PATCH 01/13] add host.id resource provider --- .../resources/HostIdResourceProvider.java | 176 ++++++++++++++++++ .../resources/HostIdResourceProviderTest.java | 144 ++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java create mode 100644 instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java new file mode 100644 index 000000000000..edfbf2bcc39e --- /dev/null +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -0,0 +1,176 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.resources; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; +import io.opentelemetry.sdk.resources.Resource; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** {@link ResourceProvider} for automatically configuring host.id. */ +public final class HostIdResourceProvider implements ConditionalResourceProvider { + + private static final Logger logger = Logger.getLogger(HostIdResourceProvider.class.getName()); + + public static final AttributeKey HOST_ID = AttributeKey.stringKey("host.id"); + public static final String REGISTRY_QUERY = + "reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid"; + + private final Supplier getOsType; + + private final Function> pathReader; + + private final Supplier queryWindowsRegistry; + + enum OsType { + WINDOWS, + LINUX + } + + static class ExecResult { + int exitCode; + List lines; + + public ExecResult(int exitCode, List lines) { + this.exitCode = exitCode; + this.lines = lines; + } + } + + public HostIdResourceProvider() { + this( + HostIdResourceProvider::getOsType, + path -> { + try { + return Files.readAllLines(path); + } catch (IOException e) { + throw new IllegalStateException(e); + } + }, + HostIdResourceProvider::queryWindowsRegistry); + } + + // Visible for testing + HostIdResourceProvider( + Supplier getOsType, + Function> pathReader, + Supplier queryWindowsRegistry) { + this.getOsType = getOsType; + this.pathReader = pathReader; + this.queryWindowsRegistry = queryWindowsRegistry; + } + + @Override + public Resource createResource(ConfigProperties config) { + OsType osType = getOsType.get(); + switch (osType) { + case WINDOWS: + return readWindowsGuid(); + case LINUX: + return readLinuxMachineId(); + } + throw new IllegalStateException("Unsupported OS type: " + osType); + } + + private Resource readLinuxMachineId() { + Path path = FileSystems.getDefault().getPath("/etc/machine-id"); + try { + List lines = pathReader.apply(path); + if (lines.isEmpty()) { + logger.warning("Failed to read /etc/machine-id: empty file"); + return Resource.empty(); + } + return Resource.create(Attributes.of(HOST_ID, lines.get(0))); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "Failed to read /etc/machine-id", e); + return Resource.empty(); + } + } + + private static OsType getOsType() { + String osName = System.getProperty("os.name"); + return osName != null && osName.startsWith("Windows") ? OsType.WINDOWS : OsType.LINUX; + } + + private Resource readWindowsGuid() { + + try { + ExecResult execResult = queryWindowsRegistry.get(); + + if (execResult.exitCode != 0) { + logger.warning( + "Failed to read Windows registry. Exit code: " + + execResult.exitCode + + " Output: " + + String.join("\n", execResult.lines)); + return Resource.empty(); + } + + for (String line : execResult.lines) { + if (line.contains("MachineGuid")) { + String[] parts = line.trim().split("\\s+"); + if (parts.length == 3) { + return Resource.create(Attributes.of(HOST_ID, parts[2])); + } + } + } + logger.warning( + "Failed to read Windows registry: No MachineGuid found in output: " + execResult.lines); + return Resource.empty(); + } catch (RuntimeException e) { + logger.log(Level.WARNING, "Failed to read Windows registry", e); + return Resource.empty(); + } + } + + private static ExecResult queryWindowsRegistry() { + try { + Process process = Runtime.getRuntime().exec(REGISTRY_QUERY); + + if (process.waitFor() != 0) { + return new ExecResult(process.exitValue(), getLines(process.getErrorStream())); + } + + return new ExecResult(0, getLines(process.getInputStream())); + } catch (IOException | InterruptedException e) { + throw new IllegalStateException(e); + } + } + + private static List getLines(InputStream inputStream) { + return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.toList()); + } + + @Override + public boolean shouldApply(ConfigProperties config, Resource existing) { + return !config.getMap("otel.resource.attributes").containsKey(HOST_ID.getKey()) + && existing.getAttribute(HOST_ID) == null; + } + + @Override + public int order() { + // Run after cloud provider resource providers + return Integer.MAX_VALUE - 1; + } +} diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java new file mode 100644 index 000000000000..50d54f8468fc --- /dev/null +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java @@ -0,0 +1,144 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.resources; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.resources.Resource; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.assertj.core.api.MapAssert; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; + +class HostIdResourceProviderTest { + + private static class LinuxTestCase { + private final String name; + private final String expectedValue; + private final Function> pathReader; + + private LinuxTestCase( + String name, String expectedValue, Function> pathReader) { + this.name = name; + this.expectedValue = expectedValue; + this.pathReader = pathReader; + } + } + + private static class WindowsTestCase { + private final String name; + private final String expectedValue; + private final Supplier queryWindowsRegistry; + + private WindowsTestCase( + String name, + String expectedValue, + Supplier queryWindowsRegistry) { + this.name = name; + this.expectedValue = expectedValue; + this.queryWindowsRegistry = queryWindowsRegistry; + } + } + + @TestFactory + Collection createResourceLinux() { + return Stream.of( + new LinuxTestCase("default", "test", path -> Collections.singletonList("test")), + new LinuxTestCase("empty file", null, path -> Collections.emptyList()), + new LinuxTestCase( + "error reading", + null, + path -> { + throw new IllegalStateException("can't read file"); + })) + .map( + testCase -> + DynamicTest.dynamicTest( + testCase.name, + () -> { + HostIdResourceProvider provider = + new HostIdResourceProvider( + () -> HostIdResourceProvider.OsType.LINUX, testCase.pathReader, null); + + assertHostId(testCase.expectedValue, provider); + })) + .collect(Collectors.toList()); + } + + @TestFactory + Collection createResourceWindows() { + return Stream.of( + new WindowsTestCase( + "default", + "test", + () -> + new HostIdResourceProvider.ExecResult( + 0, + Arrays.asList( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", + " MachineGuid REG_SZ test"))), + new WindowsTestCase( + "error code", + null, + () -> new HostIdResourceProvider.ExecResult(1, Collections.emptyList())), + new WindowsTestCase( + "short output", + null, + () -> new HostIdResourceProvider.ExecResult(0, Collections.emptyList()))) + .map( + testCase -> + DynamicTest.dynamicTest( + testCase.name, + () -> { + HostIdResourceProvider provider = + new HostIdResourceProvider( + () -> HostIdResourceProvider.OsType.WINDOWS, + null, + testCase.queryWindowsRegistry); + + assertHostId(testCase.expectedValue, provider); + })) + .collect(Collectors.toList()); + } + + private static void assertHostId(String expectedValue, HostIdResourceProvider provider) { + MapAssert, Object> that = + assertThat(provider.createResource(null).getAttributes().asMap()); + + if (expectedValue == null) { + that.isEmpty(); + } else { + that.containsEntry(HostIdResourceProvider.HOST_ID, expectedValue); + } + } + + @Test + void shouldApply() { + HostIdResourceProvider provider = new HostIdResourceProvider(); + assertThat( + provider.shouldApply( + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + Resource.getDefault())) + .isTrue(); + assertThat( + provider.shouldApply( + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.resource.attributes", "host.id=foo")), + null)) + .isFalse(); + } +} From f21dfb8cdfc9c259b81a2479a3d3955cf8715308 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 22 Feb 2024 13:49:07 +0100 Subject: [PATCH 02/13] simplify code --- .../resources/HostIdResourceProvider.java | 44 ++++++++++--------- .../resources/HostIdResourceProviderTest.java | 3 +- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index edfbf2bcc39e..4b40d80e8ea1 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -5,12 +5,12 @@ package io.opentelemetry.instrumentation.resources; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.semconv.ResourceAttributes; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -19,6 +19,7 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; @@ -31,13 +32,12 @@ public final class HostIdResourceProvider implements ConditionalResourceProvider private static final Logger logger = Logger.getLogger(HostIdResourceProvider.class.getName()); - public static final AttributeKey HOST_ID = AttributeKey.stringKey("host.id"); public static final String REGISTRY_QUERY = "reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid"; private final Supplier getOsType; - private final Function> pathReader; + private final Function> machineIdReader; private final Supplier queryWindowsRegistry; @@ -59,23 +59,18 @@ public ExecResult(int exitCode, List lines) { public HostIdResourceProvider() { this( HostIdResourceProvider::getOsType, - path -> { - try { - return Files.readAllLines(path); - } catch (IOException e) { - throw new IllegalStateException(e); - } - }, + HostIdResourceProvider::readMachineIdFile, HostIdResourceProvider::queryWindowsRegistry); } // Visible for testing + HostIdResourceProvider( Supplier getOsType, - Function> pathReader, + Function> machineIdReader, Supplier queryWindowsRegistry) { this.getOsType = getOsType; - this.pathReader = pathReader; + this.machineIdReader = machineIdReader; this.queryWindowsRegistry = queryWindowsRegistry; } @@ -93,16 +88,23 @@ public Resource createResource(ConfigProperties config) { private Resource readLinuxMachineId() { Path path = FileSystems.getDefault().getPath("/etc/machine-id"); + List lines = machineIdReader.apply(path); + if (lines.isEmpty()) { + return Resource.empty(); + } + return Resource.create(Attributes.of(ResourceAttributes.HOST_ID, lines.get(0))); + } + + private static List readMachineIdFile(Path path) { try { - List lines = pathReader.apply(path); + List lines = Files.readAllLines(path); if (lines.isEmpty()) { logger.warning("Failed to read /etc/machine-id: empty file"); - return Resource.empty(); } - return Resource.create(Attributes.of(HOST_ID, lines.get(0))); - } catch (RuntimeException e) { + return lines; + } catch (IOException e) { logger.log(Level.WARNING, "Failed to read /etc/machine-id", e); - return Resource.empty(); + return Collections.emptyList(); } } @@ -129,7 +131,7 @@ private Resource readWindowsGuid() { if (line.contains("MachineGuid")) { String[] parts = line.trim().split("\\s+"); if (parts.length == 3) { - return Resource.create(Attributes.of(HOST_ID, parts[2])); + return Resource.create(Attributes.of(ResourceAttributes.HOST_ID, parts[2])); } } } @@ -164,8 +166,10 @@ private static List getLines(InputStream inputStream) { @Override public boolean shouldApply(ConfigProperties config, Resource existing) { - return !config.getMap("otel.resource.attributes").containsKey(HOST_ID.getKey()) - && existing.getAttribute(HOST_ID) == null; + return !config + .getMap("otel.resource.attributes") + .containsKey(ResourceAttributes.HOST_ID.getKey()) + && existing.getAttribute(ResourceAttributes.HOST_ID) == null; } @Override diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java index 50d54f8468fc..a137b6367ac6 100644 --- a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java @@ -10,6 +10,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.semconv.ResourceAttributes; import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; @@ -122,7 +123,7 @@ private static void assertHostId(String expectedValue, HostIdResourceProvider pr if (expectedValue == null) { that.isEmpty(); } else { - that.containsEntry(HostIdResourceProvider.HOST_ID, expectedValue); + that.containsEntry(ResourceAttributes.HOST_ID, expectedValue); } } From 85f8c7374fd51097e994ad19ffe1900e50366d71 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 22 Feb 2024 13:53:15 +0100 Subject: [PATCH 03/13] simplify code --- .../resources/HostIdResourceProviderTest.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java index a137b6367ac6..a0572c1d93fa 100644 --- a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java @@ -59,13 +59,7 @@ private WindowsTestCase( Collection createResourceLinux() { return Stream.of( new LinuxTestCase("default", "test", path -> Collections.singletonList("test")), - new LinuxTestCase("empty file", null, path -> Collections.emptyList()), - new LinuxTestCase( - "error reading", - null, - path -> { - throw new IllegalStateException("can't read file"); - })) + new LinuxTestCase("empty file or error reading", null, path -> Collections.emptyList())) .map( testCase -> DynamicTest.dynamicTest( From 44f74621e029ffce9cb675e40ba08d02d73cd220 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 22 Feb 2024 16:36:26 +0100 Subject: [PATCH 04/13] host.id resource provider --- .../resources/HostIdResourceProvider.java | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index 4b40d80e8ea1..063bac6ceadc 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -21,13 +21,19 @@ import java.nio.file.Path; import java.util.Collections; import java.util.List; +import java.util.Locale; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -/** {@link ResourceProvider} for automatically configuring host.id. */ +/** + * {@link ResourceProvider} for automatically configuring host.id according to the + * semantic conventions + */ public final class HostIdResourceProvider implements ConditionalResourceProvider { private static final Logger logger = Logger.getLogger(HostIdResourceProvider.class.getName()); @@ -43,7 +49,8 @@ public final class HostIdResourceProvider implements ConditionalResourceProvider enum OsType { WINDOWS, - LINUX + LINUX, + OTHER } static class ExecResult { @@ -82,8 +89,11 @@ public Resource createResource(ConfigProperties config) { return readWindowsGuid(); case LINUX: return readLinuxMachineId(); + case OTHER: + break; } - throw new IllegalStateException("Unsupported OS type: " + osType); + logger.info("Unsupported OS type: " + osType); + return Resource.empty(); } private Resource readLinuxMachineId() { @@ -99,27 +109,38 @@ private static List readMachineIdFile(Path path) { try { List lines = Files.readAllLines(path); if (lines.isEmpty()) { - logger.warning("Failed to read /etc/machine-id: empty file"); + logger.info("Failed to read /etc/machine-id: empty file"); } return lines; } catch (IOException e) { - logger.log(Level.WARNING, "Failed to read /etc/machine-id", e); + logger.log(Level.INFO, "Failed to read /etc/machine-id", e); return Collections.emptyList(); } } private static OsType getOsType() { + // see + // https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/SystemUtils.java + // for values String osName = System.getProperty("os.name"); - return osName != null && osName.startsWith("Windows") ? OsType.WINDOWS : OsType.LINUX; + if (osName == null) { + return OsType.OTHER; + } + if (osName.startsWith("Windows")) { + return OsType.WINDOWS; + } + if (osName.toLowerCase(Locale.ROOT).equals("linux")) { + return OsType.LINUX; + } + return OsType.OTHER; } private Resource readWindowsGuid() { - try { ExecResult execResult = queryWindowsRegistry.get(); if (execResult.exitCode != 0) { - logger.warning( + logger.info( "Failed to read Windows registry. Exit code: " + execResult.exitCode + " Output: " @@ -135,20 +156,28 @@ private Resource readWindowsGuid() { } } } - logger.warning( + logger.info( "Failed to read Windows registry: No MachineGuid found in output: " + execResult.lines); return Resource.empty(); } catch (RuntimeException e) { - logger.log(Level.WARNING, "Failed to read Windows registry", e); + logger.log(Level.INFO, "Failed to read Windows registry", e); return Resource.empty(); } } private static ExecResult queryWindowsRegistry() { try { - Process process = Runtime.getRuntime().exec(REGISTRY_QUERY); + ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/c", REGISTRY_QUERY); + processBuilder.redirectErrorStream(true); + Process process = processBuilder.start(); + + if (!process.waitFor(2, TimeUnit.SECONDS)) { + logger.info("Timed out waiting for reg query to complete"); + process.destroy(); + return new ExecResult(-1, Collections.emptyList()); + } - if (process.waitFor() != 0) { + if (process.exitValue() != 0) { return new ExecResult(process.exitValue(), getLines(process.getErrorStream())); } From d528faba1801a2352121c1fca3ef3e5891a761d8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 28 Feb 2024 14:09:41 +0100 Subject: [PATCH 05/13] reduce log level to "fine" - it's not important enough --- .../resources/HostIdResourceProvider.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index 063bac6ceadc..e92898d489a9 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -92,7 +92,7 @@ public Resource createResource(ConfigProperties config) { case OTHER: break; } - logger.info("Unsupported OS type: " + osType); + logger.fine("Unsupported OS type: " + osType); return Resource.empty(); } @@ -109,11 +109,11 @@ private static List readMachineIdFile(Path path) { try { List lines = Files.readAllLines(path); if (lines.isEmpty()) { - logger.info("Failed to read /etc/machine-id: empty file"); + logger.fine("Failed to read /etc/machine-id: empty file"); } return lines; } catch (IOException e) { - logger.log(Level.INFO, "Failed to read /etc/machine-id", e); + logger.log(Level.FINE, "Failed to read /etc/machine-id", e); return Collections.emptyList(); } } @@ -140,7 +140,7 @@ private Resource readWindowsGuid() { ExecResult execResult = queryWindowsRegistry.get(); if (execResult.exitCode != 0) { - logger.info( + logger.fine( "Failed to read Windows registry. Exit code: " + execResult.exitCode + " Output: " @@ -156,11 +156,11 @@ private Resource readWindowsGuid() { } } } - logger.info( + logger.fine( "Failed to read Windows registry: No MachineGuid found in output: " + execResult.lines); return Resource.empty(); } catch (RuntimeException e) { - logger.log(Level.INFO, "Failed to read Windows registry", e); + logger.log(Level.FINE, "Failed to read Windows registry", e); return Resource.empty(); } } @@ -172,7 +172,7 @@ private static ExecResult queryWindowsRegistry() { Process process = processBuilder.start(); if (!process.waitFor(2, TimeUnit.SECONDS)) { - logger.info("Timed out waiting for reg query to complete"); + logger.fine("Timed out waiting for reg query to complete"); process.destroy(); return new ExecResult(-1, Collections.emptyList()); } From f24e321204e9a4bf29b0d1d7e8fc0b65eaf0b790 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 28 Feb 2024 14:20:37 +0100 Subject: [PATCH 06/13] don't throw exception in reading Windows registry --- .../resources/HostIdResourceProvider.java | 55 ++++++++----------- .../resources/HostIdResourceProviderTest.java | 23 ++------ 2 files changed, 30 insertions(+), 48 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index e92898d489a9..cc50571c14e1 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -45,7 +45,7 @@ public final class HostIdResourceProvider implements ConditionalResourceProvider private final Function> machineIdReader; - private final Supplier queryWindowsRegistry; + private final Supplier> queryWindowsRegistry; enum OsType { WINDOWS, @@ -75,7 +75,7 @@ public HostIdResourceProvider() { HostIdResourceProvider( Supplier getOsType, Function> machineIdReader, - Supplier queryWindowsRegistry) { + Supplier> queryWindowsRegistry) { this.getOsType = getOsType; this.machineIdReader = machineIdReader; this.queryWindowsRegistry = queryWindowsRegistry; @@ -136,36 +136,21 @@ private static OsType getOsType() { } private Resource readWindowsGuid() { - try { - ExecResult execResult = queryWindowsRegistry.get(); - - if (execResult.exitCode != 0) { - logger.fine( - "Failed to read Windows registry. Exit code: " - + execResult.exitCode - + " Output: " - + String.join("\n", execResult.lines)); - return Resource.empty(); - } + List lines = queryWindowsRegistry.get(); - for (String line : execResult.lines) { - if (line.contains("MachineGuid")) { - String[] parts = line.trim().split("\\s+"); - if (parts.length == 3) { - return Resource.create(Attributes.of(ResourceAttributes.HOST_ID, parts[2])); - } + for (String line : lines) { + if (line.contains("MachineGuid")) { + String[] parts = line.trim().split("\\s+"); + if (parts.length == 3) { + return Resource.create(Attributes.of(ResourceAttributes.HOST_ID, parts[2])); } } - logger.fine( - "Failed to read Windows registry: No MachineGuid found in output: " + execResult.lines); - return Resource.empty(); - } catch (RuntimeException e) { - logger.log(Level.FINE, "Failed to read Windows registry", e); - return Resource.empty(); } + logger.fine("Failed to read Windows registry: No MachineGuid found in output: " + lines); + return Resource.empty(); } - private static ExecResult queryWindowsRegistry() { + private static List queryWindowsRegistry() { try { ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/c", REGISTRY_QUERY); processBuilder.redirectErrorStream(true); @@ -174,16 +159,24 @@ private static ExecResult queryWindowsRegistry() { if (!process.waitFor(2, TimeUnit.SECONDS)) { logger.fine("Timed out waiting for reg query to complete"); process.destroy(); - return new ExecResult(-1, Collections.emptyList()); + return Collections.emptyList(); } - if (process.exitValue() != 0) { - return new ExecResult(process.exitValue(), getLines(process.getErrorStream())); + int exitedValue = process.exitValue(); + if (exitedValue != 0) { + logger.fine( + "Failed to read Windows registry. Exit code: " + + exitedValue + + " Output: " + + String.join("\n", getLines(process.getErrorStream()))); + + return Collections.emptyList(); } - return new ExecResult(0, getLines(process.getInputStream())); + return getLines(process.getInputStream()); } catch (IOException | InterruptedException e) { - throw new IllegalStateException(e); + logger.log(Level.FINE, "Failed to read Windows registry", e); + return Collections.emptyList(); } } diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java index a0572c1d93fa..b007707fe8ba 100644 --- a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java @@ -43,12 +43,10 @@ private LinuxTestCase( private static class WindowsTestCase { private final String name; private final String expectedValue; - private final Supplier queryWindowsRegistry; + private final Supplier> queryWindowsRegistry; private WindowsTestCase( - String name, - String expectedValue, - Supplier queryWindowsRegistry) { + String name, String expectedValue, Supplier> queryWindowsRegistry) { this.name = name; this.expectedValue = expectedValue; this.queryWindowsRegistry = queryWindowsRegistry; @@ -81,19 +79,10 @@ Collection createResourceWindows() { "default", "test", () -> - new HostIdResourceProvider.ExecResult( - 0, - Arrays.asList( - "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", - " MachineGuid REG_SZ test"))), - new WindowsTestCase( - "error code", - null, - () -> new HostIdResourceProvider.ExecResult(1, Collections.emptyList())), - new WindowsTestCase( - "short output", - null, - () -> new HostIdResourceProvider.ExecResult(0, Collections.emptyList()))) + Arrays.asList( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", + " MachineGuid REG_SZ test")), + new WindowsTestCase("short output", null, Collections::emptyList)) .map( testCase -> DynamicTest.dynamicTest( From b0f79e54bf37136af535a52817f40ec6b889d9c6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 28 Feb 2024 14:22:56 +0100 Subject: [PATCH 07/13] read all input for an error --- .../instrumentation/resources/HostIdResourceProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index cc50571c14e1..f95176f18142 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -168,7 +168,7 @@ private static List queryWindowsRegistry() { "Failed to read Windows registry. Exit code: " + exitedValue + " Output: " - + String.join("\n", getLines(process.getErrorStream()))); + + String.join("\n", getLines(process.getInputStream()))); return Collections.emptyList(); } From d3e2a424f21b7b734b661792d246036860b27427 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 28 Feb 2024 14:35:58 +0100 Subject: [PATCH 08/13] redirect output to file to avoid the issue of creating a separate thread to read the output --- .../resources/HostIdResourceProvider.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index f95176f18142..18c448b4748e 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -11,11 +11,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.ResourceAttributes; -import java.io.BufferedReader; +import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -27,7 +24,6 @@ import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Collectors; /** * {@link ResourceProvider} for automatically configuring host.id according to queryWindowsRegistry() { try { ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/c", REGISTRY_QUERY); processBuilder.redirectErrorStream(true); + File tempFile = File.createTempFile("otel", "regquery"); + processBuilder.redirectOutput(tempFile); Process process = processBuilder.start(); if (!process.waitFor(2, TimeUnit.SECONDS)) { - logger.fine("Timed out waiting for reg query to complete"); process.destroy(); + logger.fine("Timed out waiting for reg query to complete"); return Collections.emptyList(); } @@ -168,22 +166,20 @@ private static List queryWindowsRegistry() { "Failed to read Windows registry. Exit code: " + exitedValue + " Output: " - + String.join("\n", getLines(process.getInputStream()))); + + String.join("\n", getLines(tempFile))); return Collections.emptyList(); } - return getLines(process.getInputStream()); + return getLines(tempFile); } catch (IOException | InterruptedException e) { logger.log(Level.FINE, "Failed to read Windows registry", e); return Collections.emptyList(); } } - private static List getLines(InputStream inputStream) { - return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)) - .lines() - .collect(Collectors.toList()); + private static List getLines(File tempFile) throws IOException { + return Files.readAllLines(tempFile.toPath()); } @Override From 99a9423435dc71024b7e6e1ceba94fa80244f02d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 29 Feb 2024 12:17:46 +0100 Subject: [PATCH 09/13] read all input --- .../resources/HostIdResourceProvider.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index 18c448b4748e..587ac30be987 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -11,11 +11,13 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.ResourceAttributes; -import java.io.File; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -150,10 +152,10 @@ private static List queryWindowsRegistry() { try { ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/c", REGISTRY_QUERY); processBuilder.redirectErrorStream(true); - File tempFile = File.createTempFile("otel", "regquery"); - processBuilder.redirectOutput(tempFile); Process process = processBuilder.start(); + List output = getProcessOutput(process); + if (!process.waitFor(2, TimeUnit.SECONDS)) { process.destroy(); logger.fine("Timed out waiting for reg query to complete"); @@ -166,20 +168,31 @@ private static List queryWindowsRegistry() { "Failed to read Windows registry. Exit code: " + exitedValue + " Output: " - + String.join("\n", getLines(tempFile))); + + String.join("\n", output)); return Collections.emptyList(); } - return getLines(tempFile); + return output; } catch (IOException | InterruptedException e) { logger.log(Level.FINE, "Failed to read Windows registry", e); return Collections.emptyList(); } } - private static List getLines(File tempFile) throws IOException { - return Files.readAllLines(tempFile.toPath()); + public static List getProcessOutput(Process process) + throws IOException, InterruptedException { + List result = new ArrayList<>(); + + try (BufferedReader processOutputReader = + new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String readLine; + + while ((readLine = processOutputReader.readLine()) != null) { + result.add(readLine); + } + } + return result; } @Override From fd676472ce4659b3470cd77694fed0f1a6aa4992 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 4 Mar 2024 14:46:55 +0100 Subject: [PATCH 10/13] simplify process reading --- .../resources/HostIdResourceProvider.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index 587ac30be987..46a2eca60f12 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.ResourceAttributes; +import io.opentelemetry.testing.internal.armeria.internal.shaded.guava.base.Charsets; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -21,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Supplier; import java.util.logging.Level; @@ -155,14 +155,7 @@ private static List queryWindowsRegistry() { Process process = processBuilder.start(); List output = getProcessOutput(process); - - if (!process.waitFor(2, TimeUnit.SECONDS)) { - process.destroy(); - logger.fine("Timed out waiting for reg query to complete"); - return Collections.emptyList(); - } - - int exitedValue = process.exitValue(); + int exitedValue = process.waitFor(); if (exitedValue != 0) { logger.fine( "Failed to read Windows registry. Exit code: " @@ -180,12 +173,11 @@ private static List queryWindowsRegistry() { } } - public static List getProcessOutput(Process process) - throws IOException, InterruptedException { + public static List getProcessOutput(Process process) throws IOException { List result = new ArrayList<>(); try (BufferedReader processOutputReader = - new BufferedReader(new InputStreamReader(process.getInputStream()))) { + new BufferedReader(new InputStreamReader(process.getInputStream(), Charsets.UTF_8))) { String readLine; while ((readLine = processOutputReader.readLine()) != null) { From e1216e67a12e50bc6dd245b3d5899043c86a911f Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Fri, 8 Mar 2024 09:44:09 -0800 Subject: [PATCH 11/13] show without enum --- .../resources/HostIdResourceProvider.java | 73 +++++++------------ .../resources/HostIdResourceProviderTest.java | 4 +- 2 files changed, 28 insertions(+), 49 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index 46a2eca60f12..c6467dec2878 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -11,10 +11,10 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.ResourceAttributes; -import io.opentelemetry.testing.internal.armeria.internal.shaded.guava.base.Charsets; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -39,31 +39,15 @@ public final class HostIdResourceProvider implements ConditionalResourceProvider public static final String REGISTRY_QUERY = "reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid"; - private final Supplier getOsType; + private final Supplier getOsType; private final Function> machineIdReader; private final Supplier> queryWindowsRegistry; - enum OsType { - WINDOWS, - LINUX, - OTHER - } - - static class ExecResult { - int exitCode; - List lines; - - public ExecResult(int exitCode, List lines) { - this.exitCode = exitCode; - this.lines = lines; - } - } - public HostIdResourceProvider() { this( - HostIdResourceProvider::getOsType, + HostIdResourceProvider::getOsTypeSystemProperty, HostIdResourceProvider::readMachineIdFile, HostIdResourceProvider::queryWindowsRegistry); } @@ -71,7 +55,7 @@ public HostIdResourceProvider() { // Visible for testing HostIdResourceProvider( - Supplier getOsType, + Supplier getOsType, Function> machineIdReader, Supplier> queryWindowsRegistry) { this.getOsType = getOsType; @@ -81,19 +65,31 @@ public HostIdResourceProvider() { @Override public Resource createResource(ConfigProperties config) { - OsType osType = getOsType.get(); - switch (osType) { - case WINDOWS: - return readWindowsGuid(); - case LINUX: - return readLinuxMachineId(); - case OTHER: - break; + if(runningWindows()){ + return readWindowsGuid(); + } + if(runningLinux()){ + return readLinuxMachineId(); } - logger.fine("Unsupported OS type: " + osType); + logger.fine("Unsupported OS type: " + getOsType.get()); return Resource.empty(); } + private boolean runningLinux() { + return getOsType.get().toLowerCase(Locale.ROOT).equals("linux"); + } + + private boolean runningWindows() { + return getOsType.get().startsWith("Windows"); + } + + // see + // https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/SystemUtils.java + // for values + private static String getOsTypeSystemProperty() { + return System.getProperty("os.name", ""); + } + private Resource readLinuxMachineId() { Path path = FileSystems.getDefault().getPath("/etc/machine-id"); List lines = machineIdReader.apply(path); @@ -116,23 +112,6 @@ private static List readMachineIdFile(Path path) { } } - private static OsType getOsType() { - // see - // https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/SystemUtils.java - // for values - String osName = System.getProperty("os.name"); - if (osName == null) { - return OsType.OTHER; - } - if (osName.startsWith("Windows")) { - return OsType.WINDOWS; - } - if (osName.toLowerCase(Locale.ROOT).equals("linux")) { - return OsType.LINUX; - } - return OsType.OTHER; - } - private Resource readWindowsGuid() { List lines = queryWindowsRegistry.get(); @@ -177,7 +156,7 @@ public static List getProcessOutput(Process process) throws IOException List result = new ArrayList<>(); try (BufferedReader processOutputReader = - new BufferedReader(new InputStreamReader(process.getInputStream(), Charsets.UTF_8))) { + new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { String readLine; while ((readLine = processOutputReader.readLine()) != null) { diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java index b007707fe8ba..42aa790f32bd 100644 --- a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java @@ -65,7 +65,7 @@ Collection createResourceLinux() { () -> { HostIdResourceProvider provider = new HostIdResourceProvider( - () -> HostIdResourceProvider.OsType.LINUX, testCase.pathReader, null); + () -> "linux", testCase.pathReader, null); assertHostId(testCase.expectedValue, provider); })) @@ -90,7 +90,7 @@ Collection createResourceWindows() { () -> { HostIdResourceProvider provider = new HostIdResourceProvider( - () -> HostIdResourceProvider.OsType.WINDOWS, + () -> "Windows 95", null, testCase.queryWindowsRegistry); From 982a1bd51cca4f765382e40c116e50f4671d42fe Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 11 Mar 2024 15:00:58 +0100 Subject: [PATCH 12/13] fix log statement --- .../resources/HostIdResourceProvider.java | 16 +++++++++------- .../resources/HostIdResourceProviderTest.java | 7 ++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java index c6467dec2878..1c7b366ce04c 100644 --- a/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java +++ b/instrumentation/resources/library/src/main/java/io/opentelemetry/instrumentation/resources/HostIdResourceProvider.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.resources; +import static java.util.logging.Level.FINE; + import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; @@ -24,7 +26,6 @@ import java.util.Locale; import java.util.function.Function; import java.util.function.Supplier; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -65,13 +66,13 @@ public HostIdResourceProvider() { @Override public Resource createResource(ConfigProperties config) { - if(runningWindows()){ + if (runningWindows()) { return readWindowsGuid(); } - if(runningLinux()){ + if (runningLinux()) { return readLinuxMachineId(); } - logger.fine("Unsupported OS type: " + getOsType.get()); + logger.log(FINE, "Unsupported OS type: {0}", getOsType.get()); return Resource.empty(); } @@ -107,7 +108,7 @@ private static List readMachineIdFile(Path path) { } return lines; } catch (IOException e) { - logger.log(Level.FINE, "Failed to read /etc/machine-id", e); + logger.log(FINE, "Failed to read /etc/machine-id", e); return Collections.emptyList(); } } @@ -147,7 +148,7 @@ private static List queryWindowsRegistry() { return output; } catch (IOException | InterruptedException e) { - logger.log(Level.FINE, "Failed to read Windows registry", e); + logger.log(FINE, "Failed to read Windows registry", e); return Collections.emptyList(); } } @@ -156,7 +157,8 @@ public static List getProcessOutput(Process process) throws IOException List result = new ArrayList<>(); try (BufferedReader processOutputReader = - new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { + new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { String readLine; while ((readLine = processOutputReader.readLine()) != null) { diff --git a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java index 42aa790f32bd..100b8cab2a53 100644 --- a/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java +++ b/instrumentation/resources/library/src/test/java/io/opentelemetry/instrumentation/resources/HostIdResourceProviderTest.java @@ -64,8 +64,7 @@ Collection createResourceLinux() { testCase.name, () -> { HostIdResourceProvider provider = - new HostIdResourceProvider( - () -> "linux", testCase.pathReader, null); + new HostIdResourceProvider(() -> "linux", testCase.pathReader, null); assertHostId(testCase.expectedValue, provider); })) @@ -90,9 +89,7 @@ Collection createResourceWindows() { () -> { HostIdResourceProvider provider = new HostIdResourceProvider( - () -> "Windows 95", - null, - testCase.queryWindowsRegistry); + () -> "Windows 95", null, testCase.queryWindowsRegistry); assertHostId(testCase.expectedValue, provider); })) From f44553d29f279894af7cebb2096d8fe6ca7dfe5f Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 11 Mar 2024 16:55:21 +0100 Subject: [PATCH 13/13] add doc --- instrumentation/resources/library/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/instrumentation/resources/library/README.md b/instrumentation/resources/library/README.md index 3a3923d65b54..ca7a790ec2cc 100644 --- a/instrumentation/resources/library/README.md +++ b/instrumentation/resources/library/README.md @@ -26,6 +26,14 @@ Implemented attributes: - `host.name` - `host.arch` +Provider: `io.opentelemetry.instrumentation.resources.HostIdResourceProvider` + +Specification: + +Implemented attributes: + +- `host.id` + ### Operating System Provider: `io.opentelemetry.instrumentation.resources.OsResource`