-
Notifications
You must be signed in to change notification settings - Fork 962
jmx metrics: require explicit unit in yaml #13796
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 metrics: require explicit unit in yaml #13796
Conversation
I added to this week's SIG agenda to discuss
|
...etrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/engine/RuleParserTest.java
Outdated
Show resolved
Hide resolved
…etry/instrumentation/jmx/engine/RuleParserTest.java Co-authored-by: Jay DeLuca <jaydeluca4@gmail.com>
Thanks, I won't be able to attend both May 1st and May 8th SIG meetings though, my take on this would be to:
|
Maybe you meant throw an exception if the unit isn't provided? We discussed in the 5/1/2025 java SIG and like this approach:
|
@SylvainJuge @PeterF778 one open question is how disruptive this change might be for existing users, and whether we want to wait to make the change in 3.0 or not? |
I think that all JMX metrics do have well-defined units, so it should be fine to demand that the units are specified in the yaml file. Also, as I understand, even today the users are forced to specify units in order to get the metrics exported (see the original motivation for the PR), even if this seems to be incorrect behavior on the SDK part. I'm all behind the solution as summarized by @jack-berg . |
Thanks for discussing this during last SIG meeting, I also think it's unlikely to impact users as they currently don't have metrics without units being exported. Implementation-wise, while the parsing will throw an exception, the end result of this parsing error would be a warning in the agent log so we should not have to wait for 3.0 here. For existing users with unspecified metrics they would still get more value with a warning rather than a silent failure. If you all agree here I will update this PR accordingly. |
…pen-telemetry#13800) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…h2-http to v1.34.0 (open-telemetry#13807) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Lauri Tulmin <ltulmin@splunk.com>
…nstrumentation into jmx-use-empty-unit-as-default
@@ -34,10 +33,6 @@ private BeanGroup(@Nullable QueryExp queryExp, List<ObjectName> namePatterns) { | |||
this.namePatterns = namePatterns; | |||
} | |||
|
|||
public static BeanGroup forSingleBean(String bean) throws MalformedObjectNameException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] removed as not used anymore.
public void addBean(String bean) { | ||
if (beans == null) { | ||
beans = new ArrayList<>(); | ||
} | ||
beans.add(validateBean(bean)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] simplify a bit by allowing to add any number of beans using either bean
(single) or beans
(list)
null, | ||
"", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] using an empty string as unit seems an appropriate choice for state metrics.
...tion/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/yaml/Metric.java
Outdated
Show resolved
Hide resolved
metricType = jmxRule.getMetricType(); | ||
} | ||
if (metricType == null) { | ||
metricType = MetricInfo.Type.GAUGE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] The same default is applied in MetricInfo
constructor, moving it here makes it happen a bit earlier. I expect a later refactor of this would bring the complete building and validation logic into this method.
try { | ||
this.metricType = MetricInfo.Type.valueOf(t); | ||
} catch (IllegalArgumentException e) { | ||
throw new IllegalArgumentException("Invalid metric type: " + t, e); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] this allows to make the error message nicer for the end user when type is invalid.
@@ -167,7 +174,7 @@ static MetricAttribute buildMetricAttribute(String key, String target) { | |||
// an optional modifier may wrap the target | |||
// - lowercase(param(STRING)) | |||
boolean lowercase = false; | |||
String lowerCaseExpr = tryParseFunction("lowercase", targetExpr, target); | |||
String lowerCaseExpr = tryParseFunction("lowercase", targetExpr, errorMsg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] this fixes a typo that made the error message harder to read, same for others below.
() -> { | ||
JmxConfig config = parseConf(yaml); | ||
private static void runNegativeTest(String yaml, String message) { | ||
assertThatThrownBy( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] using assertj to make testing for exception message easier.
try { | ||
rule.buildMetricDef(); | ||
} catch (Exception e) { | ||
throw new IllegalStateException(e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] here throwing the original message allows to keep the assertion on message content the same.
@@ -616,7 +641,7 @@ void testNoBeans() { | |||
+ " - mapping: # still no beans\n" | |||
+ " A:\n" | |||
+ " metric: METRIC_NAME\n"; | |||
runNegativeTest(yaml); | |||
runNegativeTest(yaml, "No ObjectName specified"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[for reviewer] previously any parsing error would make the test pass, adding the expected exception message allows to ensure that we trigger the validation error we expect.
I've updated the PR to make the unit mandatory in YAML, this allowed to uncover that state metrics need to have a unit too, so I've picked empty string as unit for now. |
maybe "1" would be a better default unit? cc @jack-berg |
I have been thinking about it as well, and it was my first thought. However, the unit of |
yeah, though I think we're reporting them as updowncounters, which implies they can be aggregated? |
Good point. @SylvainJuge , do you see a use case for aggregation of state metrics? If not, perhaps we should revisit the type of the metric. |
For state metrics, the aggregation can be used to provide a "count" of the total number of observed items. Because the value is always 0 or 1 I think aggregation should always produce something useful as we are "counting things that have a state". For example, with the Tomcat connector example:
I think we can get similar usages with the So, if the meaning attached to the So we could have at least 4 possible choices for the unit of state metrics:
I don't have any strong opinion here, but the empty string seems the simplest path for now:
|
...tion/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/yaml/Metric.java
Outdated
Show resolved
Hide resolved
if (beans == null) { | ||
beans = new ArrayList<>(); | ||
} | ||
beans.add(validateBean(bean)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[minor] beans could actually be a Set to prevent duplicates
…nstrumentation into jmx-use-empty-unit-as-default
…nstrumentation into jmx-use-empty-unit-as-default
Related discussion: #13777
Resolves: #13812
With JMX metrics, the default metric unit is currently
null
, which means metrics are not properly exported unless a metric is explicitly provided in the YAML. Unfortunately this is quite easy to miss and it's probably better to report with an unexpected metric rather than not report anything.The Java SDK currently explicitly tests for empty units, which means it should be something supported and thus reported.
As an alternative, we could maybe treat a missing metric as an error and throw an exception during parsing.
Bonus: take that opportunity to refactor and simplify a bit yaml parsing.Update: as discussed in the comments, we switched the approach to throw an error when the unit is not explicitly set, this PR has thus been updated to reflect this new approach.