Add resource providers (#6574)
* Add resource providers * Use autoservice annotation
This commit is contained in:
parent
0d1b954d9c
commit
6b607c1e18
|
@ -136,6 +136,7 @@ testing {
|
|||
implementation("org.junit.jupiter:junit-jupiter-params")
|
||||
runtimeOnly("org.junit.jupiter:junit-jupiter-engine")
|
||||
runtimeOnly("org.junit.vintage:junit-vintage-engine")
|
||||
implementation("org.junit-pioneer:junit-pioneer")
|
||||
|
||||
|
||||
implementation("org.assertj:assertj-core")
|
||||
|
|
|
@ -106,6 +106,7 @@ val DEPENDENCIES = listOf(
|
|||
"com.google.code.findbugs:jsr305:3.0.2",
|
||||
"org.apache.groovy:groovy:${groovyVersion}",
|
||||
"org.apache.groovy:groovy-json:${groovyVersion}",
|
||||
"org.codehaus.mojo:animal-sniffer-annotations:1.22",
|
||||
"org.junit-pioneer:junit-pioneer:1.7.1",
|
||||
"org.objenesis:objenesis:3.2",
|
||||
"org.spockframework:spock-core:2.2-groovy-4.0",
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# OpenTelemetry Resource Providers
|
||||
|
||||
This package includes some standard `ResourceProvider`s for filling in attributes related to
|
||||
common environments. Currently, the resources provide the following semantic conventions:
|
||||
|
||||
## Populated attributes
|
||||
|
||||
### Container
|
||||
|
||||
Provider: `io.opentelemetry.instrumentation.resources.ContainerResource`
|
||||
|
||||
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/container.md
|
||||
|
||||
Implemented attributes:
|
||||
- `container.id`
|
||||
|
||||
### Host
|
||||
|
||||
Provider: `io.opentelemetry.instrumentation.resources.HostResource`
|
||||
|
||||
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/host.md
|
||||
|
||||
Implemented attributes:
|
||||
- `host.name`
|
||||
- `host.arch`
|
||||
|
||||
### Operating System
|
||||
|
||||
Provider: `io.opentelemetry.instrumentation.resources.OsResource`
|
||||
|
||||
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/os.md
|
||||
|
||||
Implemented attributes:
|
||||
- `os.type`
|
||||
- `os.description`
|
||||
|
||||
### Process
|
||||
|
||||
Implementation: `io.opentelemetry.instrumentation.resources.ProcessResource`
|
||||
|
||||
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/process.md#process
|
||||
|
||||
Implemented attributes:
|
||||
- `process.pid`
|
||||
- `process.executable.path` (note, we assume the `java` binary is located in the `bin` subfolder of `JAVA_HOME`)
|
||||
- `process.command_line` (note this includes all system properties and arguments when running)
|
||||
|
||||
### Java Runtime
|
||||
|
||||
Implementation: `io.opentelemetry.instrumentation.resources.ProcessRuntimeResource`
|
||||
|
||||
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/process.md#process-runtimes
|
||||
|
||||
Implemented attributes:
|
||||
- `process.runtime.name`
|
||||
- `process.runtime.version`
|
||||
- `process.runtime.description`
|
||||
|
||||
## Platforms
|
||||
|
||||
This package currently does not run on Android. It has been verified on OpenJDK and should work on
|
||||
other server JVM distributions but if you find any issues please let us know.
|
|
@ -0,0 +1,64 @@
|
|||
plugins {
|
||||
id("otel.library-instrumentation")
|
||||
id("otel.animalsniffer-conventions")
|
||||
}
|
||||
|
||||
val mrJarVersions = listOf(11)
|
||||
|
||||
dependencies {
|
||||
implementation("io.opentelemetry:opentelemetry-sdk-common")
|
||||
implementation("io.opentelemetry:opentelemetry-semconv")
|
||||
implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
|
||||
|
||||
compileOnly("org.codehaus.mojo:animal-sniffer-annotations")
|
||||
|
||||
annotationProcessor("com.google.auto.service:auto-service")
|
||||
compileOnly("com.google.auto.service:auto-service-annotations")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
}
|
||||
|
||||
for (version in mrJarVersions) {
|
||||
sourceSets {
|
||||
create("java$version") {
|
||||
java {
|
||||
setSrcDirs(listOf("src/main/java$version"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<JavaCompile>("compileJava${version}Java") {
|
||||
sourceCompatibility = "$version"
|
||||
targetCompatibility = "$version"
|
||||
options.release.set(version)
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
named("java${version}Implementation") {
|
||||
extendsFrom(configurations["implementation"])
|
||||
}
|
||||
named("java${version}CompileOnly") {
|
||||
extendsFrom(configurations["compileOnly"])
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Common to reference classes in main sourceset from Java 9 one (e.g., to return a common interface)
|
||||
add("java${version}Implementation", files(sourceSets.main.get().output.classesDirs))
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType(Jar::class) {
|
||||
for (version in mrJarVersions) {
|
||||
into("META-INF/versions/$version") {
|
||||
from(sourceSets["java$version"].output)
|
||||
}
|
||||
}
|
||||
manifest.attributes(
|
||||
"Multi-Release" to "true"
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.internal.OtelEncodingUtils;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nullable;
|
||||
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
|
||||
|
||||
/** Factory for {@link Resource} retrieving Container ID information. */
|
||||
public final class ContainerResource {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ContainerResource.class.getName());
|
||||
private static final String UNIQUE_HOST_NAME_FILE_NAME = "/proc/self/cgroup";
|
||||
private static final Resource INSTANCE = buildSingleton(UNIQUE_HOST_NAME_FILE_NAME);
|
||||
|
||||
@IgnoreJRERequirement
|
||||
private static Resource buildSingleton(String uniqueHostNameFileName) {
|
||||
// can't initialize this statically without running afoul of animalSniffer on paths
|
||||
return buildResource(Paths.get(uniqueHostNameFileName));
|
||||
}
|
||||
|
||||
// package private for testing
|
||||
static Resource buildResource(Path path) {
|
||||
String containerId = extractContainerId(path);
|
||||
|
||||
if (containerId == null || containerId.isEmpty()) {
|
||||
return Resource.empty();
|
||||
} else {
|
||||
return Resource.create(Attributes.of(ResourceAttributes.CONTAINER_ID, containerId));
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns resource with container information. */
|
||||
public static Resource get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each line of cgroup file looks like "14:name=systemd:/docker/.../... A hex string is expected
|
||||
* inside the last section separated by '/' Each segment of the '/' can contain metadata separated
|
||||
* by either '.' (at beginning) or '-' (at end)
|
||||
*
|
||||
* @return containerId
|
||||
*/
|
||||
@IgnoreJRERequirement
|
||||
@Nullable
|
||||
private static String extractContainerId(Path cgroupFilePath) {
|
||||
if (!Files.exists(cgroupFilePath) || !Files.isReadable(cgroupFilePath)) {
|
||||
return null;
|
||||
}
|
||||
try (Stream<String> lines = Files.lines(cgroupFilePath)) {
|
||||
Optional<String> value =
|
||||
lines
|
||||
.filter(line -> !line.isEmpty())
|
||||
.map(ContainerResource::getIdFromLine)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst();
|
||||
if (value.isPresent()) {
|
||||
return value.get();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Unable to read file", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getIdFromLine(String line) {
|
||||
// This cgroup output line should have the container id in it
|
||||
int lastSlashIdx = line.lastIndexOf('/');
|
||||
if (lastSlashIdx < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String containerId;
|
||||
|
||||
String lastSection = line.substring(lastSlashIdx + 1);
|
||||
int colonIdx = lastSection.lastIndexOf(':');
|
||||
|
||||
if (colonIdx != -1) {
|
||||
// since containerd v1.5.0+, containerId is divided by the last colon when the cgroupDriver is
|
||||
// systemd:
|
||||
// https://github.com/containerd/containerd/blob/release/1.5/pkg/cri/server/helpers_linux.go#L64
|
||||
containerId = lastSection.substring(colonIdx + 1);
|
||||
} else {
|
||||
int startIdx = lastSection.lastIndexOf('-');
|
||||
int endIdx = lastSection.lastIndexOf('.');
|
||||
|
||||
startIdx = startIdx == -1 ? 0 : startIdx + 1;
|
||||
if (endIdx == -1) {
|
||||
endIdx = lastSection.length();
|
||||
}
|
||||
if (startIdx > endIdx) {
|
||||
return null;
|
||||
}
|
||||
|
||||
containerId = lastSection.substring(startIdx, endIdx);
|
||||
}
|
||||
|
||||
if (OtelEncodingUtils.isValidBase16String(containerId) && !containerId.isEmpty()) {
|
||||
return containerId;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ContainerResource() {}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
/** {@link ResourceProvider} for automatically configuring {@link ResourceProvider}. */
|
||||
@AutoService(ResourceProvider.class)
|
||||
public class ContainerResourceProvider implements ResourceProvider {
|
||||
@Override
|
||||
public Resource createResource(ConfigProperties config) {
|
||||
return ContainerResource.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.common.AttributesBuilder;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/** Factory for a {@link Resource} which provides information about the host info. */
|
||||
public final class HostResource {
|
||||
|
||||
private static final Resource INSTANCE = buildResource();
|
||||
|
||||
/** Returns a {@link Resource} which provides information about host. */
|
||||
public static Resource get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static Resource buildResource() {
|
||||
AttributesBuilder attributes = Attributes.builder();
|
||||
try {
|
||||
attributes.put(ResourceAttributes.HOST_NAME, InetAddress.getLocalHost().getHostName());
|
||||
} catch (UnknownHostException e) {
|
||||
// Ignore
|
||||
}
|
||||
String hostArch = null;
|
||||
try {
|
||||
hostArch = System.getProperty("os.arch");
|
||||
} catch (SecurityException t) {
|
||||
// Ignore
|
||||
}
|
||||
if (hostArch != null) {
|
||||
attributes.put(ResourceAttributes.HOST_ARCH, hostArch);
|
||||
}
|
||||
|
||||
return Resource.create(attributes.build(), ResourceAttributes.SCHEMA_URL);
|
||||
}
|
||||
|
||||
private HostResource() {}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
/** {@link ResourceProvider} for automatically configuring {@link HostResource}. */
|
||||
@AutoService(ResourceProvider.class)
|
||||
public final class HostResourceProvider implements ResourceProvider {
|
||||
@Override
|
||||
public Resource createResource(ConfigProperties config) {
|
||||
return HostResource.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.common.AttributesBuilder;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Factory of a {@link Resource} which provides information about the current operating system. */
|
||||
public final class OsResource {
|
||||
|
||||
private static final Resource INSTANCE = buildResource();
|
||||
|
||||
/**
|
||||
* Returns a factory for a {@link Resource} which provides information about the current operating
|
||||
* system.
|
||||
*/
|
||||
public static Resource get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static Resource buildResource() {
|
||||
|
||||
String os;
|
||||
try {
|
||||
os = System.getProperty("os.name");
|
||||
} catch (SecurityException t) {
|
||||
// Security manager enabled, can't provide much os information.
|
||||
return Resource.empty();
|
||||
}
|
||||
|
||||
if (os == null) {
|
||||
return Resource.empty();
|
||||
}
|
||||
|
||||
AttributesBuilder attributes = Attributes.builder();
|
||||
|
||||
String osName = getOs(os);
|
||||
if (osName != null) {
|
||||
attributes.put(ResourceAttributes.OS_TYPE, osName);
|
||||
}
|
||||
|
||||
String version = null;
|
||||
try {
|
||||
version = System.getProperty("os.version");
|
||||
} catch (SecurityException e) {
|
||||
// Ignore
|
||||
}
|
||||
String osDescription = version != null ? os + ' ' + version : os;
|
||||
attributes.put(ResourceAttributes.OS_DESCRIPTION, osDescription);
|
||||
|
||||
return Resource.create(attributes.build(), ResourceAttributes.SCHEMA_URL);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getOs(String os) {
|
||||
os = os.toLowerCase();
|
||||
if (os.startsWith("windows")) {
|
||||
return ResourceAttributes.OsTypeValues.WINDOWS;
|
||||
} else if (os.startsWith("linux")) {
|
||||
return ResourceAttributes.OsTypeValues.LINUX;
|
||||
} else if (os.startsWith("mac")) {
|
||||
return ResourceAttributes.OsTypeValues.DARWIN;
|
||||
} else if (os.startsWith("freebsd")) {
|
||||
return ResourceAttributes.OsTypeValues.FREEBSD;
|
||||
} else if (os.startsWith("netbsd")) {
|
||||
return ResourceAttributes.OsTypeValues.NETBSD;
|
||||
} else if (os.startsWith("openbsd")) {
|
||||
return ResourceAttributes.OsTypeValues.OPENBSD;
|
||||
} else if (os.startsWith("dragonflybsd")) {
|
||||
return ResourceAttributes.OsTypeValues.DRAGONFLYBSD;
|
||||
} else if (os.startsWith("hp-ux")) {
|
||||
return ResourceAttributes.OsTypeValues.HPUX;
|
||||
} else if (os.startsWith("aix")) {
|
||||
return ResourceAttributes.OsTypeValues.AIX;
|
||||
} else if (os.startsWith("solaris")) {
|
||||
return ResourceAttributes.OsTypeValues.SOLARIS;
|
||||
} else if (os.startsWith("z/os")) {
|
||||
return ResourceAttributes.OsTypeValues.Z_OS;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private OsResource() {}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
/** {@link ResourceProvider} for automatically configuring {@link OsResource}. */
|
||||
@AutoService(ResourceProvider.class)
|
||||
public final class OsResourceProvider implements ResourceProvider {
|
||||
@Override
|
||||
public Resource createResource(ConfigProperties config) {
|
||||
return OsResource.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
|
||||
|
||||
final class ProcessPid {
|
||||
|
||||
private ProcessPid() {}
|
||||
|
||||
@IgnoreJRERequirement
|
||||
static long getPid() {
|
||||
// While this is not strictly defined, almost all commonly used JVMs format this as
|
||||
// pid@hostname.
|
||||
String runtimeName = ManagementFactory.getRuntimeMXBean().getName();
|
||||
int atIndex = runtimeName.indexOf('@');
|
||||
if (atIndex >= 0) {
|
||||
String pidString = runtimeName.substring(0, atIndex);
|
||||
try {
|
||||
return Long.parseLong(pidString);
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignore parse failure.
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.common.AttributesBuilder;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import java.io.File;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
|
||||
|
||||
/** Factory of a {@link Resource} which provides information about the current running process. */
|
||||
public final class ProcessResource {
|
||||
|
||||
private static final Resource INSTANCE = buildResource();
|
||||
|
||||
/**
|
||||
* Returns a factory for a {@link Resource} which provides information about the current running
|
||||
* process.
|
||||
*/
|
||||
public static Resource get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static Resource buildResource() {
|
||||
try {
|
||||
return doBuildResource();
|
||||
} catch (LinkageError t) {
|
||||
// Will only happen on Android, where these attributes generally don't make much sense
|
||||
// anyways.
|
||||
return Resource.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@IgnoreJRERequirement
|
||||
private static Resource doBuildResource() {
|
||||
AttributesBuilder attributes = Attributes.builder();
|
||||
|
||||
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
long pid = ProcessPid.getPid();
|
||||
|
||||
if (pid >= 0) {
|
||||
attributes.put(ResourceAttributes.PROCESS_PID, pid);
|
||||
}
|
||||
|
||||
String javaHome = null;
|
||||
String osName = null;
|
||||
try {
|
||||
javaHome = System.getProperty("java.home");
|
||||
osName = System.getProperty("os.name");
|
||||
} catch (SecurityException e) {
|
||||
// Ignore
|
||||
}
|
||||
if (javaHome != null) {
|
||||
StringBuilder executablePath = new StringBuilder(javaHome);
|
||||
executablePath
|
||||
.append(File.pathSeparatorChar)
|
||||
.append("bin")
|
||||
.append(File.pathSeparatorChar)
|
||||
.append("java");
|
||||
if (osName != null && osName.toLowerCase().startsWith("windows")) {
|
||||
executablePath.append(".exe");
|
||||
}
|
||||
|
||||
attributes.put(ResourceAttributes.PROCESS_EXECUTABLE_PATH, executablePath.toString());
|
||||
|
||||
StringBuilder commandLine = new StringBuilder(executablePath);
|
||||
for (String arg : runtime.getInputArguments()) {
|
||||
commandLine.append(' ').append(arg);
|
||||
}
|
||||
attributes.put(ResourceAttributes.PROCESS_COMMAND_LINE, commandLine.toString());
|
||||
}
|
||||
|
||||
return Resource.create(attributes.build(), ResourceAttributes.SCHEMA_URL);
|
||||
}
|
||||
|
||||
private ProcessResource() {}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
/** {@link ResourceProvider} for automatically configuring {@link ProcessResource}. */
|
||||
@AutoService(ResourceProvider.class)
|
||||
public final class ProcessResourceProvider implements ResourceProvider {
|
||||
@Override
|
||||
public Resource createResource(ConfigProperties config) {
|
||||
return ProcessResource.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.PROCESS_RUNTIME_DESCRIPTION;
|
||||
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.PROCESS_RUNTIME_NAME;
|
||||
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.PROCESS_RUNTIME_VERSION;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
|
||||
/** Factory of a {@link Resource} which provides information about the Java runtime. */
|
||||
public final class ProcessRuntimeResource {
|
||||
|
||||
private static final Resource INSTANCE = buildResource();
|
||||
|
||||
/** Returns a factory for a {@link Resource} which provides information about the Java runtime. */
|
||||
public static Resource get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static Resource buildResource() {
|
||||
try {
|
||||
String name = System.getProperty("java.runtime.name");
|
||||
String version = System.getProperty("java.runtime.version");
|
||||
String description =
|
||||
System.getProperty("java.vm.vendor")
|
||||
+ " "
|
||||
+ System.getProperty("java.vm.name")
|
||||
+ " "
|
||||
+ System.getProperty("java.vm.version");
|
||||
|
||||
return Resource.create(
|
||||
Attributes.of(
|
||||
PROCESS_RUNTIME_NAME,
|
||||
name,
|
||||
PROCESS_RUNTIME_VERSION,
|
||||
version,
|
||||
PROCESS_RUNTIME_DESCRIPTION,
|
||||
description),
|
||||
ResourceAttributes.SCHEMA_URL);
|
||||
} catch (SecurityException ignored) {
|
||||
return Resource.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private ProcessRuntimeResource() {}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
|
||||
/** {@link ResourceProvider} for automatically configuring {@link ProcessRuntimeResource}. */
|
||||
@AutoService(ResourceProvider.class)
|
||||
public final class ProcessRuntimeResourceProvider implements ResourceProvider {
|
||||
@Override
|
||||
public Resource createResource(ConfigProperties config) {
|
||||
return ProcessRuntimeResource.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* {@link io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider} implementations for common
|
||||
* resource information.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
|
||||
|
||||
final class ProcessPid {
|
||||
|
||||
private ProcessPid() {}
|
||||
|
||||
@IgnoreJRERequirement
|
||||
static long getPid() {
|
||||
return ManagementFactory.getRuntimeMXBean().getPid();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import static io.opentelemetry.instrumentation.resources.ContainerResource.buildResource;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
class ContainerResourceTest {
|
||||
|
||||
@Test
|
||||
void buildResource_Invalid(@TempDir Path tempFolder) throws IOException {
|
||||
// invalid containerId (non-hex)
|
||||
Path cgroup =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup1"),
|
||||
"13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz");
|
||||
assertThat(buildResource(cgroup)).isEqualTo(Resource.empty());
|
||||
|
||||
// unrecognized format (last "-" is after last ".")
|
||||
cgroup =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup1"),
|
||||
"13:name=systemd:/podruntime/docker/kubepods/ac679f8.a8319c8cf7d38e1adf263bc08-d23zzzz");
|
||||
assertThat(buildResource(cgroup)).isEqualTo(Resource.empty());
|
||||
|
||||
// test invalid file
|
||||
cgroup = tempFolder.resolve("DoesNotExist");
|
||||
assertThat(buildResource(cgroup)).isEqualTo(Resource.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildResource_Valid(@TempDir Path tempFolder) throws IOException {
|
||||
// with suffix
|
||||
Path cgroup =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup1"),
|
||||
"13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa");
|
||||
assertThat(getContainerId(buildResource(cgroup)))
|
||||
.isEqualTo("ac679f8a8319c8cf7d38e1adf263bc08d23");
|
||||
|
||||
// with prefix and suffix
|
||||
Path cgroup2 =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup2"),
|
||||
"13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff");
|
||||
assertThat(getContainerId(buildResource(cgroup2)))
|
||||
.isEqualTo("dc679f8a8319c8cf7d38e1adf263bc08d23");
|
||||
|
||||
// just container id
|
||||
Path cgroup3 =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup3"),
|
||||
"13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356");
|
||||
assertThat(getContainerId(buildResource(cgroup3)))
|
||||
.isEqualTo("d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356");
|
||||
|
||||
// with prefix
|
||||
Path cgroup4 =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup4"),
|
||||
"//\n"
|
||||
+ "1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23"
|
||||
+ "2:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23"
|
||||
+ "3:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23");
|
||||
assertThat(getContainerId(buildResource(cgroup4)))
|
||||
.isEqualTo("dc579f8a8319c8cf7d38e1adf263bc08d23");
|
||||
|
||||
// with two dashes in prefix
|
||||
Path cgroup5 =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup5"),
|
||||
"11:perf_event:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod4415fd05_2c0f_4533_909b_f2180dca8d7c.slice/cri-containerd-713a77a26fe2a38ebebd5709604a048c3d380db1eb16aa43aca0b2499e54733c.scope");
|
||||
assertThat(getContainerId(buildResource(cgroup5)))
|
||||
.isEqualTo("713a77a26fe2a38ebebd5709604a048c3d380db1eb16aa43aca0b2499e54733c");
|
||||
|
||||
// with colon, env: k8s v1.24.0, the cgroupDriver by systemd(default), and container is
|
||||
// cri-containerd v1.6.8
|
||||
Path cgroup6 =
|
||||
createCgroup(
|
||||
tempFolder.resolve("cgroup6"),
|
||||
"11:devices:/system.slice/containerd.service/kubepods-pod87a18a64_b74a_454a_b10b_a4a36059d0a3.slice:cri-containerd:05c48c82caff3be3d7f1e896981dd410e81487538936914f32b624d168de9db0");
|
||||
assertThat(getContainerId(buildResource(cgroup6)))
|
||||
.isEqualTo("05c48c82caff3be3d7f1e896981dd410e81487538936914f32b624d168de9db0");
|
||||
}
|
||||
|
||||
private static String getContainerId(Resource resource) {
|
||||
return resource.getAttribute(ResourceAttributes.CONTAINER_ID);
|
||||
}
|
||||
|
||||
private static Path createCgroup(Path path, String line) throws IOException {
|
||||
return Files.write(path, line.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.Attributes;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.condition.EnabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
class HostResourceTest {
|
||||
@Test
|
||||
void shouldCreateRuntimeAttributes() {
|
||||
// when
|
||||
Resource resource = HostResource.buildResource();
|
||||
Attributes attributes = resource.getAttributes();
|
||||
|
||||
// then
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(attributes.get(ResourceAttributes.HOST_NAME)).isNotBlank();
|
||||
assertThat(attributes.get(ResourceAttributes.HOST_ARCH)).isNotBlank();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@ExtendWith(SecurityManagerExtension.class)
|
||||
@EnabledOnJre(
|
||||
value = {JRE.JAVA_8, JRE.JAVA_11, JRE.JAVA_16},
|
||||
disabledReason = "Java 17 deprecates security manager for removal")
|
||||
static class SecurityManagerEnabled {
|
||||
@Test
|
||||
void empty() {
|
||||
Attributes attributes = HostResource.buildResource().getAttributes();
|
||||
assertThat(attributes.asMap()).containsOnlyKeys(ResourceAttributes.HOST_NAME);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.condition.EnabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junitpioneer.jupiter.SetSystemProperty;
|
||||
|
||||
class OsResourceTest {
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "Linux 4.11")
|
||||
void linux() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.LINUX);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "MacOS X 11")
|
||||
void macos() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.DARWIN);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "Windows 10")
|
||||
void windows() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.WINDOWS);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "FreeBSD 10")
|
||||
void freebsd() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.FREEBSD);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "NetBSD 10")
|
||||
void netbsd() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.NETBSD);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "OpenBSD 10")
|
||||
void openbsd() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.OPENBSD);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "DragonFlyBSD 10")
|
||||
void dragonflybsd() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.DRAGONFLYBSD);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "HP-UX 10")
|
||||
void hpux() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.HPUX);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "AIX 10")
|
||||
void aix() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.AIX);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "Solaris 10")
|
||||
void solaris() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.SOLARIS);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "Z/OS 10")
|
||||
void zos() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE))
|
||||
.isEqualTo(ResourceAttributes.OsTypeValues.Z_OS);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "RagOS 10")
|
||||
void unknown() {
|
||||
Resource resource = OsResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE)).isNull();
|
||||
assertThat(resource.getAttribute(ResourceAttributes.OS_DESCRIPTION)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@ExtendWith(SecurityManagerExtension.class)
|
||||
@EnabledOnJre(
|
||||
value = {JRE.JAVA_8, JRE.JAVA_11, JRE.JAVA_16},
|
||||
disabledReason = "Java 17 deprecates security manager for removal")
|
||||
static class SecurityManagerEnabled {
|
||||
@Test
|
||||
void empty() {
|
||||
assertThat(OsResource.buildResource()).isEqualTo(Resource.empty());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.Attributes;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.condition.EnabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junitpioneer.jupiter.SetSystemProperty;
|
||||
|
||||
class ProcessResourceTest {
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "Linux 4.12")
|
||||
void notWindows() {
|
||||
Resource resource = ProcessResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
Attributes attributes = resource.getAttributes();
|
||||
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_PID)).isGreaterThan(1);
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_EXECUTABLE_PATH))
|
||||
.contains("java")
|
||||
.doesNotEndWith(".exe");
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_COMMAND_LINE))
|
||||
.contains(attributes.get(ResourceAttributes.PROCESS_EXECUTABLE_PATH));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetSystemProperty(key = "os.name", value = "Windows 10")
|
||||
void windows() {
|
||||
Resource resource = ProcessResource.buildResource();
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
Attributes attributes = resource.getAttributes();
|
||||
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_PID)).isGreaterThan(1);
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_EXECUTABLE_PATH))
|
||||
.contains("java")
|
||||
.endsWith(".exe");
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_COMMAND_LINE))
|
||||
.contains(attributes.get(ResourceAttributes.PROCESS_EXECUTABLE_PATH));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@ExtendWith(SecurityManagerExtension.class)
|
||||
@EnabledOnJre(
|
||||
value = {JRE.JAVA_8, JRE.JAVA_11, JRE.JAVA_16},
|
||||
disabledReason = "Java 17 deprecates security manager for removal")
|
||||
static class SecurityManagerEnabled {
|
||||
@Test
|
||||
void empty() {
|
||||
Attributes attributes = ProcessResource.buildResource().getAttributes();
|
||||
assertThat(attributes.asMap()).containsOnlyKeys(ResourceAttributes.PROCESS_PID);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.Attributes;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.condition.EnabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
class ProcessRuntimeResourceTest {
|
||||
@Test
|
||||
void shouldCreateRuntimeAttributes() {
|
||||
// when
|
||||
Resource resource = ProcessRuntimeResource.buildResource();
|
||||
Attributes attributes = resource.getAttributes();
|
||||
|
||||
// then
|
||||
assertThat(resource.getSchemaUrl()).isEqualTo(ResourceAttributes.SCHEMA_URL);
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_RUNTIME_NAME)).isNotBlank();
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_RUNTIME_VERSION)).isNotBlank();
|
||||
assertThat(attributes.get(ResourceAttributes.PROCESS_RUNTIME_DESCRIPTION)).isNotBlank();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@ExtendWith(SecurityManagerExtension.class)
|
||||
@EnabledOnJre(
|
||||
value = {JRE.JAVA_8, JRE.JAVA_11, JRE.JAVA_16},
|
||||
disabledReason = "Java 17 deprecates security manager for removal")
|
||||
static class SecurityManagerEnabled {
|
||||
@Test
|
||||
void empty() {
|
||||
assertThat(ProcessRuntimeResource.buildResource()).isEqualTo(Resource.empty());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.resources;
|
||||
|
||||
import java.security.Permission;
|
||||
import java.util.HashSet;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.Set;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
final class SecurityManagerExtension implements BeforeEachCallback, AfterEachCallback {
|
||||
|
||||
private static final ExtensionContext.Namespace NAMESPACE =
|
||||
ExtensionContext.Namespace.create(SecurityManagerExtension.class);
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
context.getStore(NAMESPACE).put(SecurityManager.class, System.getSecurityManager());
|
||||
System.setSecurityManager(BlockPropertiesAccess.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) {
|
||||
System.setSecurityManager(
|
||||
(SecurityManager) context.getStore(NAMESPACE).get(SecurityManager.class));
|
||||
}
|
||||
|
||||
private static class BlockPropertiesAccess extends SecurityManager {
|
||||
|
||||
private static final BlockPropertiesAccess INSTANCE = new BlockPropertiesAccess();
|
||||
|
||||
private static final Set<String> BLOCKED_PROPERTIES = new HashSet<>();
|
||||
|
||||
static {
|
||||
BLOCKED_PROPERTIES.add("java.home");
|
||||
BLOCKED_PROPERTIES.add("java.runtime.home");
|
||||
BLOCKED_PROPERTIES.add("java.runtime.version");
|
||||
BLOCKED_PROPERTIES.add("java.vm.name");
|
||||
BLOCKED_PROPERTIES.add("java.vm.vendor");
|
||||
BLOCKED_PROPERTIES.add("java.vm.version");
|
||||
BLOCKED_PROPERTIES.add("os.arch");
|
||||
BLOCKED_PROPERTIES.add("os.name");
|
||||
BLOCKED_PROPERTIES.add("os.version");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
if (perm instanceof PropertyPermission) {
|
||||
if (BLOCKED_PROPERTIES.contains(perm.getName())) {
|
||||
throw new SecurityException("Property access not allowed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -395,6 +395,7 @@ include(":instrumentation:redisson:redisson-3.0:javaagent")
|
|||
include(":instrumentation:redisson:redisson-3.17:javaagent")
|
||||
include(":instrumentation:redisson:redisson-common:javaagent")
|
||||
include(":instrumentation:redisson:redisson-common:testing")
|
||||
include(":instrumentation:resources:library")
|
||||
include(":instrumentation:restlet:restlet-1.0:javaagent")
|
||||
include(":instrumentation:restlet:restlet-1.0:library")
|
||||
include(":instrumentation:restlet:restlet-1.0:testing")
|
||||
|
|
Loading…
Reference in New Issue