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

Runtime attachment additions #354

Merged
merged 26 commits into from
Jun 17, 2022

Conversation

jeanbisutti
Copy link
Member

@jeanbisutti jeanbisutti commented Jun 13, 2022

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
Copy link
Member

@trask trask left a comment

Choose a reason for hiding this comment

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

thx!

runtime-attach/build.gradle.kts Outdated Show resolved Hide resolved
runtime-attach/build.gradle.kts Outdated Show resolved Hide resolved
runtime-attach/README.md Outdated Show resolved Hide resolved
runtime-attach/README.md Outdated Show resolved Hide resolved
Comment on lines 43 to 46
if (agentIsDisabledWithEnvVar()) {
LOGGER.warning("Agent was disabled with " + AGENT_ENABLED_ENV_VAR + " environment variable.");
return false;
}
Copy link
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
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
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

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
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
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
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
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
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

@@ -11,4 +11,15 @@ dependencies {

// 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
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
Member Author

Choose a reason for hiding this comment

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

Done

@trask trask merged commit 658daad into open-telemetry:main Jun 17, 2022
@trask
Copy link
Member

trask commented Jun 17, 2022

thx @jeanbisutti!

public final class RuntimeAttach {

private static final Logger logger = Logger.getLogger(RuntimeAttach.class.getName());
Copy link
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?

Copy link
Member Author

@jeanbisutti jeanbisutti Jun 20, 2022

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
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