Implement OS and some process resource attributes. (#1555)

* Implement OS and some process resource attributes.

* Update link in javadoc

* pid, docs

* Don't support Android
This commit is contained in:
Anuraag Agrawal 2020-08-21 01:42:30 +09:00 committed by GitHub
parent ad9f7d4cf5
commit cb50978106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 366 additions and 1 deletions

View File

@ -20,11 +20,41 @@ package io.opentelemetry.sdk.resources;
* Provides constants for resource semantic conventions defined by the OpenTelemetry specification. * Provides constants for resource semantic conventions defined by the OpenTelemetry specification.
* *
* @see <a * @see <a
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-resource-semantic-conventions.md">Resource * href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/README.md">Resource
* Conventions</a> * Conventions</a>
*/ */
public class ResourceConstants { public class ResourceConstants {
/** The operating system type, such as {@code "WINDOWS"}, {@code "DARWIN"}, {@code "LINUX"}. */
public static final String OS_NAME = "os.name";
/**
* Human readable information about the OS version, e.g. {@code "Microsoft Windows [Version
* 10.0.18363.778]"}, {@code "Ubuntu 18.04.1 LTS"}.
*/
public static final String OS_DESCRIPTION = "os.description";
/** Process identifier (PID). */
public static final String PROCESS_PID = "process.pid";
/** The name of the process executable. */
public static final String PROCESS_EXECUTABLE_NAME = "process.executable.name";
/** The full path to the process executable. */
public static final String PROCESS_EXECUTABLE_PATH = "process.executable.path";
/** The command used to launch the process (i.e. the command name). */
public static final String PROCESS_COMMAND = "process.command";
/**
* The full command used to launch the process. The value can be either a list of strings
* representing the ordered list of arguments, or a single string representing the full command.
*/
public static final String PROCESS_COMMAND_LINE = "process.command_line";
/** The username of the user that owns the process. */
public static final String PROCESS_OWNER = "process.owner";
/** /**
* Logical name of the service. MUST be the same for all instances of horizontally scaled * Logical name of the service. MUST be the same for all instances of horizontally scaled
* services. * services.

View File

@ -0,0 +1,32 @@
# 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
### Operating System
Provider: `io.opentelemetry.sdk.extensions.resources.OsResource`
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/os.md
Implemented attributes:
- `os.name`
- `os.description`
### Process
Implementation: `io.opentelemetry.sdk.extensions.resources.ProcessResource`
Specification: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/process.md
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)
## 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.

View File

@ -0,0 +1,19 @@
plugins {
id "java"
id "maven-publish"
id "ru.vyarus.animalsniffer"
}
description = 'OpenTelemetry SDK Resource Providers'
ext.moduleName = "io.opentelemetry.sdk.extension.resources"
dependencies {
api project(':opentelemetry-sdk-common')
testImplementation libraries.junit_pioneer
signature "org.codehaus.mojo.signature:java17:1.0@signature"
// TODO(anuraaga): Use reflection for RuntimeMXBean which is not included in Android.
// signature "net.sf.androidscents.signature:android-api-level-24:7.0_r2@signature"
}

View File

@ -0,0 +1,88 @@
/*
* Copyright 2020, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.sdk.extensions.resources;
import io.opentelemetry.common.Attributes;
import io.opentelemetry.sdk.resources.ResourceConstants;
import io.opentelemetry.sdk.resources.ResourceProvider;
import javax.annotation.Nullable;
/** {@link ResourceProvider} which provides information about the current operating system. */
public class OsResource extends ResourceProvider {
@Override
protected Attributes getAttributes() {
final String os;
try {
os = System.getProperty("os.name");
} catch (SecurityException t) {
// Security manager enabled, can't provide much os information.
return Attributes.empty();
}
if (os == null) {
return Attributes.empty();
}
Attributes.Builder attributes = Attributes.newBuilder();
String osName = getOs(os);
if (osName != null) {
attributes.setAttribute(ResourceConstants.OS_NAME, osName);
}
String version = null;
try {
version = System.getProperty("os.version");
} catch (SecurityException e) {
// Ignore
}
String osDescription = version != null ? os + ' ' + version : os;
attributes.setAttribute(ResourceConstants.OS_DESCRIPTION, osDescription);
return attributes.build();
}
@Nullable
private static String getOs(String os) {
os = os.toLowerCase();
if (os.startsWith("windows")) {
return "WINDOWS";
} else if (os.startsWith("linux")) {
return "LINUX";
} else if (os.startsWith("mac")) {
return "DARWIN";
} else if (os.startsWith("freebsd")) {
return "FREEBSD";
} else if (os.startsWith("netbsd")) {
return "NETBSD";
} else if (os.startsWith("openbsd")) {
return "OPENBSD";
} else if (os.startsWith("dragonflybsd")) {
return "DRAGONFLYBSD";
} else if (os.startsWith("hp-ux")) {
return "HPUX";
} else if (os.startsWith("aix")) {
return "AIX";
} else if (os.startsWith("solaris")) {
return "SOLARIS";
} else if (os.startsWith("z/os")) {
return "ZOS";
}
return null;
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright 2020, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.sdk.extensions.resources;
import io.opentelemetry.common.Attributes;
import io.opentelemetry.sdk.resources.ResourceConstants;
import io.opentelemetry.sdk.resources.ResourceProvider;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
/** {@link ResourceProvider} which provides information about the current running process. */
public class ProcessResource extends ResourceProvider {
@Override
protected Attributes getAttributes() {
Attributes.Builder attributes = Attributes.newBuilder();
// TODO(anuraaga): Use reflection to get more stable values on Java 9+
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
long pid = -1;
// 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 {
pid = Long.parseLong(pidString);
} catch (NumberFormatException ignored) {
// Ignore parse failure.
}
}
if (pid >= 0) {
attributes.setAttribute(ResourceConstants.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.setAttribute(ResourceConstants.PROCESS_EXECUTABLE_PATH, executablePath.toString());
StringBuilder commandLine = new StringBuilder(executablePath);
for (String arg : runtime.getInputArguments()) {
commandLine.append(' ').append(arg);
}
attributes.setAttribute(ResourceConstants.PROCESS_COMMAND_LINE, commandLine.toString());
}
return attributes.build();
}
}

View File

@ -0,0 +1,2 @@
io.opentelemetry.sdk.extensions.resources.OsResource
io.opentelemetry.sdk.extensions.resources.ProcessResource

View File

@ -0,0 +1,62 @@
/*
* Copyright 2020, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.sdk.extensions.resources;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import io.opentelemetry.common.Attributes;
import io.opentelemetry.common.ReadableAttributes;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.resources.ResourceConstants;
import org.junit.jupiter.api.Test;
class OsResourceTest {
private static final OsResource RESOURCE = new OsResource();
@Test
void linux() {
assumeThat(System.getProperty("os.name").toLowerCase()).startsWith("linux");
Attributes attributes = RESOURCE.getAttributes();
assertThat(attributes.get(ResourceConstants.OS_NAME).getStringValue()).isEqualTo("LINUX");
assertThat(attributes.get(ResourceConstants.OS_DESCRIPTION).getStringValue()).isNotEmpty();
}
@Test
void macos() {
assumeThat(System.getProperty("os.name").toLowerCase()).startsWith("mac");
Attributes attributes = RESOURCE.getAttributes();
assertThat(attributes.get(ResourceConstants.OS_NAME).getStringValue()).isEqualTo("DARWIN");
assertThat(attributes.get(ResourceConstants.OS_DESCRIPTION).getStringValue()).isNotEmpty();
}
@Test
void windows() {
assumeThat(System.getProperty("os.name").toLowerCase()).startsWith("windows");
Attributes attributes = RESOURCE.getAttributes();
assertThat(attributes.get(ResourceConstants.OS_NAME).getStringValue()).isEqualTo("WINDOWS");
assertThat(attributes.get(ResourceConstants.OS_DESCRIPTION).getStringValue()).isNotEmpty();
}
@Test
void inDefault() {
ReadableAttributes attributes = Resource.getDefault().getAttributes();
assertThat(attributes.get(ResourceConstants.OS_NAME)).isNotNull();
assertThat(attributes.get(ResourceConstants.OS_DESCRIPTION)).isNotNull();
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 2020, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.sdk.extensions.resources;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.common.Attributes;
import io.opentelemetry.common.ReadableAttributes;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.resources.ResourceConstants;
import org.junit.jupiter.api.Test;
class ProcessResourceTest {
private static final ProcessResource RESOURCE = new ProcessResource();
@Test
void normal() {
Attributes attributes = RESOURCE.getAttributes();
assertThat(attributes.get(ResourceConstants.PROCESS_PID).getLongValue()).isGreaterThan(1);
assertThat(attributes.get(ResourceConstants.PROCESS_EXECUTABLE_PATH).getStringValue())
.contains("java");
assertThat(attributes.get(ResourceConstants.PROCESS_COMMAND_LINE).getStringValue())
.contains(attributes.get(ResourceConstants.PROCESS_EXECUTABLE_PATH).getStringValue());
}
@Test
void inDefault() {
ReadableAttributes attributes = Resource.getDefault().getAttributes();
assertThat(attributes.get(ResourceConstants.PROCESS_PID)).isNotNull();
assertThat(attributes.get(ResourceConstants.PROCESS_EXECUTABLE_PATH)).isNotNull();
assertThat(attributes.get(ResourceConstants.PROCESS_COMMAND_LINE)).isNotNull();
}
}

View File

@ -43,6 +43,7 @@ include ":opentelemetry-all",
":opentelemetry-sdk-extension-auto-config", ":opentelemetry-sdk-extension-auto-config",
":opentelemetry-sdk-extension-aws-v1-support", ":opentelemetry-sdk-extension-aws-v1-support",
":opentelemetry-sdk-extension-otproto", ":opentelemetry-sdk-extension-otproto",
":opentelemetry-sdk-extension-resources",
":opentelemetry-sdk-extension-testbed", ":opentelemetry-sdk-extension-testbed",
":opentelemetry-sdk-extension-jaeger-remote-sampler", ":opentelemetry-sdk-extension-jaeger-remote-sampler",
":opentelemetry-sdk-extension-zpages", ":opentelemetry-sdk-extension-zpages",