Use when writing or editing FluentBit configs (YAML/conf), Lua filters for FluentBit, FluentBit CI pipelines, or testing Lua filters with FluentBit. Also use when debugging FluentBit Lua filter behavior, return codes, or field mapping issues.
FluentBit Lua filter development, testing, and CI patterns. Lua 5.1/LuaJIT semantics.
Every FluentBit Lua filter needs at minimum a cb_filter function:
function cb_filter(tag, timestamp, record)
-- record is a Lua table (flat key-value pairs)
-- Modify record as needed
record["new_field"] = "value"
-- Return: code, timestamp, record
return 1, timestamp, record
end
| Code | Meaning | When to use |
|---|---|---|
| 0 | Keep record unchanged | No modifications needed |
| 1 |
| Record modified, use new record |
| Standard enrichment path |
| 2 | Drop record entirely | Filtering out unwanted records |
-- Called once when FluentBit loads the filter (optional)
function cb_init()
-- Load lookup tables, parse JSON files, initialize state
return 0 -- 0 = success
end
-- Called on FluentBit shutdown (optional, rarely needed)
function cb_exit()
end
This is the most dangerous mistake when writing FluentBit Lua filters.
FluentBit records use flat dot-notation strings as keys. These are NOT nested Lua tables - the dot is part of the key string.
-- CORRECT: Flat key (how Elasticsearch/FluentBit works)
record["calling_party.vorwahl"] = "49221"
record["calling_party.ortsnetzname"] = "Köln"
-- WRONG: Nested table (looks right, breaks everything)
record["calling_party"] = { vorwahl = "49221", ortsnetzname = "Köln" }
-- This creates ONE key "calling_party" with a table value,
-- NOT two flat keys. Elasticsearch will reject or mismap this.
Why this happens: LLMs see calling_party.vorwahl and infer an object path (correct in JavaScript, Python dicts). In FluentBit/Elasticsearch, the dot is literal.
How to catch it: Assert against the exact flat key strings in tests. If record["calling_party.vorwahl"] is nil but the filter "worked", it probably created a nested table instead.