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:
parent
ad9f7d4cf5
commit
cb50978106
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
io.opentelemetry.sdk.extensions.resources.OsResource
|
||||||
|
io.opentelemetry.sdk.extensions.resources.ProcessResource
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue