Repository navigation
input: fix threaded input conditional routing for logs #11783
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
Changes from 4 commits
4e6ae9f
bd30053
9b7cfd1
4915f8e
361eed7
1326f37
41e500d
22086e7
e1828b9
31e77e1
c0fb084
04510b6
514cad5
8f861df
83b1710
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -980,7 +980,8 @@ static int split_and_append_route_payloads(struct flb_input_instance *ins, | |
| const char *tag, | ||
| size_t tag_len, | ||
| const void *buf, | ||
| size_t buf_size) | ||
| size_t buf_size, | ||
| int local_append) | ||
| { | ||
| int ret; | ||
| int appended; | ||
|
|
@@ -1018,13 +1019,6 @@ static int split_and_append_route_payloads(struct flb_input_instance *ins, | |
| return 0; | ||
| } | ||
|
|
||
| /* Conditional routing not supported for threaded inputs */ | ||
| if (flb_input_is_threaded(ins)) { | ||
| flb_plg_warn(ins, "conditional routing not supported for threaded inputs, " | ||
| "falling back to normal routing"); | ||
| return 0; | ||
| } | ||
|
|
||
| cfl_list_init(&payloads); | ||
| cfl_list_foreach(head, &ins->routes_direct) { | ||
| route_path = cfl_list_entry(head, struct flb_router_path, _head); | ||
|
|
@@ -1249,13 +1243,24 @@ static int split_and_append_route_payloads(struct flb_input_instance *ins, | |
| continue; | ||
| } | ||
|
|
||
| ret = flb_input_chunk_append_raw(ins, | ||
| FLB_INPUT_LOGS, | ||
| payload->total_records, | ||
| payload->tag, | ||
| flb_sds_len(payload->tag), | ||
| payload->data, | ||
| payload->size); | ||
| if (local_append == FLB_TRUE) { | ||
| ret = flb_input_chunk_append_raw_local(ins, | ||
| FLB_INPUT_LOGS, | ||
| payload->total_records, | ||
| payload->tag, | ||
| flb_sds_len(payload->tag), | ||
| payload->data, | ||
| payload->size); | ||
| } | ||
| else { | ||
| ret = flb_input_chunk_append_raw(ins, | ||
| FLB_INPUT_LOGS, | ||
| payload->total_records, | ||
| payload->tag, | ||
| flb_sds_len(payload->tag), | ||
| payload->data, | ||
| payload->size); | ||
| } | ||
| if (ret != 0) { | ||
| flb_router_chunk_context_destroy(&context); | ||
| route_payload_list_destroy(&payloads); | ||
|
|
@@ -1305,56 +1310,20 @@ static int split_and_append_route_payloads(struct flb_input_instance *ins, | |
| return 0; | ||
| } | ||
|
|
||
| static int input_log_append(struct flb_input_instance *ins, | ||
| size_t processor_starting_stage, | ||
| size_t records, | ||
| const char *tag, size_t tag_len, | ||
| const void *buf, size_t buf_size) | ||
| static int input_log_append_processed_internal(struct flb_input_instance *ins, | ||
| size_t records, | ||
| const char *tag, size_t tag_len, | ||
| const void *buf, size_t buf_size, | ||
| int local_append) | ||
| { | ||
| int ret; | ||
| int conditional_result; | ||
| int conditional_handled = FLB_FALSE; | ||
| int processor_is_active; | ||
| void *out_buf = (void *) buf; | ||
| size_t dummy = 0; | ||
| size_t out_size = buf_size; | ||
| const char *base_tag = tag; | ||
| size_t base_tag_len = tag_len; | ||
| struct flb_input_chunk *chunk = NULL; | ||
|
|
||
| processor_is_active = flb_processor_is_active(ins->processor); | ||
| if (processor_is_active) { | ||
| if (!tag) { | ||
| if (ins->tag && ins->tag_len > 0) { | ||
| tag = ins->tag; | ||
| tag_len = ins->tag_len; | ||
| } | ||
| else { | ||
| tag = ins->name; | ||
| tag_len = strlen(ins->name); | ||
| } | ||
| } | ||
|
|
||
| ret = flb_processor_run(ins->processor, | ||
| processor_starting_stage, | ||
| FLB_PROCESSOR_LOGS, | ||
| tag, tag_len, | ||
| (char *) buf, buf_size, | ||
| &out_buf, &out_size); | ||
| if (ret == -1) { | ||
| return -1; | ||
| } | ||
|
|
||
| if (out_size == 0) { | ||
| return 0; | ||
| } | ||
|
|
||
| if (buf != out_buf) { | ||
| /* a new buffer was created, re-count the number of records */ | ||
| records = flb_mp_count_log_records(out_buf, out_size); | ||
| } | ||
| } | ||
|
|
||
| if (!base_tag) { | ||
| if (ins->tag && ins->tag_len > 0) { | ||
| base_tag = ins->tag; | ||
|
|
@@ -1370,11 +1339,9 @@ static int input_log_append(struct flb_input_instance *ins, | |
| } | ||
|
|
||
| conditional_result = split_and_append_route_payloads(ins, records, tag, tag_len, | ||
| out_buf, out_size); | ||
| buf, buf_size, | ||
| local_append); | ||
| if (conditional_result < 0) { | ||
| if (processor_is_active && buf != out_buf) { | ||
| flb_free(out_buf); | ||
| } | ||
| return -1; | ||
| } | ||
|
|
||
|
|
@@ -1387,8 +1354,14 @@ static int input_log_append(struct flb_input_instance *ins, | |
| * receive data even when conditional routes exist. The conditional routing | ||
| * should be additive, not exclusive. | ||
| */ | ||
| ret = flb_input_chunk_append_raw(ins, FLB_INPUT_LOGS, records, | ||
| tag, tag_len, out_buf, out_size); | ||
| if (local_append == FLB_TRUE) { | ||
| ret = flb_input_chunk_append_raw_local(ins, FLB_INPUT_LOGS, records, | ||
| tag, tag_len, buf, buf_size); | ||
| } | ||
| else { | ||
| ret = flb_input_chunk_append_raw(ins, FLB_INPUT_LOGS, records, | ||
| tag, tag_len, buf, buf_size); | ||
| } | ||
|
|
||
| if (ret == 0 && conditional_handled == FLB_TRUE && base_tag) { | ||
| chunk = NULL; | ||
|
|
@@ -1403,9 +1376,75 @@ static int input_log_append(struct flb_input_instance *ins, | |
| } | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| static int input_log_append(struct flb_input_instance *ins, | ||
| size_t processor_starting_stage, | ||
| size_t records, | ||
| const char *tag, size_t tag_len, | ||
| const void *buf, size_t buf_size) | ||
| { | ||
| int ret; | ||
| int processor_is_active; | ||
| void *out_buf = (void *) buf; | ||
| size_t out_size = buf_size; | ||
|
|
||
| processor_is_active = flb_processor_is_active(ins->processor); | ||
| if (processor_is_active) { | ||
| if (!tag) { | ||
| if (ins->tag && ins->tag_len > 0) { | ||
| tag = ins->tag; | ||
| tag_len = ins->tag_len; | ||
| } | ||
| else { | ||
| tag = ins->name; | ||
| tag_len = strlen(ins->name); | ||
| } | ||
| } | ||
|
|
||
| ret = flb_processor_run(ins->processor, | ||
| processor_starting_stage, | ||
| FLB_PROCESSOR_LOGS, | ||
| tag, tag_len, | ||
| (char *) buf, buf_size, | ||
| &out_buf, &out_size); | ||
| if (ret == -1) { | ||
| return -1; | ||
| } | ||
|
|
||
| if (out_size == 0) { | ||
| if (buf != out_buf) { | ||
| flb_free(out_buf); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| if (buf != out_buf) { | ||
| /* a new buffer was created, re-count the number of records */ | ||
| records = flb_mp_count_log_records(out_buf, out_size); | ||
| } | ||
| } | ||
|
|
||
| if (flb_input_is_threaded(ins) == FLB_TRUE && | ||
| input_has_conditional_routes(ins) == FLB_TRUE) { | ||
| ret = flb_input_chunk_ring_buffer_enqueue_log_routing(ins, | ||
| FLB_INPUT_LOGS, | ||
| records, | ||
| tag, tag_len, | ||
| out_buf, out_size); | ||
| } | ||
|
Comment on lines
+1585
to
+1592
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.
🤖 Prompt for AI Agents |
||
| else { | ||
| ret = input_log_append_processed_internal(ins, records, | ||
| tag, tag_len, | ||
| out_buf, out_size, | ||
| FLB_FALSE); | ||
| } | ||
|
|
||
| if (processor_is_active && buf != out_buf) { | ||
| flb_free(out_buf); | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
|
|
@@ -1422,6 +1461,23 @@ int flb_input_log_append(struct flb_input_instance *ins, | |
| return ret; | ||
| } | ||
|
|
||
| int flb_input_log_append_processed(struct flb_input_instance *ins, | ||
| size_t records, | ||
| const char *tag, | ||
| size_t tag_len, | ||
| const void *buf, | ||
| size_t buf_size) | ||
| { | ||
| if (records == 0) { | ||
| records = flb_mp_count_log_records(buf, buf_size); | ||
| } | ||
|
|
||
| return input_log_append_processed_internal(ins, records, | ||
| tag, tag_len, | ||
| buf, buf_size, | ||
| FLB_TRUE); | ||
| } | ||
|
|
||
| /* Take a msgpack serialized record and enqueue it as a chunk */ | ||
| int flb_input_log_append_skip_processor_stages(struct flb_input_instance *ins, | ||
| size_t processor_starting_stage, | ||
|
|
@@ -1450,4 +1506,3 @@ int flb_input_log_append_records(struct flb_input_instance *ins, | |
| ret = input_log_append(ins, 0, records, tag, tag_len, buf, buf_size); | ||
| return ret; | ||
| } | ||
|
|
||
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.
Handle append failures in ring-buffer collector to avoid silent data loss.
The collector discards
crregardless of append result. If append fails, dequeued records are lost without explicit failure handling.🛠️ Suggested fix
void flb_input_chunk_ring_buffer_collector(struct flb_config *ctx, void *data) { int ret; + int append_ret; int tag_len = 0; @@ - if (cr->event_type == FLB_INPUT_LOGS && - (cr->flags & FLB_INPUT_CHUNK_RAW_LOG_ROUTING) != 0) { - flb_input_log_append_processed(cr->ins, cr->records, - cr->tag, tag_len, - cr->buf_data, cr->buf_size); - } - else { - input_chunk_append_raw(cr->ins, cr->event_type, cr->records, - cr->tag, tag_len, - cr->buf_data, cr->buf_size); - } + if (cr->event_type == FLB_INPUT_LOGS && + (cr->flags & FLB_INPUT_CHUNK_RAW_LOG_ROUTING) != 0) { + append_ret = flb_input_log_append_processed(cr->ins, cr->records, + cr->tag, tag_len, + cr->buf_data, cr->buf_size); + } + else { + append_ret = input_chunk_append_raw(cr->ins, cr->event_type, cr->records, + cr->tag, tag_len, + cr->buf_data, cr->buf_size); + } + + if (append_ret != 0) { + flb_plg_error(ins, "failed to append dequeued ring-buffer payload"); + } destroy_chunk_raw(cr);🤖 Prompt for AI Agents