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

[jmx-scraper] Assertions refactoring - Tomcat integration test converted #1589

Merged
merged 59 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
c3deb51
New metrics validation framework fundamentals.
robsunday Nov 22, 2024
fcf2bf8
Spotless fixes
robsunday Nov 22, 2024
d833450
Improved check for not received metrics
robsunday Nov 25, 2024
8cb96ad
Cassandra integration test converted
robsunday Nov 25, 2024
f3bac7e
Fine tuning assertion messages.
robsunday Nov 25, 2024
c9eb0a7
ActiveMqIntegrationTest converted
robsunday Nov 25, 2024
2c85c38
Spotless fix
robsunday Nov 26, 2024
bd1947f
introduce 'register' API
SylvainJuge Nov 26, 2024
1e64f80
introduce dedicated assertThat for metrics
SylvainJuge Nov 26, 2024
f7c6373
refactor metrics verifier
SylvainJuge Nov 26, 2024
b10a340
add some javadoc & few comments
SylvainJuge Nov 26, 2024
65ddfb3
spotless & minor things
SylvainJuge Nov 26, 2024
db54835
add new assertion for attribute entries
SylvainJuge Nov 26, 2024
1bdf694
check for missing assertions
SylvainJuge Nov 26, 2024
9f8a394
verify attributes are checked in strict mode
SylvainJuge Nov 27, 2024
6fb7960
enhance datapoint attributes check
SylvainJuge Nov 27, 2024
a458c1c
comments, cleanup and inline a bit
SylvainJuge Nov 27, 2024
b9f054c
strict check avoids duplicate assertions
SylvainJuge Nov 28, 2024
cf72d19
remove obsolete comments in activemq yaml
SylvainJuge Nov 28, 2024
eab7c69
register -> add
SylvainJuge Nov 28, 2024
9c3390c
reformat
SylvainJuge Nov 28, 2024
9392780
refactor cassandra
SylvainJuge Nov 28, 2024
5ae735d
fix lint
SylvainJuge Nov 28, 2024
2c65318
refactor activemq
SylvainJuge Nov 28, 2024
a670561
refactor jvm metrics
SylvainJuge Nov 28, 2024
df09034
remove unused code
SylvainJuge Nov 28, 2024
06a968f
recycle assertions when we can
SylvainJuge Nov 28, 2024
0e5fd2c
Merge pull request #4 from SylvainJuge/assertions-refactoring-more
robsunday Nov 28, 2024
8062a96
Added some JavaDocs.
robsunday Nov 28, 2024
ba95efa
Merge branch 'main' into assertions-refactoring
robsunday Nov 29, 2024
4bed658
Cleanup
robsunday Nov 29, 2024
fddc5fc
Spotless fix
robsunday Nov 29, 2024
fd82042
Refactoring of data point attribute assertions
robsunday Dec 4, 2024
80994f2
Merge branch 'main' into assertions-refactoring
robsunday Dec 4, 2024
b26cf42
Coe review changes
robsunday Dec 4, 2024
0bf10f5
JavaDoc update
robsunday Dec 4, 2024
9f47ef6
JavaDoc update
robsunday Dec 4, 2024
2971ef7
Update jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/…
robsunday Dec 5, 2024
7d7e504
Code review changes
robsunday Dec 5, 2024
19f5d4c
Cleanup
robsunday Dec 5, 2024
6431feb
Additional comments added
robsunday Dec 5, 2024
ba0f900
add attribute matcher set class
SylvainJuge Dec 5, 2024
fdc64e3
remove equals/hashcode
SylvainJuge Dec 5, 2024
7754e3a
use AttributeMatcherSet for matching
SylvainJuge Dec 5, 2024
7b7f0d0
code cleanup
SylvainJuge Dec 5, 2024
cdf4c74
Merge branch 'assertions-refactoring' of github.com:robsunday/opentel…
SylvainJuge Dec 5, 2024
b170021
move set matching
SylvainJuge Dec 5, 2024
59a7dfc
inline conversion to map
SylvainJuge Dec 5, 2024
34b3ab3
reformat & cleanup
SylvainJuge Dec 5, 2024
45ba126
simplify matchesValue
SylvainJuge Dec 6, 2024
5e69a82
rename attribute set -> group
SylvainJuge Dec 6, 2024
dfe3af3
Merge pull request #6 from SylvainJuge/assertions-refactoring
robsunday Dec 6, 2024
159cb5f
Merge branch 'main' into assertions-refactoring
robsunday Dec 10, 2024
036ea99
Use new metrics assertions framework
robsunday Dec 10, 2024
687002c
Spotless fix
robsunday Dec 10, 2024
cf0a17a
Added comment about unit not aligned with semconv
robsunday Dec 10, 2024
ebedd5f
Units updated to align with semconv
robsunday Dec 11, 2024
d286b7a
Update JMX Metrics Gatherer units definitions for Cassandra to match …
robsunday Dec 11, 2024
014d7c9
Unused methods removed
robsunday Dec 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ class TomcatIntegrationTest extends AbstractIntegrationTest {
void endToEnd() {
waitAndAssertMetrics(
metric ->
assertGauge(metric, "tomcat.sessions", "The number of active sessions.", "sessions"),
assertGauge(metric, "tomcat.sessions", "The number of active sessions.", "{session}"),
metric ->
assertSumWithAttributes(
metric,
"tomcat.errors",
"The number of errors encountered.",
"errors",
"{error}",
attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))),
metric ->
assertSumWithAttributes(
Expand All @@ -73,7 +73,7 @@ void endToEnd() {
metric,
"tomcat.traffic",
"The number of bytes transmitted and received.",
"by",
"By",
attrs ->
attrs.containsOnly(
entry("proto_handler", "\"http-nio-8080\""), entry("direction", "sent")),
Expand All @@ -86,7 +86,7 @@ void endToEnd() {
metric,
"tomcat.threads",
"The number of threads",
"threads",
"{thread}",
attrs ->
attrs.containsOnly(
entry("proto_handler", "\"http-nio-8080\""), entry("state", "idle")),
Expand All @@ -105,7 +105,7 @@ void endToEnd() {
metric,
"tomcat.request_count",
"The total requests.",
"requests",
"{request}",
attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))));
}
}
20 changes: 10 additions & 10 deletions jmx-metrics/src/main/resources/target-systems/tomcat.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@


