Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6ebcf90
move wildfly yaml
SylvainJuge Jul 9, 2025
5bd74ca
simplify a bit test class names
SylvainJuge Jul 9, 2025
965e541
add test webapp
SylvainJuge Jul 9, 2025
f57d108
use local test app in tomcat test
SylvainJuge Jul 9, 2025
989e04a
add test infra for wildfly
SylvainJuge Jul 9, 2025
ebf0788
session metrics
SylvainJuge Jul 9, 2025
81a82c1
request and error metrics
SylvainJuge Jul 9, 2025
9727eb2
add network io
SylvainJuge Jul 9, 2025
d347336
cleanup and update doc
SylvainJuge Jul 9, 2025
c5f4e0e
add a few comments
SylvainJuge Jul 9, 2025
397ee85
add client db pool metrics
SylvainJuge Jul 9, 2025
3764a0e
remove from deprecated test
SylvainJuge Jul 9, 2025
c161fb5
./gradlew spotlessApply
otelbot[bot] Jul 9, 2025
f916b4b
use servlet annotations for ja{vax,karta} compat
SylvainJuge Jul 10, 2025
6b75e06
start test with wildfly 9.x
SylvainJuge Jul 10, 2025
b7ba13d
./gradlew spotlessApply
otelbot[bot] Jul 10, 2025
495eca5
add transaction/rollback metrics
SylvainJuge Jul 10, 2025
c502b79
Merge branch 'jmx-wildfly' of github.com:SylvainJuge/opentelemetry-ja…
SylvainJuge Jul 10, 2025
998cef7
rework a bit transactions
SylvainJuge Jul 10, 2025
05974a0
relax assertion for older versions
SylvainJuge Jul 10, 2025
4ee825a
fix commited transactions
SylvainJuge Jul 10, 2025
a30e91d
clarify description
SylvainJuge Jul 10, 2025
d024a03
update documentation
SylvainJuge Jul 10, 2025
f67f2b9
./gradlew spotlessApply
otelbot[bot] Jul 10, 2025
6f7c271
align transaction metrics with sessions
SylvainJuge Jul 10, 2025
c1a1652
refine a bit and add session limit
SylvainJuge Jul 10, 2025
3334081
fix doc
SylvainJuge Jul 10, 2025
3dd8e38
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jul 10, 2025
ba56971
add explicit session count for tomcat
SylvainJuge Jul 10, 2025
16b4165
post-review changes
SylvainJuge Jul 11, 2025
6ed598d
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jul 15, 2025
abc2bba
post-review changes
SylvainJuge Jul 15, 2025
531f836
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jul 17, 2025
db7c8a3
fix and simplify jetty test
SylvainJuge Jul 17, 2025
3d1c2cd
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jul 18, 2025
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
2 changes: 1 addition & 1 deletion instrumentation/jmx-metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ No targets are enabled by default. The supported target environments are listed
- [jetty](library/jetty.md)
- [kafka-broker](javaagent/kafka-broker.md)
- [tomcat](library/tomcat.md)
- [wildfly](javaagent/wildfly.md)
- [wildfly](library/wildfly.md)
- [hadoop](javaagent/hadoop.md)

The [jvm](library/jvm.md) metrics definitions are also included in the [jmx-metrics library](./library)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ class JmxMetricInsightInstallerTest {
private static final String PATH_TO_ALL_EXISTING_RULES = "src/main/resources/jmx/rules";
private static final Set<String> FILES_TO_BE_TESTED =
new HashSet<>(
Arrays.asList(
"activemq.yaml", "camel.yaml", "hadoop.yaml", "kafka-broker.yaml", "wildfly.yaml"));
Arrays.asList("activemq.yaml", "camel.yaml", "hadoop.yaml", "kafka-broker.yaml"));

