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

Add xpack info and usage endpoints for runtime fields #65600

Merged
merged 11 commits into from
Dec 8, 2020

Conversation

javanna
Copy link
Member

@javanna javanna commented Nov 30, 2020

Relates to #59332

@javanna javanna added >enhancement :Search Foundations/Mapping Index mappings, including merging and defining field types v8.0.0 v7.11.0 labels Nov 30, 2020
@javanna javanna requested a review from nik9000 November 30, 2020 13:11
@elasticmachine elasticmachine added the Team:Search Meta label for search team label Nov 30, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search (Team:Search)

@javanna javanna mentioned this pull request Nov 30, 2020
30 tasks
Set<String> indexFieldTypes = new HashSet<>();
MappingMetadata mappingMetadata = indexMetadata.mapping();
if (mappingMetadata != null) {
Object runtimeObject = mappingMetadata.getSourceAsMap().get("runtime");
Copy link
Contributor

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?

Copy link
Member Author

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?

Copy link
Member

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.

@javanna
Copy link
Member Author

javanna commented Nov 30, 2020

run elasticsearch-ci/1

Copy link
Member

@nik9000 nik9000 left a 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
Copy link
Member

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");
Copy link
Member

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;
Copy link
Member

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.

Copy link
Member

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.

Copy link
Member Author

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) {
Copy link
Member

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 continues if mappingMetadata is null. I find quick continues to be easier to short cut in my head when reading. With these indenting ifs 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) {
Copy link
Member

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?

Copy link
Member Author

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);
Copy link
Member

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.

Copy link
Member Author

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?

Copy link
Member

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;
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

@nik9000 nik9000 left a 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[\\[\\.]");
Copy link
Member

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.

Copy link
Member Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>enhancement :Search Foundations/Mapping Index mappings, including merging and defining field types Team:Search Meta label for search team v7.11.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants