Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve exception handling and documentation of runtime attachment #388

Merged
merged 1 commit into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion runtime-attach/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ If you can't update the JVM arguments to attach the [OpenTelemetry Java agent](h

The `io.opentelemetry.contrib.attach.RuntimeAttach` class has an `attachJavaagentToCurrentJVM` method allowing to trigger the attachment of the OTel agent for Java.

The attachment will not be initiated in the following cases:
The attachment will _not_ be initiated in the following cases:
* The `otel.javaagent.enabled` property is set to `false`
* The `OTEL_JAVAAGENT_ENABLED` environment variable is set to `false`
* The attachment is not requested from the _main_ thread
* The attachment is not requested from the `public static void main(String[] args)` method
* The agent is already attached
* The application is running on a JRE (a JDK is necessary)
* The application is running on a read-only file system
Comment on lines +13 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


_The attachment must be requested at the beginning of the `public static void main(String[] args)` method._ We give below an example for Spring Boot applications:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ private static Path createTempDir() {
try {
tempDir = Files.createTempDirectory("otel-agent");
} catch (IOException e) {
throw new IllegalStateException("Runtime attachment can't create temp directory", e);
throw new RuntimeAttachException(
"Runtime attachment can't create a temp directory. Are you using a read-only file system?",
e);
}
return tempDir;
}
Expand All @@ -50,12 +52,12 @@ private Path createTempAgentJarFileIn(Path tempDir) {
try (InputStream jarAsInputStream =
AgentFileProvider.class.getResourceAsStream(this.agentJarResourceName)) {
if (jarAsInputStream == null) {
throw new IllegalStateException(this.agentJarResourceName + " resource can't be found");
throw new RuntimeAttachException(this.agentJarResourceName + " resource can't be found");
}
Files.copy(jarAsInputStream, agentJarPath);
} catch (IOException e) {
throw new IllegalStateException(
"Runtime attachment can't create agent jar file in temp directory", e);
throw new RuntimeAttachException(
"Runtime attachment can't create an agent jar file in temp directory", e);
}
return agentJarPath;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ public void attachJavaagentToCurrentJVM() {
AgentFileProvider agentFileProvider = new AgentFileProvider(agentJarResourceName);

File javaagentFile = agentFileProvider.getAgentFile();
ByteBuddyAgent.attach(javaagentFile, getPid());

try {
ByteBuddyAgent.attach(javaagentFile, getPid());
} catch (RuntimeException e) {
handleByteBuddyException(e);
}

if (!agentIsAttached()) {
printError("Agent was not attached. An unexpected issue has happened.");
Expand Down Expand Up @@ -88,6 +93,24 @@ private static boolean agentIsDisabledWithEnvVar() {
return "false".equals(agentEnabledEnvVarValue);
}

private static void handleByteBuddyException(RuntimeException exception) {
handleNoAgentProvider(exception);
throw new RuntimeAttachException(
"A problem has occurred during the runtime attachment of the Java agent.", exception);
}

private static void handleNoAgentProvider(RuntimeException exception) {
if (exception instanceof IllegalStateException) {
String message = exception.getMessage();
if (message != null
&& message.contains(
"No compatible attachment provider is available")) { // ByteBuddy message
throw new RuntimeAttachException(
"Runtime attachment has failed. Are you using a JRE (not a JDK)?", exception);
}
}
}

private static boolean agentIsAttached() {
try {
Class.forName("io.opentelemetry.javaagent.OpenTelemetryAgent", false, null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.attach;

/**
* Exception that gets thrown if a problem occurs during the attachment of the OpenTelemetry agent.
*/
public final class RuntimeAttachException extends RuntimeException {

private static final long serialVersionUID = 1982913847038355735L;

private RuntimeAttachException() {}

RuntimeAttachException(String message) {
super(message);
}

RuntimeAttachException(String message, Throwable cause) {
super(message, cause);
}
}