-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Fix the timestamp field of a data stream to @timestamp #59076
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
Fix the timestamp field of a data stream to @timestamp #59076
Conversation
The commit makes the following changes: * The timestamp field of a data stream definition in a composable index template can only be set to '@timestamp'. * Removed custom data stream timestamp field validation and reuse the validation from `TimestampFieldMapper` and instead only check that the _timestamp field mapping has been defined on a backing index of a data stream. * Moved code that injects _timestamp meta field mapping from `MetadataCreateIndexService#applyCreateIndexRequestWithV2Template58956(...)` method to `MetadataIndexTemplateService#collectMappings(...)` method. * Fixed a bug (elastic#58956) that cases timestamp field validation to be performed for each template and instead of the final mappings that is created. Relates to elastic#58642 Relates to elastic#53100 Closes elastic#58956 Closes elastic#58583
@elasticmachine run elasticsearch-ci/2 |
Pinging @elastic/es-core-features (:Core/Features/Data streams) |
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.
LGTM, thanks Martijn! I left some really minor comments
@@ -256,6 +257,10 @@ public String toString() { | |||
private final String timestampField; | |||
|
|||
public DataStreamTemplate(String timestampField) { | |||
if ("@timestamp".equals(timestampField) == false) { |
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.
Can we make this a public static string so it can be referenced elsewhere?
* @return a mapping snippet for a backing index with `_timestamp` meta field mapper properly configured. | ||
*/ | ||
public Map<String, Object> getDataSteamMappingSnippet() { | ||
return Map.of("_doc", Map.of(TimestampFieldMapper.NAME, Map.of("path", timestampField))); |
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.
Super minor:
return Map.of("_doc", Map.of(TimestampFieldMapper.NAME, Map.of("path", timestampField))); | |
return Map.of(MapperService.SINGLE_MAPPING_NAME, Map.of(TimestampFieldMapper.NAME, Map.of("path", timestampField))); |
|
||
public TimestampField(String name) { | ||
assert "@timestamp".equals(name) : "unexpected timestamp field [" + name + "]"; |
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 we should transform this into an actual error, that way if we end up using it for the HLRC it doesn't fail to throw because assertions are disabled
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 HLRC uses its own DataStream
pojo. I will change this from an assertion to an actual error.
|
||
@SuppressWarnings("unchecked") | ||
private static final ConstructingObjectParser<TimestampField, Void> PARSER = new ConstructingObjectParser<>( | ||
"timestamp_field", | ||
args -> new TimestampField((String) args[0], (Map<String, Object>) args[1]) | ||
args -> new TimestampField((String) args[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.
This makes me wonder, this is fine as-is, but should we even bother having this class or specifying the name of the field if it's going to be hardcoded for the foreseeable future?
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 prefer to keep this class. I think that that the timestamp field will not stay hard coded for a long time.
…a stream or data stream rollover, this fixes a docs test, where a regular index creation matches (logs-*) with a template with a data stream definition.
@@ -902,6 +909,23 @@ public static String findV2Template(Metadata metadata, String indexName, boolean | |||
Optional.ofNullable(template.template()) | |||
.map(Template::mappings) | |||
.ifPresent(mappings::add); | |||
|
|||
// Only include _timestamp mapping snippet if creating backing index. | |||
if (indexName.startsWith(DataStream.BACKING_INDEX_PREFIX)) { |
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.
@dakrone I had to add this if statement otherwise the meta field mapper was going to be applied on each create index api call. In a docs test, the new logs-- composable index template was triggered by a regular create index api call and then the test failed, because the document being indexed had no timestamp field.
I think only applying the meta field automatically makes sense for backing indices only and not when a user creates a new index via create index api and the index composable template matches?
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.
Note currently in master, the _timestamp
field gets only applied if the create index request originates from create data stream api and data stream rollover (signalled via CreateIndexClusterStateUpdateRequest#dataStreamName
field), but now this logic moved MetadataIndexTemplateService.collectMappings(...)
method, which didn't have that context.
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.
Would it be cleaner to pull this check out of collectMappings
and into the caller? That way we could avoid the workaround here: https://github.com/elastic/elasticsearch/pull/59076/files#diff-115cd2f0fff9dd97acc95e1d29012a15R1075.
…and keep using current timestamp field
(a change got in after I merged in master into this pr, but didn't notice it until I merged this pr)
Backport elastic#59076 of to 7.x branch. The commit makes the following changes: * The timestamp field of a data stream definition in a composable index template can only be set to '@timestamp'. * Removed custom data stream timestamp field validation and reuse the validation from `TimestampFieldMapper` and instead only check that the _timestamp field mapping has been defined on a backing index of a data stream. * Moved code that injects _timestamp meta field mapping from `MetadataCreateIndexService#applyCreateIndexRequestWithV2Template58956(...)` method to `MetadataIndexTemplateService#collectMappings(...)` method. * Fixed a bug (elastic#58956) that cases timestamp field validation to be performed for each template and instead of the final mappings that is created. * only apply _timestamp meta field if index is created as part of a data stream or data stream rollover, this fixes a docs test, where a regular index creation matches (logs-*) with a template with a data stream definition. Relates to elastic#58642 Relates to elastic#53100 Closes elastic#58956 Closes elastic#58583
(a change got in after I merged in master into this pr, but didn't notice it until I merged this pr)
Backport of #59076 to 7.x branch. The commit makes the following changes: * The timestamp field of a data stream definition in a composable index template can only be set to '@timestamp'. * Removed custom data stream timestamp field validation and reuse the validation from `TimestampFieldMapper` and instead only check that the _timestamp field mapping has been defined on a backing index of a data stream. * Moved code that injects _timestamp meta field mapping from `MetadataCreateIndexService#applyCreateIndexRequestWithV2Template58956(...)` method to `MetadataIndexTemplateService#collectMappings(...)` method. * Fixed a bug (#58956) that cases timestamp field validation to be performed for each template and instead of the final mappings that is created. * only apply _timestamp meta field if index is created as part of a data stream or data stream rollover, this fixes a docs test, where a regular index creation matches (logs-*) with a template with a data stream definition. Relates to #58642 Relates to #53100 Closes #58956 Closes #58583
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 a few late comments!
/** | ||
* @return a mapping snippet for a backing index with `_timestamp` meta field mapper properly configured. | ||
*/ | ||
public Map<String, Object> getDataSteamMappingSnippet() { |
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.
Noticed this typo as I was trying to pull up the method: DataSteam
-> DataStream
.
@@ -196,6 +196,10 @@ public void validate(DocumentFieldMappers lookup) { | |||
} | |||
} | |||
|
|||
public String getPath() { |
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.
Does TimestampFieldMapper
need a path
parameter now? We're not sure how we will eventually implement custom timestamp names, I can see an implementation where we don't use path
here at all. So maybe we could simplify and just have an enabled
boolean flag instead.
Depending on the implementation, we can always add path
later and just default to @timestamp
if it's not specified.
} else { | ||
mappingPath = "properties." + fieldPath.replace(".", ".properties."); | ||
if (timestampFieldName.equals(fieldMapper.getPath()) == false) { | ||
throw new IllegalArgumentException("[_timestamp] meta field doesn't point to data stream timestamp field [" + |
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 error will be hard for end users to understand, since they shouldn't be aware of the _timestamp
field. Maybe we won't even need this check, once we remove the ability to set timestamp_field
, as discussed in #59317 (comment)?
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.
This is more of a sanity check. Kind of ensuring that we did apply the _data_stream_timestamp
meta field mapper. If a user would run into this error then this would be a bug. Can tweak this check.
…led' option and adjusted exception messages. Relates to elastic#59076
…led' option Backport elastic#59503 to 7.x and adjusted exception messages. Relates to elastic#59076
…led' option Backport elastic#59727 to 7.x and adjusted exception messages. Relates to elastic#59076
The commit makes the following changes:
index template can only be set to
@timestamp
.TimestampFieldMapper
andinstead only check that the _timestamp field mapping has been defined on a backing index of a data stream.
MetadataCreateIndexService#applyCreateIndexRequestWithV2Template(...)
methodto
MetadataIndexTemplateService#collectMappings(...)
method.for each template and instead of the final mappings that is created.
Relates to #58642
Relates to #53100
Closes #58956
Closes #58583