Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
b2576b8
lib: cmetrics: preserve typed OTLP metadata in msgpack
edsiper Oct 16, 2026
f5f2160
lib: ctraces: preserve unknown span kinds
edsiper Oct 16, 2026
e2fd81b
mp: add record pooling and a log record scanner
edsiper Oct 16, 2026
a3465dd
log_event_decoder: reuse the unpack zone between records
edsiper Oct 16, 2026
3d8bdba
json: render mutable values with a heap stack
edsiper Oct 16, 2026
b5aa52e
processor: carry record counts and reset encoder on failure
edsiper Oct 16, 2026
56146e5
output: use the serialized trace size for processed chunks
edsiper Oct 16, 2026
85d7fbe
input_log: forward exact record counts to processors
edsiper Oct 16, 2026
44ff488
opentelemetry: preserve typed OTLP values
edsiper Oct 16, 2026
ddff18c
out_opentelemetry: export event name and dropped attributes count
edsiper Oct 16, 2026
633ad1c
processor_labels: keep the complete sample on static conversion
edsiper Oct 16, 2026
a2a3031
processor_opentelemetry_envelope: fix envelope list insertion
edsiper Oct 16, 2026
07914b0
processor_fts: add Fluent Typed Scripting processor
edsiper Oct 16, 2026
ae98413
tests: internal: mp: cover record pooling and the log scanner
edsiper Oct 16, 2026
1e345d3
tests: internal: processor: cover metrics failure output
edsiper Oct 16, 2026
056a7bb
tests: internal: opentelemetry: cover typed values and series merge
edsiper Oct 16, 2026
dd6b22f
tests: internal: fts: add processor tests
edsiper Oct 16, 2026
156959c
tests: integration: add processor_fts scenarios
edsiper Oct 16, 2026
57882e6
lib: cfl: pack arena objects and refine string classes
edsiper Oct 17, 2026
3972cce
mp: add log windows and appending chunk encoding
edsiper Oct 17, 2026
b7bf5ec
processor: process large log buffers in windows
edsiper Oct 17, 2026
377dcee
processor_fts: enable windowed log processing
edsiper Oct 17, 2026
2e2161e
processor_content_modifier: enable windowed log processing
edsiper Oct 17, 2026
0055b7f
tests: internal: mp: cover log windows
edsiper Oct 17, 2026
62e69a2
tests: internal: processor: cover windowed log processing
edsiper Oct 17, 2026
8e9e451
tests: integration: cover windowed output processing
edsiper Oct 17, 2026
4350195
mp: drop unused log scanner modes
edsiper Oct 17, 2026
90b63a9
tests: internal: mp: use the record-only log scanner
edsiper Oct 17, 2026
692c9ad
mp: keep end markers in the previous log window
edsiper Oct 17, 2026
9d7fad0
mp: keep group markers that span appends on request
edsiper Oct 17, 2026
54bc2af
tests: internal: mp: cover group normalization and window boundaries
edsiper Oct 17, 2026
aa13360
processor: give each run its own chunk decoder and encoder
edsiper Oct 17, 2026
7c40058
processor: keep only the group boundaries the input already had
edsiper Oct 17, 2026
b584894
processor_fts: keep groups that span appends
edsiper Oct 17, 2026
3c273ef
tests: internal: fts: expect open input groups to stay open
edsiper Oct 17, 2026
5ab7929
processor_fts: compare duplicate context keys by position
edsiper Oct 17, 2026
5c661b4
processor_fts: detect duplicate JSON keys by sorting
edsiper Oct 17, 2026
83a09e6
tests: internal: processor: cover per-run chunk codecs
edsiper Oct 17, 2026
f06af5a
tests: internal: fts: cover split groups, duplicate context keys and …
edsiper Oct 17, 2026
407ac5e
tests: integration: cover groups split across appends
edsiper Oct 17, 2026
6f4970e
lib: cmetrics: keep label attributes for unrepresentable typed values
edsiper Oct 17, 2026
ce21873
processor_fts: copy protobuf keys with the system allocator
edsiper Oct 17, 2026
46f8d90
output: use the serialized size for processed profiles
edsiper Oct 17, 2026
d431238
tests: internal: mp: keep corrupted msgpack counts small
edsiper Oct 17, 2026
c623a95
tests: internal: opentelemetry: fix literal length and Windows build
edsiper Oct 17, 2026
447539c
processor_fts: clear stale stack poisoning after Lua errors in ASan b…
edsiper Oct 17, 2026
fc74ece
output: keep the group boundaries of stored chunks
edsiper Oct 17, 2026
2d37e7e
processor_fts: fail kept families whose name the policy output uses
edsiper Oct 17, 2026
99c7a31
processor_fts: document telemetry value lifetime and output limits
edsiper Oct 17, 2026
faa7d40
lib: cmetrics: keep OTLP metadata readable by older versions
edsiper Oct 17, 2026
550e9bc
lib: ctraces: store unknown span kinds as unspecified
edsiper Oct 17, 2026
9f37c94
opentelemetry: free metric arrays when summary allocation fails
edsiper Oct 17, 2026
e2587de
tests: internal: processor: cover group boundaries of the input
edsiper Oct 17, 2026
cda1fa3
tests: integration: expect unknown span kinds as unspecified when stored
edsiper Oct 17, 2026
e0d9a0e
tests: internal: fts: cover kept metric family name collisions
edsiper Oct 17, 2026
632a9f8
tests: internal: processor: get pthreads from flb_compat.h
edsiper Oct 17, 2026
73c9f65
out_opentelemetry: send every pending log record once
edsiper Oct 17, 2026
32439bb
tests: integration: out_opentelemetry: cover empty trailing groups an…
edsiper Oct 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/plugins_options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ DEFINE_OPTION(FLB_IN_EBPF "Enable Linux eBPF input plugin"
# ==========
DEFINE_OPTION(FLB_PROCESSOR_CONTENT_MODIFIER "Enable content modifier processor" ON)
DEFINE_OPTION(FLB_PROCESSOR_CUMULATIVE_TO_DELTA "Enable cumulative to delta metrics processor" ON)
DEFINE_OPTION(FLB_PROCESSOR_FTS "Enable Fluent Typed Scripting processor" ON)
DEFINE_OPTION(FLB_PROCESSOR_LABELS "Enable metrics label manipulation processor" ON)
DEFINE_OPTION(FLB_PROCESSOR_METRICS_SELECTOR "Enable metrics selector processor" ON)
DEFINE_OPTION(FLB_PROCESSOR_OPENTELEMETRY_ENVELOPE "Enable OpenTelemetry envelope processor" ON)
Expand Down
19 changes: 19 additions & 0 deletions include/fluent-bit/flb_mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,28 @@
#define FLB_MP_ARRAY MSGPACK_OBJECT_ARRAY

int flb_mp_count(const void *data, size_t bytes);

/*
* Count log records without building msgpack objects; allocation-free in
* non-tracking builds. Rejects unsupported or deep shapes, so callers can fall
* back to the event decoder.
*/
int flb_mp_scan_log_records(const void *data, size_t bytes, int *records);
int flb_mp_count_log_records(const void *data, size_t bytes);
int flb_mp_log_window_next(const void *data, size_t bytes, size_t offset,
size_t limit_bytes, int limit_records,
size_t *window_end, int *window_records);
/* group markers that belong to neighbouring appends, see flb_mp_log_group_boundaries() */
#define FLB_MP_GROUPS_KEEP_LEADING_END 1
#define FLB_MP_GROUPS_KEEP_TRAILING_OPEN 2

int flb_mp_log_group_boundaries(const void *data, size_t bytes);
int flb_mp_log_group_starts(const void *data, size_t bytes);
int flb_mp_normalize_log_buffer_groups_msgpack(const void *in_buf, size_t in_size,
char **out_buf, size_t *out_size);
int flb_mp_normalize_log_buffer_groups_msgpack_ex(const void *in_buf, size_t in_size,
char **out_buf, size_t *out_size,
int flags);
int flb_mp_normalize_log_buffer_groups(const void *in_buf, size_t in_size,
char **out_buf, size_t *out_size);
int flb_mp_count_remaining(const void *data, size_t bytes, size_t *remaining_bytes);
Expand Down
21 changes: 21 additions & 0 deletions include/fluent-bit/flb_mp_chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

/* Forward declaration to avoid circular dependencies */
struct flb_condition;
struct flb_mp_record_block;

struct flb_mp_chunk_record {
int modified;
Expand All @@ -41,6 +42,9 @@ struct flb_mp_chunk_record {
int owns_group_metadata;
int owns_group_attributes;
struct cfl_list _head;

/* Pool block holding this record, NULL when allocated individually. */
struct flb_mp_record_block *storage_block;
};

struct flb_mp_chunk_cobj {
Expand All @@ -56,6 +60,15 @@ struct flb_mp_chunk_cobj {

/* Condition for filtering records during processing */
struct flb_condition *condition;

/* Opt-in, bounded native value storage for the final serialization stage. */
struct cfl_arena *value_pool;
size_t value_pool_bytes;

/* Reference-counted wrapper blocks remain valid when records move. */
int record_pool_enabled;
size_t record_pool_blocks;
struct flb_mp_record_block *record_pool;
};


Expand All @@ -70,9 +83,17 @@ struct flb_mp_chunk_cobj *flb_mp_chunk_cobj_create(struct flb_log_event_encoder
struct flb_log_event_decoder *log_decoder);
int flb_mp_chunk_cobj_destroy(struct flb_mp_chunk_cobj *chunk_cobj);

/* Only enable when CFL values will be read and serialized, without mutation by
* a later native processor. The chunk owns the arena until destruction. */
void flb_mp_chunk_cobj_value_pool_enable(struct flb_mp_chunk_cobj *chunk_cobj);
struct cfl_arena *flb_mp_chunk_cobj_value_pool_get(struct flb_mp_chunk_cobj *chunk_cobj,
size_t estimated_bytes);

int flb_mp_chunk_cobj_encode_append(struct flb_mp_chunk_cobj *chunk_cobj);
int flb_mp_chunk_cobj_encode(struct flb_mp_chunk_cobj *chunk_cobj, char **out_buf, size_t *out_size);
int flb_mp_chunk_cobj_count_log_records(struct flb_mp_chunk_cobj *chunk_cobj);
int flb_mp_chunk_cobj_normalize_groups(struct flb_mp_chunk_cobj *chunk_cobj);
int flb_mp_chunk_cobj_normalize_groups_ex(struct flb_mp_chunk_cobj *chunk_cobj, int flags);



Expand Down
11 changes: 8 additions & 3 deletions include/fluent-bit/flb_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -902,9 +902,10 @@ struct flb_output_flush *flb_output_flush_create(struct flb_task *task,
normalized_buf = NULL;
normalized_size = 0;

ret = flb_mp_normalize_log_buffer_groups_msgpack(p_buf, p_size,
&normalized_buf,
&normalized_size);
/* keep only the group markers that span chunks in the stored data */
ret = flb_mp_normalize_log_buffer_groups_msgpack_ex(
p_buf, p_size, &normalized_buf, &normalized_size,
flb_mp_log_group_boundaries(evc->data, evc->size));
if (ret == 0) {
if (p_buf != evc->data) {
flb_free(p_buf);
Expand Down Expand Up @@ -1151,6 +1152,8 @@ struct flb_output_flush *flb_output_flush_create(struct flb_task *task,
return NULL;
}

/* Capacity can exceed the serialized trace bytes after processing. */
p_size = serialization_buffer_offset;
out_flush->processed_event_chunk = flb_event_chunk_create(
evc->type,
0,
Expand Down Expand Up @@ -1251,6 +1254,8 @@ struct flb_output_flush *flb_output_flush_create(struct flb_task *task,
return NULL;
}

/* Capacity can exceed the serialized profile bytes after processing. */
p_size = serialization_buffer_offset;
out_flush->processed_event_chunk = flb_event_chunk_create(
evc->type,
0,
Expand Down
17 changes: 16 additions & 1 deletion include/fluent-bit/flb_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@
#define FLB_PROCESSOR_UNIT_NATIVE 0
#define FLB_PROCESSOR_UNIT_FILTER 1

/*
* Plugin flags
*
* FLB_PROCESSOR_FLAG_LOG_WINDOWS: the logs callback only depends on each
* record and its group, so the processor chain can run it over large buffers
* in group aligned windows.
*/
#define FLB_PROCESSOR_FLAG_LOG_WINDOWS 1


/* The current values mean the processor stack will
* wait for 2 seconds at most in 50 millisecond increments
Expand Down Expand Up @@ -148,7 +157,7 @@ struct flb_processor {
};

struct flb_processor_plugin {
int flags; /* Flags (not available at the moment */
int flags; /* FLB_PROCESSOR_FLAG_* capabilities */
char *name; /* Processor short name */
char *description; /* Description */

Expand Down Expand Up @@ -240,6 +249,12 @@ int flb_processor_run(struct flb_processor *proc,
void **out_buf, size_t *out_size);


/* Carry known logical log counts through the pipeline. -1 means unknown. */
int flb_processor_run_with_count(struct flb_processor *proc, size_t starting_stage, int type,
const char *tag, size_t tag_len, void *data, size_t data_size,
void **out_buf, size_t *out_size,
int input_records, int *output_records);

struct flb_processor_unit *flb_processor_unit_create(struct flb_processor *proc,
int event_type,
char *unit_name);
Expand Down
15 changes: 13 additions & 2 deletions lib/cfl/ARENA.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,19 @@ Setting the limit to zero disables external-buffer caching. Reducing the limit
immediately trims the cache. A larger limit can improve throughput for repeated
large payloads but may increase retained memory and RSS.

The arena also maintains size classes for commonly-sized owned SDS values.
Callers do not need to select a class.
The arena also maintains size classes for owned SDS values up to 1 KiB.
Callers do not need to select a class. Classes below 128 bytes grow in
alignment-sized steps of the complete allocation, so short strings such as map
keys use at most one alignment unit more than they need; larger classes grow
by about 25 percent. A released string is recycled for the next string of the
same class. `cfl_sds_alloc()` reports the class capacity, which can exceed the
requested length.

Variants, kvpairs, key/value lists, arrays, and SDS headers are aligned for the
pointers, sizes, 64-bit integers, and doubles they contain. This can be less
strict than the raw allocation alignment, which also covers `long double`, so
CFL objects pack more densely in arena chunks. Raw allocations keep the public
alignment guarantee.

## Memory statistics

Expand Down
9 changes: 9 additions & 0 deletions lib/cfl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ This file records the notable changes in each CFL release.

- Added public request-lifetime arena allocation, duplication helpers,
allocator callbacks, and optional bounded geometric chunk growth.
- Reduced arena memory for CFL object graphs: objects use their natural
alignment instead of the raw allocation alignment, and owned SDS strings use
finer size classes. Decoded log records use 27 to 31 percent less arena
memory. Owned SDS blocks are no longer zeroed before initialization.
- Added a bump-allocation fast path for the current arena chunk.
- Fixed the alignment of external arena allocations, which returned storage
at a misaligned offset for large owned SDS strings.
- Added the `cfl-benchmark-arena-records` benchmark for decoded record
batches.

## 1.0.0 - 2026-07-11

Expand Down
3 changes: 3 additions & 0 deletions lib/cfl/benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ target_link_libraries(cfl-benchmark-variant-arena cfl-static)

add_executable(cfl-benchmark-variant-mutable variant_mutable.c)
target_link_libraries(cfl-benchmark-variant-mutable cfl-static)

add_executable(cfl-benchmark-arena-records records.c)
target_link_libraries(cfl-benchmark-arena-records cfl-static)
17 changes: 17 additions & 0 deletions lib/cfl/benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,20 @@ document is still alive. Compare them with `arena_initial_used` and
`arena_used`. `max_rss_kb` is process-level high-water RSS and can remain the
same for small workloads because it is page-granular and includes executable,
library, and allocator-retained pages.

## Decoded record batches

The records benchmark builds batches of small log records, each with short
keys, a nested map, an array, and string, integer, and double values, as
produced by decoding a buffer of telemetry records. Arena batches are reset
between iterations; heap batches destroy every record:

```sh
build-bench/benchmarks/cfl-benchmark-arena-records arena 512 3000
build-bench/benchmarks/cfl-benchmark-arena-records heap 512 3000
```

Optional arguments select `referenced` or `owned` values, enable record edits
(`1` removes, inserts, and renames keys), and set the arena chunk size. The
tool reports nanoseconds per record and, for arenas, used and reserved bytes
per record.
Loading
Loading