Repository navigation
Conversation
opensearch_data_stream accepts the pipeline parameter from the regular output but never sends it, so records skip the configured ingest pipeline without any warning. Add it to the bulk request, with the chunk placeholders filled in as the regular output does. Signed-off-by: Lucas Barros <lucasbarros.kam@gmail.com>
Watson1978
left a comment
There was a problem hiding this comment.
Thanks for the fix. I checked it with OpenSearch 3.9.0. A pipeline given on the _bulk request is applied to the data stream, and the ${tag} placeholder works too.
Two changes are needed before merging. Details are in the inline comments.
- Do not send the pipeline parameter when the expanded value is empty. OpenSearch rejects
?pipeline=for the whole request. - Expand the pipeline at the top of
write, before the records are processed.
OpenSearch rejects the whole bulk request for ?pipeline=, so do not send the parameter when the pipeline is empty or its placeholders expand to an empty string. Expand the pipeline at the top of write, so a chunk whose pipeline cannot be built fails before any record is sent to @error. Co-authored-by: Shizuo Fujita <fujita@clear-code.com> Signed-off-by: Lucas Barros <lucasbarros.kam@gmail.com>
Watson1978
left a comment
There was a problem hiding this comment.
Thanks for the update. Both requested changes are implemented in 81d86dc. Empty pipeline values are no longer sent, and the three new tests fail on 1cef9dd and pass now.
However, my second request introduced a regression, and I am sorry about that. When the pipeline cannot be built, a chunk with only invalid records no longer reaches @ERROR. Details, a possible fix, and tests are in the inline comment.
| def write(chunk) | ||
| data_stream_name = @data_stream_name | ||
| data_stream_template_name = @data_stream_template_name | ||
| pipeline = extract_placeholders(@pipeline, chunk) if @pipeline |
There was a problem hiding this comment.
MUST: My earlier request in #205 (comment) caused a regression here.
Use pipeline pipe-${tag} and id_key req_id. Use <buffer tag> and the tag /badtag. Keep emit_error_label_event at its default, and use no secondary output. Feed one record whose req_id is an array.
On main and on 1cef9dd, the record goes to @ERROR. On 81d86dc, the expansion fails before the record is checked, so the record does not reach @ERROR. Fluentd backs up the chunk instead, or drops it with disable_chunk_backup true.
Please keep both of these:
- A chunk with only invalid records sends them to
@ERROR, as onmain. - When the pipeline cannot be built, a chunk with both invalid and valid records does not send the invalid records to
@ERROR. The whole chunk is backed up instead, as in 81d86dc.
One way is to collect the invalid records in the loop, and send them to @ERROR after the pipeline is expanded. Expand the pipeline only when records is not empty. Do not check bulk_message here. When a record fails to serialize, its action line is already in bulk_message.
records = []
invalid_records = []
chunk.msgpack_each do |time, record|
# ...
rescue => e
invalid_records << [time, record, e]
end
end
pipeline = extract_placeholders(@pipeline, chunk) if @pipeline && !records.empty?
if emit_error_label_event?
invalid_records.each { |time, record, e| router.emit_error_event(tag, time, record, e) }
end
return if bulk_message.to_s.empty?Remove the expansion at the top of write (this line). Keep the params[:pipeline] line as it is.
Please replace test_pipeline_is_expanded_before_records_are_processed with two tests. Both use its configuration (pipeline pipe-${tag}, id_key req_id, <buffer tag> with disable_chunk_backup true, the tag /badtag), and assert that no bulk request is made.
- Feed one record whose
req_idis an array.driver.error_eventshas one event. - Feed the same record and one valid record.
driver.error_eventsis empty.
…pipeline Expanding the pipeline at the top of write kept a chunk with only invalid records from reaching @error. Collect the invalid records, expand the pipeline only when there are valid ones, and then send the invalid records to @error. When the pipeline cannot be built, a mixed chunk is still backed up as a whole. Signed-off-by: Lucas Barros <lucasbarros.kam@gmail.com>
|
No problem, thanks for the follow-up. Pushed 6aeed9c:
|
|
The Ruby 3.1 jobs on macOS and Windows fail in the new test The other jobs pass. The test expects Could you make this test pass with Fluentd versions before 1.19.3 too? For example, skip it there, or make the expansion fail in a way that does not depend on that check. The change in |
opensearch_data_streaminherits thepipelineparameter fromopensearch, but itswritebuilds the bulk request with onlyindexandbody, so the parameter is ignored and records skip the ingest pipeline with no warning. OpenSearch applies an ingest pipeline given on a_bulkrequest to data streams too, so nothing on the server side stops this from working.This change adds
pipelineto the bulk parameters and fills in chunk placeholders (pipeline-${tag}) after the records are checked and before any invalid record is sent to@ERROR. It is only expanded when the chunk has a valid record. Ifpipelineis not set, or it is empty after expansion (OpenSearch rejects?pipeline=for the whole request), the request is unchanged. A shortpipelineentry was added to the Data Stream section of the README, like theid_keyone added in #200.Tests added to
test/plugin/test_out_opensearch_data_stream.rb:test_record_with_pipeline, with a fixed value and a${tag}placeholder. The bulk request must carry?pipeline=mypipelineor?pipeline=pipeline-test. Both fail onmainbecause the request goes out without the query parameter.test_record_with_empty_pipelineandtest_record_with_pipeline_placeholder_expanded_to_empty: nopipelinequery parameter is sent.test_invalid_records_go_to_error_when_pipeline_cannot_be_builtandtest_chunk_with_valid_records_is_not_sent_to_error_when_pipeline_cannot_be_built: with a tag that cannot be used in a placeholder, a chunk with only an invalid record sends it to@ERROR, a chunk with an invalid and a valid record sends nothing to@ERROR, and no bulk request is made in either case.bundle exec rake test: 466 tests, 0 failures, 0 errors.(check all that apply)
versionin gemspec are untouched