@Test
void testToVerifyExistingRulesAreValid() throws Exception {
Expand Down
18 changes: 0 additions & 18 deletions instrumentation/jmx-metrics/javaagent/wildfly.md

This file was deleted.

9 changes: 7 additions & 2 deletions instrumentation/jmx-metrics/library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@ tasks {
test {
// get packaged agent jar for testing
val shadowTask = project(":javaagent").tasks.named<ShadowJar>("shadowJar").get()

dependsOn(shadowTask)

val testAppTask = project(":instrumentation:jmx-metrics:testing-webapp").tasks.named<War>("war")
dependsOn(testAppTask)

inputs.files(layout.files(shadowTask))
.withPropertyName("javaagent")
.withNormalizer(ClasspathNormalizer::class)

doFirst {
jvmArgs("-Dio.opentelemetry.javaagent.path=${shadowTask.archiveFile.get()}")
jvmArgs(
"-Dio.opentelemetry.javaagent.path=${shadowTask.archiveFile.get()}",
"-Dio.opentelemetry.testapp.path=${testAppTask.get().archiveFile.get().asFile.absolutePath}"
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
rules:

- bean: jboss.as:deployment=*,subsystem=undertow
prefix: wildfly.session.
metricAttribute:
wildfly.deployment: param(deployment)
unit: "{session}"
mapping:
# wildfly.session.created
sessionsCreated:
metric: created
type: counter
desc: The number of sessions created
# wildfly.session.active.count
activeSessions:
metric: active.count
type: updowncounter
desc: The number of active sessions
# wildfly.session.active.limit
maxActiveSessions:
metric: active.limit
type: updowncounter
desc: The maximum number of active sessions
# discard negative values used to indicate absence of limit
dropNegativeValues: true
# wildfly.session.expired
expiredSessions:
metric: expired
type: counter
desc: The number of expired sessions
# wildfly.session.rejected
rejectedSessions:
metric: rejected
type: counter
desc: The number of rejected sessions

- bean: jboss.as:subsystem=undertow,server=*,http-listener=*
prefix: wildfly.
metricAttribute:
wildfly.server: param(server)
wildfly.listener: param(http-listener)
type: counter
mapping:
# wildfly.request.count
requestCount:
metric: request.count
unit: "{request}"
desc: The number of requests served
# wildfly.request.duration.sum
processingTime:
metric: request.duration.sum
sourceUnit: ns
unit: s
desc: The total amount of time spent processing requests
# wildfly.error.count
errorCount:
metric: error.count
unit: "{request}"
desc: The number of requests that have resulted in a 5xx response

# wildly.network.io
- bean: jboss.as:subsystem=undertow,server=*,http-listener=*
metricAttribute:
wildfly.server: param(server)
wildfly.listener: param(http-listener)
type: counter
unit: By
mapping:
bytesSent:
metric: &metric wildfly.network.io
desc: &desc Total number of bytes transferred
metricAttribute:
network.io.direction: const(transmit)
bytesReceived:
metric: *metric
desc: *desc
metricAttribute:
network.io.direction: const(receive)

- bean: jboss.as:subsystem=datasources,data-source=*,statistics=pool
prefix: wildfly.db.client.connection.
metricAttribute:
db.client.connection.pool.name: param(data-source)
mapping:
# wildfly.db.client.connection.count
ActiveCount:
metric: &metric count
type: &type updowncounter
unit: &unit "{connection}"
desc: &desc The number of open physical database connections
metricAttribute:
db.client.connection.state: const(used)
IdleCount:
metric: *metric
type: *type
unit: *unit
desc: *desc
metricAttribute:
db.client.connection.state: const(idle)
# wildfly.db.client.connection.wait.count
WaitCount:
metric: wait.count
type: counter
# In this context, 'request' means 'connection request'
unit: "{request}"
desc: The number of connection requests that had to wait to obtain it

- bean: jboss.as:subsystem=transactions
prefix: wildfly.transaction.
unit: "{transaction}"
mapping:
# wildfly.transaction.count
numberOfInflightTransactions:
metric: count
type: updowncounter
desc: The number of in-flight transactions
# wildfly.transaction.created
numberOfTransactions:
metric: created
type: counter
desc: The total number of transactions created
# wildfly.transaction.committed
Copy link
Contributor

@robsunday robsunday Jul 15, 2025

Choose a reason for hiding this comment

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

I'd prefer having wildfly.transaction.committed.count because it bescribes a data it keeps better than just wildfly.transaction.committed.
Many metrics in this file have .count suffix, but many do not, or even got it removed.
Do you think we could use .count suffix as a standard for counters/updowncounters ? Semconv recommends it for updowncounters anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's something that I really considered doing, however adding the .count to every counter/updowncounter metric seems a bit redundant so I think it's simpler to use it only when needed, for example in the following cases:

  • wildfly.db.client.connection.wait.count adding count helps with the naming as "wait" is not really a noun, also using a similar pattern we could capture the "wait time", for example with wildfly.db.client.connection.wait.duration, in this case it would anticipate a potential future use-case that does not exist yet.
  • wildfly.session.active.count because we also have wildfly.session.active.limit, however for sessions we have wildfly.session.{created,expired,rejected}: there isn't any further breakdown possible, hence it should be fine to define them without .count suffix.

The way I understand the semconv specification here is that we could use .count to remove ambiguity or avoid plural terms, not that we have to use this strategy for every counter.

Copy link
Contributor

@robsunday robsunday Jul 15, 2025

Choose a reason for hiding this comment

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

I'm still not 100% convinced, but this is just my personal preference to keep metric names as explicit as possible.
If I see a metric with the name like tomcat.error.count it is obvious that we have number of errors. If I see metric with name tomcat.error it is not obvious what data is there, at least not at the first glance.

And according to the example you brought up:
wildfly.session.active.count, wildfly.session.created, wildfly.session.expired and wildfly.session.rejected share similar category of data, but do not share naming pattern.
I'd really prefer having consitent wildfly.session.{active,created,expired,rejected} or wildfly.session.{active,created,expired,rejected}.count, but I'm not going to hold this PR if nobody else has any objections.

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 another point of reference the JVM metrics, which happen to be the only ones that are currently part of semconv tend to only use the .count to indicate the current value, for example we have:

  • jvm.class.loaded
  • jvm.class.count
  • jvm.class.unloaded

And in the case of memory buffers we already have a case where we have "distinct depths" in the same namespace:

  • jvm.buffer.count
  • jvm.buffer.memory.used
  • jvm.buffer.memory.limit

numberOfCommittedTransactions:
metric: committed
type: counter
desc: The total number of transactions committed
# wildfly.transaction.rollback
numberOfApplicationRollbacks:
metric: &metric rollback
type: &type counter
metricAttribute:
wildfly.rollback.cause: const(application)
desc: &desc The total number of transactions rolled back
numberOfResourceRollbacks:
metric: *metric
type: *type
metricAttribute:
wildfly.rollback.cause: const(resource)
desc: *desc
numberOfSystemRollbacks:
metric: *metric
type: *type
metricAttribute:
wildfly.rollback.cause: const(system)
desc: *desc

Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
import org.junit.jupiter.params.provider.ValueSource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.images.builder.ImageFromDockerfile;

public class JettyIntegrationTest extends TargetSystemTest {
public class JettyTest extends TargetSystemTest {

private static final int JETTY_PORT = 8080;

Expand All @@ -48,25 +47,20 @@ void testCollectedMetrics(int jettyMajorVersion) {
// with older versions deployment and session management are available by default
jettyModules.add("stats");
}
String addModulesArg = "--add-to-startd=" + String.join(",", jettyModules);
String moduleArg = "--module=" + String.join(",", jettyModules);

GenericContainer<?> container =
new GenericContainer<>(
new ImageFromDockerfile()
.withDockerfileFromBuilder(
builder ->
builder
.from("jetty:" + jettyMajorVersion)
.run("java", "-jar", "/usr/local/jetty/start.jar", addModulesArg)
.run("mkdir -p /var/lib/jetty/webapps/ROOT/")
.run("touch /var/lib/jetty/webapps/ROOT/index.html")
.build()))
new GenericContainer<>("jetty:" + jettyMajorVersion)
.withCommand(moduleArg)
.withEnv("JAVA_OPTIONS", String.join(" ", jvmArgs))
.withStartupTimeout(Duration.ofMinutes(2))
.withExposedPorts(JETTY_PORT)
.waitingFor(Wait.forListeningPorts(JETTY_PORT));

copyFilesToTarget(container, yamlFiles);
copyAgentToTarget(container);
copyYamlFilesToTarget(container, yamlFiles);
// Deploy example web application for session-related metrics
copyTestWebAppToTarget(container, "/var/lib/jetty/webapps/ROOT.war");

startTarget(container);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;

class JvmTargetSystemTest extends TargetSystemTest {
class JvmTest extends TargetSystemTest {

@ParameterizedTest
@ValueSource(
Expand All @@ -47,7 +47,8 @@ void testJvmMetrics(String image) {
.withExposedPorts(8080)
.waitingFor(Wait.forListeningPorts(8080));

copyFilesToTarget(target, yamlFiles);
copyAgentToTarget(target);
copyYamlFilesToTarget(target, yamlFiles);

startTarget(target);

Expand Down
Loading
Loading