-
Notifications
You must be signed in to change notification settings - Fork 25k
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 xpack info and usage endpoints for runtime fields #65600
Add xpack info and usage endpoints for runtime fields #65600
Conversation
Pinging @elastic/es-search (Team:Search) |
Set<String> indexFieldTypes = new HashSet<>(); | ||
MappingMetadata mappingMetadata = indexMetadata.mapping(); | ||
if (mappingMetadata != null) { | ||
Object runtimeObject = mappingMetadata.getSourceAsMap().get("runtime"); |
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.
We have MappingVisitor which already implements some of this, although it looks in properties
rather than runtime
- might be worth extending or re-using some of that?
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.
I am aware, those rely on standard field type structure also. To reuse the existing mappings visitor I should have made a runtime visitor that looks in the runtime section instead of properties, and also plugin a function to process fields differently for runtime fields, as we want to have additional stats for them. Also, the standard mappings visitor looks at multi fields recursively which is not something that we support for runtime fields. The only call to this visitor would be from the runtime fields usage api, hence I thought it's overkill. I believe it would be more lines added for the added flexibility than shared between the two implementations. What do you think?
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.
I figure if we see the need later we'll add a visitor but that this works fine for now.
run elasticsearch-ci/1 |
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.
I left some small stuff but LGTM either way.
static final List<XPackUsageFeatureAction> ALL = List.of( | ||
SECURITY, MONITORING, WATCHER, GRAPH, MACHINE_LEARNING, LOGSTASH, EQL, SQL, ROLLUP, INDEX_LIFECYCLE, SNAPSHOT_LIFECYCLE, CCR, | ||
TRANSFORM, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS, DATA_STREAMS, SEARCHABLE_SNAPSHOTS, DATA_TIERS, | ||
AGGREGATE_METRIC, RUNTIME_FIELDS |
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.
👍
While you are here could you make them one per line and alphabetical order? I know it is a pain but it'll push everyone who comes after you to be neat and tidy.
Set<String> indexFieldTypes = new HashSet<>(); | ||
MappingMetadata mappingMetadata = indexMetadata.mapping(); | ||
if (mappingMetadata != null) { | ||
Object runtimeObject = mappingMetadata.getSourceAsMap().get("runtime"); |
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.
I figure if we see the need later we'll add a visitor but that this works fine for now.
Object runtimeObject = mappingMetadata.getSourceAsMap().get("runtime"); | ||
if (runtimeObject instanceof Map) { | ||
@SuppressWarnings("unchecked") | ||
Map<String, Object> runtimeMappings = (Map<String, Object>) runtimeObject; |
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.
If you cast to Map<?, ?>
you don't need to suppress and .values
will still return Object
. You can't .put
on the map but you don't need to.
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.
Just a sneaky way to save a line.
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.
nice trick
} | ||
Set<String> indexFieldTypes = new HashSet<>(); | ||
MappingMetadata mappingMetadata = indexMetadata.mapping(); | ||
if (mappingMetadata != 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.
Is there any chance you could flip this so it continue
s if mappingMetadata
is null. I find quick continues to be easier to short cut in my head when reading. With these indenting if
s I have to scroll down and check if there is an else
.
Object scriptObject = runtimeFieldMapping.get("script"); | ||
if (scriptObject == null) { | ||
stats.scriptLessCount++; | ||
} else if (scriptObject instanceof Map) { |
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.
If script isn't an instanceof Map
can it be a String
? Would we get the short form here?
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.
It is my understanding that regardless of how it was submitted, the script always gets outputted in the long form. I will double check though. That is also why I am using the Script class in the unit tests
} | ||
RuntimeFieldStats[] runtimeFieldStats = fieldTypes.values().toArray(new RuntimeFieldStats[0]); | ||
Arrays.sort(runtimeFieldStats, Comparator.comparing(RuntimeFieldStats::type)); | ||
return new RuntimeFieldsFeatureSetUsage(runtimeFieldStats); |
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.
Any reason not to use a List
in the response? I know we sometimes use List
and sometimes arrays but I've never been sure why.
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.
I generally use a list when elements need to be added, and an array otherwise. I guess you'd like to use a list because it can be made truly immutable?
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.
Mostly because we accumulated a list so it feels like we may as well keep it that way. Either way is fine.
private long maxSourceUsages = 0; | ||
private long totalSourceUsages = 0; | ||
private long maxDocUsages = 0; | ||
private long totalDocUsages = 0; |
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.
= 0
is the default, right?
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.
I guess, but I always forget.
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.
I think this is good.
I also think it means we'll need totally separate stuff for grok or geoip or whatever.
String scriptSource = sourceObject.toString(); | ||
int chars = scriptSource.length(); | ||
long lines = scriptSource.lines().count(); | ||
int docUsages = countOccurrences(scriptSource, "doc[\\[\\.]"); |
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.
I think its worth double checking if this matches stuff like doc\
. I never can remember the escaping rules for character classes.
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.
I think it's ok, but I am not sure I can be trusted, I will double check
Relates to #59332