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

add wildfly.yaml to JMX scraper #1531

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

SylvainJuge
Copy link
Contributor

Description:

  • add wildfly support for jmx scraper with dedicated YAML configuration
  • adds wildfly tests using jboss-client.jar for using HTTP management API
  • fixes support for login/pwd authentication
  • adds a test webapp needed to test wildfly session metrics
  • moves existing test app to dedicated module for simplicity (and making it similar to test webapp)
  • fixes use of plural form in units in wildfly.groovy to fit the stable convention for metric units.

Part of #1362

Notes:

In the original groovy implementation session metrics are not tested, this requires deploying and application to the container, this is not properly tested in the YAML implementation.

In the original groovy implementation the gatherer was run directly from the same docker container probably for simplicity as jboss-client.jar is directly available.
When using two containers, the jar needs to be copied from wildfly container to scraper container and it complicates authentication: login/pwd can be skipped if both processes run on the same host and can access the same filesystem.
Testing here is done using two distinct containers as this setup is a bit more complex and thus likely to fail (doing so here helped me find that we did not handle it properly).

@SylvainJuge SylvainJuge marked this pull request as ready for review November 6, 2024 16:29
@SylvainJuge SylvainJuge requested a review from a team as a code owner November 6, 2024 16:29
@@ -25,11 +25,12 @@ protected GenericContainer<?> createTargetContainer(int jmxPort) {
builder -> builder.from("apache/activemq-classic:5.18.6").build()))
.withEnv("JAVA_TOOL_OPTIONS", genericJmxJvmArguments(jmxPort))
.withStartupTimeout(Duration.ofMinutes(2))
.waitingFor(Wait.forListeningPort());
.waitingFor(Wait.forLogMessage(".*Apache ActiveMQ.*started.*", 1));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[for reviewer] waiting for open port seems to sometimes not be accurate enough to detect proper startup, which makes the scraper container start when the JMX port is not yet available. Waiting on log message is an attempt to make this a bit less flaky (time will tell if that's a good idea or not here).

Copy link
Contributor

@robsunday robsunday Nov 7, 2024

Choose a reason for hiding this comment

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

Wait.forListeningPort() requires withExposedPorts(jmxPort) to be called to work properly. I think Tomcat test works by a chance. I added withExposedPorts to all tests using forListeningPort on my branch, but you can add it in your PR instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While this sounds brittle, I think it's slightly better to wait for the target application to be properly started (here we use the log message as a proxy), because while the JMX port might be open early, the MBeans are likely not yet published so while we can connect to it the MBeans that we are trying to access are likely not yet published.

Otherwise do you suggest to add to every container something like this for Tomcat:

  protected GenericContainer<?> createTargetContainer(int jmxPort) {
    return new GenericContainer<>(
        new ImageFromDockerfile()
        // ...
        .withStartupTimeout(Duration.ofMinutes(2))
        .withExposedPorts(8080, jmxPort)
        .waitingFor(Wait.forListeningPorts(8080, jmxPort));
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed today I've implemented it for all other containers in 3ab2f28.


- command line arguments: `java -jar scraper.jar --config otel.jmx.target.system=...`
- system properties `java -jar scraper.jar`
- java properties file: `java -jar config.properties`
Copy link
Contributor

Choose a reason for hiding this comment

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

I think for now it could be:

  • command line arguments: java -Dotel.jmx.service.url=service:jmx:rmi:///jndi/rmi://tomcat:9010/jmxrmi -Dotel.jmx.target.system=tomcat -jar scraper.jar
  • java properties file: java -jar scraper.jar -config config.properties
  • config provided from stdin: java -jar scraper.jar -config - then type: otel.jmx.target.system=tomcat and: otel.jmx.service.url=service:jmx:rmi:///jndi/rmi://tomcat:9010/jmxrmi

@@ -25,11 +25,13 @@ protected GenericContainer<?> createTargetContainer(int jmxPort) {
builder -> builder.from("apache/activemq-classic:5.18.6").build()))
.withEnv("JAVA_TOOL_OPTIONS", genericJmxJvmArguments(jmxPort))
.withStartupTimeout(Duration.ofMinutes(2))
.waitingFor(Wait.forListeningPort());
.withExposedPorts(61616, jmxPort)
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be more maintainable if some named constant is used instead of just 61616. The same applies to other tests below

public class WildflyIntegrationTest extends TargetSystemIntegrationTest {

@SuppressWarnings("NonFinalStaticField")
private static Path tempJbossClient = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we do not need static and SuppressWarnings here? JUnit is managing lifecycle of the test suite. It is creating single instance of the test suite anyway

private static Path tempJbossClient = null;

@AfterAll
public static void cleanup() throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

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

I see here some room for improvement for our integration tests. Containers are created in @Test in base class. Also temp file is created there, while it is removed in @AfterAll.
In theory we could add more @Test functions that creates more containers, more temp files, etc., so it would be safer to do cleanup in @AfterEach.
As alternative we can consider moving container creation to @BeforeAll
For me current implementation is somehow risky.

mapping:
sessionsCreated:
metric: count
type: counter
Copy link
Contributor

Choose a reason for hiding this comment

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

minor - could be defined as a common type

desc: The number of requests that have resulted in a 5xx response.
bytesSent:
metric: network.io
unit: "by"
Copy link
Contributor

@robsunday robsunday Nov 13, 2024

Choose a reason for hiding this comment

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

"By" seems to be unit recommended by semconv. Can we just use "By" here?

type: counter
prefix: wildfly.jdbc.
mapping:
ActiveCount:
Copy link
Contributor

Choose a reason for hiding this comment

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

ActiveCount and IdleCount could use YAML references since they share a lot. The same applies to few props in the bean below. What do you think about it?

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.

3 participants