def beantomcatmanager = otel.mbeans("Catalina:type=Manager,host=localhost,context=*")
otel.instrument(beantomcatmanager, "tomcat.sessions", "The number of active sessions.", "sessions", "activeSessions", otel.&longValueCallback)
otel.instrument(beantomcatmanager, "tomcat.sessions", "The number of active sessions.", "{session}", "activeSessions", otel.&longValueCallback)

def beantomcatrequestProcessor = otel.mbeans("Catalina:type=GlobalRequestProcessor,name=*")
otel.instrument(beantomcatrequestProcessor, "tomcat.errors", "The number of errors encountered.", "errors",
otel.instrument(beantomcatrequestProcessor, "tomcat.errors", "The number of errors encountered.", "{error}",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
"errorCount", otel.&longCounterCallback)
otel.instrument(beantomcatrequestProcessor, "tomcat.request_count", "The total requests.", "requests",
otel.instrument(beantomcatrequestProcessor, "tomcat.request_count", "The total requests.", "{request}",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
"requestCount", otel.&longCounterCallback)
otel.instrument(beantomcatrequestProcessor, "tomcat.max_time", "Maximum time to process a request.", "ms",
Expand All @@ -32,24 +32,24 @@ otel.instrument(beantomcatrequestProcessor, "tomcat.processing_time", "The total
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
"processingTime", otel.&longCounterCallback)
otel.instrument(beantomcatrequestProcessor, "tomcat.traffic",
"The number of bytes transmitted and received.", "by",
"The number of bytes transmitted and received.", "By",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name")}],
["bytesReceived":["direction" : {"received"}], "bytesSent": ["direction" : {"sent"}]],
otel.&longCounterCallback)

def beantomcatconnectors = otel.mbeans("Catalina:type=ThreadPool,name=*")
otel.instrument(beantomcatconnectors, "tomcat.threads", "The number of threads", "threads",
otel.instrument(beantomcatconnectors, "tomcat.threads", "The number of threads", "{thread}",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
["currentThreadCount":["state":{"idle"}],"currentThreadsBusy":["state":{"busy"}]], otel.&longValueCallback)

def beantomcatnewmanager = otel.mbeans("Tomcat:type=Manager,host=localhost,context=*")
otel.instrument(beantomcatnewmanager, "tomcat.sessions", "The number of active sessions.", "sessions", "activeSessions", otel.&longValueCallback)
otel.instrument(beantomcatnewmanager, "tomcat.sessions", "The number of active sessions.", "{session}", "activeSessions", otel.&longValueCallback)

def beantomcatnewrequestProcessor = otel.mbeans("Tomcat:type=GlobalRequestProcessor,name=*")
otel.instrument(beantomcatnewrequestProcessor, "tomcat.errors", "The number of errors encountered.", "errors",
otel.instrument(beantomcatnewrequestProcessor, "tomcat.errors", "The number of errors encountered.", "{error}",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
"errorCount", otel.&longCounterCallback)
otel.instrument(beantomcatnewrequestProcessor, "tomcat.request_count", "The total requests.", "requests",
otel.instrument(beantomcatnewrequestProcessor, "tomcat.request_count", "The total requests.", "{request}",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
"requestCount", otel.&longCounterCallback)
otel.instrument(beantomcatnewrequestProcessor, "tomcat.max_time", "Maximum time to process a request.", "ms",
Expand All @@ -59,12 +59,12 @@ otel.instrument(beantomcatnewrequestProcessor, "tomcat.processing_time", "The to
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
"processingTime", otel.&longCounterCallback)
otel.instrument(beantomcatnewrequestProcessor, "tomcat.traffic",
"The number of bytes transmitted and received.", "by",
"The number of bytes transmitted and received.", "By",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name")}],
["bytesReceived":["direction" : {"received"}], "bytesSent": ["direction" : {"sent"}]],
otel.&longCounterCallback)

def beantomcatnewconnectors = otel.mbeans("Tomcat:type=ThreadPool,name=*")
otel.instrument(beantomcatnewconnectors, "tomcat.threads", "The number of threads", "threads",
otel.instrument(beantomcatnewconnectors, "tomcat.threads", "The number of threads", "{thread}",
["proto_handler" : { mbean -> mbean.name().getKeyProperty("name") }],
["currentThreadCount":["state":{"idle"}],"currentThreadsBusy":["state":{"busy"}]], otel.&longValueCallback)
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ class MetricAssertions {

private MetricAssertions() {}

static void assertGauge(Metric metric, String name, String description, String unit) {
assertThat(metric.getName()).isEqualTo(name);
assertThat(metric)
.hasDescription(description)
.hasUnit(unit)
.isGauge()
.hasDataPointsWithoutAttributes();
}

static void assertSum(Metric metric, String name, String description, String unit) {
assertSum(metric, name, description, unit, /* isMonotonic= */ true);
}
Expand Down Expand Up @@ -73,37 +64,6 @@ static void assertSumWithAttributes(
assertAttributedPoints(metric.getSum().getDataPointsList(), attributeGroupAssertions);
}

@SafeVarargs
static void assertSumWithAttributesMultiplePoints(
Metric metric,
String name,
String description,
String unit,
boolean isMonotonic,
Consumer<MapAssert<String, String>>... attributeGroupAssertions) {

assertThat(metric.getName()).isEqualTo(name);
assertThat(metric).hasDescription(description).hasUnit(unit);

assertThat(metric.hasSum()).isTrue();
assertThat(metric.getSum().getIsMonotonic()).isEqualTo(isMonotonic);
assertAttributedMultiplePoints(metric.getSum().getDataPointsList(), attributeGroupAssertions);
}

@SafeVarargs
static void assertGaugeWithAttributes(
Metric metric,
String name,
String description,
String unit,
Consumer<MapAssert<String, String>>... attributeGroupAssertions) {
assertThat(metric.getName()).isEqualTo(name);

assertThat(metric).hasDescription(description).hasUnit(unit).isGauge();

assertAttributedPoints(metric.getGauge().getDataPointsList(), attributeGroupAssertions);
}

@SuppressWarnings("unchecked")
private static void assertAttributedPoints(
List<NumberDataPoint> points,
Expand All @@ -122,22 +82,4 @@ private static void assertAttributedPoints(
KeyValue::getKey, keyValue -> keyValue.getValue().getStringValue())))
.satisfiesExactlyInAnyOrder(assertions);
}

@SuppressWarnings("unchecked")
private static void assertAttributedMultiplePoints(
List<NumberDataPoint> points,
Consumer<MapAssert<String, String>>... attributeGroupAssertions) {

points.stream()
.map(NumberDataPoint::getAttributesList)
.forEach(
kvList -> {
Map<String, String> kvMap =
kvList.stream()
.collect(
Collectors.toMap(KeyValue::getKey, kv -> kv.getValue().getStringValue()));
Arrays.stream(attributeGroupAssertions)
.forEach(assertion -> assertion.accept(assertThat(kvMap)));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

package io.opentelemetry.contrib.jmxscraper.target_systems;

import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertGaugeWithAttributes;
import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertSumWithAttributes;
import static org.assertj.core.api.Assertions.entry;
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attribute;
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeGroup;
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeWithAnyValue;

import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer;
import java.nio.file.Path;
Expand Down Expand Up @@ -46,67 +46,76 @@ protected JmxScraperContainer customizeScraperContainer(
}

@Override
protected void verifyMetrics() {
waitAndAssertMetrics(
metric ->
assertGaugeWithAttributes(
metric,
"tomcat.sessions",
"The number of active sessions",
"sessions",
attrs -> attrs.containsKey("context")),
metric ->
assertSumWithAttributes(
metric,
"tomcat.errors",
"The number of errors encountered",
"errors",
attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))),
metric ->
assertSumWithAttributes(
metric,
"tomcat.processing_time",
"The total processing time",
"ms",
attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))),
metric ->
assertSumWithAttributes(
metric,
"tomcat.traffic",
"The number of bytes transmitted and received",
"by",
attrs ->
attrs.containsOnly(
entry("proto_handler", "\"http-nio-8080\""), entry("direction", "sent")),
attrs ->
attrs.containsOnly(
entry("proto_handler", "\"http-nio-8080\""),
entry("direction", "received"))),
metric ->
assertGaugeWithAttributes(
metric,
"tomcat.threads",
"The number of threads",
"threads",
attrs ->
attrs.containsOnly(
entry("proto_handler", "\"http-nio-8080\""), entry("state", "idle")),
attrs ->
attrs.containsOnly(
entry("proto_handler", "\"http-nio-8080\""), entry("state", "busy"))),
metric ->
assertGaugeWithAttributes(
metric,
"tomcat.max_time",
"Maximum time to process a request",
"ms",
attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))),
metric ->
assertSumWithAttributes(
metric,
"tomcat.request_count",
"The total requests",
"requests",
attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))));
protected MetricsVerifier createMetricsVerifier() {
return MetricsVerifier.create()
.add(
"tomcat.sessions",
metric ->
metric
.hasDescription("The number of active sessions")
.hasUnit("{session}")
.isGauge()
.hasDataPointsWithOneAttribute(attributeWithAnyValue("context")))
.add(
"tomcat.errors",
metric ->
metric
.hasDescription("The number of errors encountered")
.hasUnit("{error}")
.isCounter()
.hasDataPointsWithOneAttribute(attribute("proto_handler", "\"http-nio-8080\"")))
.add(
"tomcat.processing_time",
metric ->
metric
.hasDescription("The total processing time")
.hasUnit("ms")
.isCounter()
.hasDataPointsWithOneAttribute(attribute("proto_handler", "\"http-nio-8080\"")))
.add(
"tomcat.traffic",
metric ->
metric
.hasDescription("The number of bytes transmitted and received")
.hasUnit("By")
.isCounter()
.hasDataPointsWithAttributes(
attributeGroup(
attribute("direction", "sent"),
attribute("proto_handler", "\"http-nio-8080\"")),
attributeGroup(
attribute("direction", "received"),
attribute("proto_handler", "\"http-nio-8080\""))))
.add(
"tomcat.threads",
metric ->
metric
.hasDescription("The number of threads")
.hasUnit("{thread}")
.isGauge()
.hasDataPointsWithAttributes(
attributeGroup(
attribute("state", "idle"),
attribute("proto_handler", "\"http-nio-8080\"")),
attributeGroup(
attribute("state", "busy"),
attribute("proto_handler", "\"http-nio-8080\""))))
.add(
"tomcat.max_time",
metric ->
metric
.hasDescription("Maximum time to process a request")
.hasUnit("ms")
.isGauge()
.hasDataPointsWithOneAttribute(attribute("proto_handler", "\"http-nio-8080\"")))
.add(
"tomcat.request_count",
metric ->
metric
.hasDescription("The total requests")
.hasUnit("{request}")
.isCounter()
.hasDataPointsWithOneAttribute(
attribute("proto_handler", "\"http-nio-8080\"")));
}
}
14 changes: 7 additions & 7 deletions jmx-scraper/src/main/resources/tomcat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ rules:
activeSessions:
metric: tomcat.sessions
type: gauge
unit: sessions
unit: "{session}"
desc: The number of active sessions

- beans:
Expand All @@ -28,12 +28,12 @@ rules:
errorCount:
metric: errors
type: counter
unit: errors
unit: "{error}"
desc: The number of errors encountered
requestCount:
metric: request_count
type: counter
unit: requests
unit: "{request}"
desc: The total requests
maxTime:
metric: max_time
Expand All @@ -48,14 +48,14 @@ rules:
bytesSent:
metric: traffic
type: counter
unit: by
unit: By
desc: The number of bytes transmitted and received
metricAttribute:
direction: const(sent)
bytesReceived:
metric: traffic
type: counter
unit: by
unit: By
desc: The number of bytes transmitted and received
metricAttribute:
direction: const(received)
Expand All @@ -71,13 +71,13 @@ rules:
metric: threads
desc: The number of threads
type: gauge
unit: threads
unit: "{thread}"
metricAttribute:
state: const(idle)
currentThreadsBusy:
metric: threads
desc: The number of threads
type: gauge
unit: threads
unit: "{thread}"
metricAttribute:
state: const(busy)
Loading