Skip to content

Runtime attachment additions#354

Merged
trask merged 26 commits into
open-telemetry:mainfrom
jeanbisutti:rt-attachment-additions
Jun 17, 2022
Merged

Runtime attachment additions#354
trask merged 26 commits into
open-telemetry:mainfrom
jeanbisutti:rt-attachment-additions

Conversation

@jeanbisutti

@jeanbisutti jeanbisutti commented Jun 13, 2022

Copy link
Copy Markdown
Member

Description:

Runtime attachment additions

  • Add tests
  • Add log when agent is disabled with otel.javaagent.enabled property
  • Add log when agent is disabled with OTEL_JAVAAGENT_ENABLED environment variable
  • Do not try to attach if agent is already attached
  • Do not try to attach if attachment is requested from the main thread
  • Do not try to attach if attachment is requested from the main method
  • Add log if an unexpected issue has happened during attachment
  • Add javadoc
  • Add information to the Readme

@jeanbisutti jeanbisutti requested a review from a team June 13, 2022 13:21
@github-actions github-actions Bot requested review from iNikem and trask June 13, 2022 13:21
@jeanbisutti jeanbisutti marked this pull request as draft June 13, 2022 13:22
@jeanbisutti jeanbisutti marked this pull request as ready for review June 13, 2022 14:17

@trask trask left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thx!

Comment thread runtime-attach/build.gradle.kts Outdated
Comment thread runtime-attach/build.gradle.kts Outdated
Comment thread runtime-attach/README.md Outdated
Comment thread runtime-attach/README.md Outdated
Comment thread runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java Outdated
Comment thread runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java Outdated
Comment thread runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java Outdated
Comment thread runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java Outdated
Comment on lines +43 to +46
if (agentIsDisabledWithEnvVar()) {
LOGGER.warning("Agent was disabled with " + AGENT_ENABLED_ENV_VAR + " environment variable.");
return false;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we need to check the env var and system property? it may be ok for the runtime attach component to try to attach and the javaagent will disable itself if these are set

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I understand your point of view @trask . It could make sense. I would prefer not to try to attach, in such a case, to stop the things sooner. It's the current behavior. What do you think @iNikem?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ah, I hadn't noticed this was the current behavior, let's keep it then, thx

Comment thread runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java Outdated
jeanbisutti and others added 12 commits June 14, 2022 10:27
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
…untimeAttach.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
…untimeAttach.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
…untimeAttach.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Comment thread runtime-attach/README.md
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what do you think about adding one more check, that the call stack only has main in it, i.e. that it was really called directly from the initial main method?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think it's a good idea. I will do it. I could even check that the first element of the call stack contains main.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Implemented. The new code be tested with the following class:

public class MainClass {

  public static void main(String[] args) {
    System.out.println("isMainMethod = " + isMainMethod());
  }

  static boolean isMainMethod() {
    StackTraceElement bottomOfStack = findBottomOfStack(Thread.currentThread());
    String methodName = bottomOfStack.getMethodName();
    return "main".equals(methodName);
  }

  private static StackTraceElement findBottomOfStack(Thread thread) {
    StackTraceElement[] stackTrace = thread.getStackTrace();
    return  stackTrace[stackTrace.length - 1];
  }
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think typically the main thread will always be rooted at the main() method(?), I was thinking of a more restrictive chck that attach() was called directly from main()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm going to merge this for the 1.15.0 release, and we can discuss / follow-up on this point later

Comment thread runtime-attach/build.gradle.kts Outdated
// Used by byte-buddy but not brought in as a transitive dependency.
compileOnly("com.google.code.findbugs:annotations")

testImplementation("io.opentelemetry.javaagent:opentelemetry-javaagent:1.14.0")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can you move this version to dependency management section so we don't miss updating it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done

Comment thread runtime-attach/src/main/java/io/opentelemetry/contrib/attach/RuntimeAttach.java Outdated
@trask trask merged commit 658daad into open-telemetry:main Jun 17, 2022
@trask

trask commented Jun 17, 2022

Copy link
Copy Markdown
Member

thx @jeanbisutti!

/** This class allows you to attach the OpenTelemetry Java agent at runtime. */
public final class RuntimeAttach {

private static final Logger logger = Logger.getLogger(RuntimeAttach.class.getName());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I might be a little bit late here, but... 😄

Should we use JUL here? This class is supposed to be the very first thing called in main, right? JUL won't be set up this early, and these calls certainly won't be redirected to agent's PatchLogger. Wouldn't it be safer to use stderr here?

@jeanbisutti jeanbisutti Jun 20, 2022

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Should we use JUL here? This class is supposed to be the very first thing called in main, right? JUL won't be set up this early, and these calls certainly won't be redirected to agent's PatchLogger. Wouldn't it be safer to use stderr here?

Probably!

What about the logging added by a user? For example, if a user has a Spring Boot application and uses a logging API (jul, Log4j, logback, ...) in the class annotated with @SpringBootApplication, it would also have a problem? The problem would only be about JUL?

...
import java.util.logging.Logger;
...
private static final Logger logger = Logger.getLogger(SpringBootApp.class.getName());
...
@SpringBootApplication
public class SpringBootApp {
    public static void main(String[] args) {
        RuntimeAttach.attachJavaagentToCurrentJVM();
        SpringApplication.run(SpringBootApp.class, args);
    }
}

The user should initialize the logger after the runtime attachment?

...
import java.util.logging.Logger;
...
private static Logger logger;
...
@SpringBootApplication
public class SpringBootApp {
    public static void main(String[] args) {
        RuntimeAttach.attachJavaagentToCurrentJVM();
        logger = Logger.getLogger(SpringBootApp.class.getName());
        SpringApplication.run(SpringBootApp.class, args);
    }
}

@mateuszrzeszutek @trask What do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thx, I agree with changing the logging in the runtime attach code itself to use stderr so that we don't trigger loading of j.u.l too early, e.g. in case the user is using jboss-logging (maybe https://www.wildfly.org/news/2020/06/18/Bootable-jar-Wildfly-20/?)

I don't think we need to add any restrictions on the user's logging setup. If whatever they were doing before they added the "runtime attach snippet" worked, it should still work after they add the snippet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants