-
Notifications
You must be signed in to change notification settings - Fork 1k
jmx state metrics #12369
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
Merged
Merged
jmx state metrics #12369
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
9272bfe
minor test refactor
SylvainJuge 6f20784
enhance tests
SylvainJuge d1a195b
add more assertions in tests
SylvainJuge 3f2f151
add state mapping + tests
SylvainJuge 5973b01
impl + test
SylvainJuge 4fd10aa
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge 6155206
spotless
SylvainJuge af37bb4
thou shall lint
SylvainJuge 6551200
minor add @Nullable
SylvainJuge 376acc5
fix state metric detection
SylvainJuge 679c460
lint again
SylvainJuge e5ff7c5
implement new syntax
SylvainJuge 8e73f10
cleanup
SylvainJuge e9e8e83
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge 550b003
spotless
SylvainJuge 1bb4302
add documentation
SylvainJuge ebf58ff
minor code refactor to use lists instead of arrays
SylvainJuge 6c10e6d
port-review change in docs
SylvainJuge 652ab32
switch to _ + enhance doc for 2 state
SylvainJuge e24b9ae
Update instrumentation/jmx-metrics/library/src/main/java/io/opentelem…
SylvainJuge 2698be3
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge e4b9fe5
restore '*' as wildcard + clarify quoting
SylvainJuge 111c26b
Merge branch 'state-jmx-metrics' of github.com:SylvainJuge/openteleme…
SylvainJuge 96bb6cc
restore '*' again
SylvainJuge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
| import io.opentelemetry.instrumentation.jmx.engine.BeanAttributeExtractor; | ||
| import io.opentelemetry.instrumentation.jmx.engine.BeanGroup; | ||
| import io.opentelemetry.instrumentation.jmx.engine.MetricAttribute; | ||
| import io.opentelemetry.instrumentation.jmx.engine.MetricAttributeExtractor; | ||
| import io.opentelemetry.instrumentation.jmx.engine.MetricDef; | ||
| import io.opentelemetry.instrumentation.jmx.engine.MetricExtractor; | ||
| import io.opentelemetry.instrumentation.jmx.engine.MetricInfo; | ||
|
|
@@ -18,6 +19,7 @@ | |
| import java.util.Map; | ||
| import java.util.Set; | ||
| import javax.annotation.Nullable; | ||
| import javax.management.MBeanServerConnection; | ||
| import javax.management.MalformedObjectNameException; | ||
| import javax.management.ObjectName; | ||
|
|
||
|
|
@@ -143,8 +145,7 @@ public MetricDef buildMetricDef() throws Exception { | |
| } | ||
|
|
||
| Set<String> attrNames = mapping.keySet(); | ||
| MetricExtractor[] metricExtractors = new MetricExtractor[attrNames.size()]; | ||
| int n = 0; | ||
| List<MetricExtractor> metricExtractors = new ArrayList<>(); | ||
| for (String attributeName : attrNames) { | ||
| BeanAttributeExtractor attrExtractor = BeanAttributeExtractor.fromName(attributeName); | ||
| // This is essentially the same as 'attributeName' but with escape characters removed | ||
|
|
@@ -162,44 +163,104 @@ public MetricDef buildMetricDef() throws Exception { | |
| metricInfo = m.buildMetricInfo(prefix, niceAttributeName, getUnit(), getMetricType()); | ||
| } | ||
|
|
||
| List<MetricAttribute> attributeList; | ||
| List<MetricAttribute> ownAttributes = getAttributeList(); | ||
| if (ownAttributes != null && m != null && m.getAttributeList() != null) { | ||
| // MetricAttributes have been specified at two levels, need to combine them | ||
| attributeList = combineMetricAttributes(ownAttributes, m.getAttributeList()); | ||
| } else if (ownAttributes != null) { | ||
| attributeList = ownAttributes; | ||
| } else if (m != null && m.getAttributeList() != null) { | ||
| // Get the attributes from the metric | ||
| attributeList = m.getAttributeList(); | ||
| List<MetricAttribute> metricAttributes = m != null ? m.getAttributeList() : null; | ||
| List<MetricAttribute> attributeList = | ||
| combineMetricAttributes(ownAttributes, metricAttributes); | ||
|
|
||
| // higher priority to metric level mapping, then jmx rule as fallback | ||
| StateMapping stateMapping = getEffectiveStateMapping(m, this); | ||
|
|
||
| if (stateMapping.isEmpty()) { | ||
| metricExtractors.add( | ||
| new MetricExtractor( | ||
| attrExtractor, metricInfo, attributeList.toArray(new MetricAttribute[0]))); | ||
| } else { | ||
| // There are no attributes at all | ||
| attributeList = new ArrayList<MetricAttribute>(); | ||
|
|
||
| // generate one metric extractor per state metric key | ||
| // each metric extractor will have the state attribute replaced with a constant | ||
| metricExtractors.addAll( | ||
| createStateMappingExtractors(stateMapping, attributeList, attrExtractor, metricInfo)); | ||
| } | ||
| } | ||
|
|
||
| return new MetricDef(group, metricExtractors.toArray(new MetricExtractor[0])); | ||
| } | ||
|
|
||
| private static List<MetricExtractor> createStateMappingExtractors( | ||
| StateMapping stateMapping, | ||
| List<MetricAttribute> attributeList, | ||
| BeanAttributeExtractor attrExtractor, | ||
| MetricInfo metricInfo) { | ||
|
|
||
| List<MetricExtractor> extractors = new ArrayList<>(); | ||
| for (String key : stateMapping.getStateKeys()) { | ||
| List<MetricAttribute> stateMetricAttributes = new ArrayList<>(); | ||
|
|
||
| for (MetricAttribute ma : attributeList) { | ||
| // replace state metric attribute with constant key value | ||
| if (!ma.isStateAttribute()) { | ||
| stateMetricAttributes.add(ma); | ||
| } else { | ||
| stateMetricAttributes.add( | ||
| new MetricAttribute( | ||
| ma.getAttributeName(), MetricAttributeExtractor.fromConstant(key))); | ||
| } | ||
| } | ||
|
|
||
| BeanAttributeExtractor stateMetricExtractor = | ||
| new BeanAttributeExtractor(attrExtractor.getAttributeName()) { | ||
|
|
||
| MetricExtractor metricExtractor = | ||
| @Override | ||
| protected Object getSampleValue( | ||
| MBeanServerConnection connection, ObjectName objectName) { | ||
| // metric actual type is sampled in the discovery process, so we have to | ||
| // make this extractor as extracting integers. | ||
| return 0; | ||
| } | ||
|
|
||
| @Override | ||
| protected Number extractNumericalAttribute( | ||
| MBeanServerConnection connection, ObjectName objectName) { | ||
| String rawStateValue = attrExtractor.extractValue(connection, objectName); | ||
| String mappedStateValue = stateMapping.getStateValue(rawStateValue); | ||
| return key.equals(mappedStateValue) ? 1 : 0; | ||
| } | ||
| }; | ||
|
|
||
| extractors.add( | ||
| new MetricExtractor( | ||
| attrExtractor, | ||
| stateMetricExtractor, | ||
| metricInfo, | ||
| attributeList.toArray(new MetricAttribute[attributeList.size()])); | ||
| metricExtractors[n++] = metricExtractor; | ||
| stateMetricAttributes.toArray(new MetricAttribute[0]))); | ||
| } | ||
|
|
||
| return new MetricDef(group, metricExtractors); | ||
| return extractors; | ||
| } | ||
|
|
||
| private static List<MetricAttribute> combineMetricAttributes( | ||
| List<MetricAttribute> ownAttributes, List<MetricAttribute> metricAttributes) { | ||
|
|
||
| Map<String, MetricAttribute> set = new HashMap<>(); | ||
| for (MetricAttribute ownAttribute : ownAttributes) { | ||
| set.put(ownAttribute.getAttributeName(), ownAttribute); | ||
| if (ownAttributes != null) { | ||
| for (MetricAttribute ownAttribute : ownAttributes) { | ||
| set.put(ownAttribute.getAttributeName(), ownAttribute); | ||
| } | ||
| } | ||
|
|
||
| // Let the metric level defined attributes override own attributes | ||
| for (MetricAttribute metricAttribute : metricAttributes) { | ||
| set.put(metricAttribute.getAttributeName(), metricAttribute); | ||
| if (metricAttributes != null) { | ||
| // Let the metric level defined attributes override own attributes | ||
| for (MetricAttribute metricAttribute : metricAttributes) { | ||
| set.put(metricAttribute.getAttributeName(), metricAttribute); | ||
| } | ||
| } | ||
|
|
||
| return new ArrayList<MetricAttribute>(set.values()); | ||
| return new ArrayList<>(set.values()); | ||
| } | ||
|
|
||
| private static StateMapping getEffectiveStateMapping(Metric m, JmxRule rule) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [for reviewer] for state mapping, the resulting mapping is not a combination of rule level and metric level definitions. Only one of them is used. |
||
| if (m == null || m.getStateMapping().isEmpty()) { | ||
| return rule.getStateMapping(); | ||
| } else { | ||
| return m.getStateMapping(); | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 bypass the sample value check for the "artificial" attribute value that we need for the state metric.