Fluent Bit can grab Windows Event Log entries, but it treats them like any other log stream, which is usually not what you want.
Let’s see it in action. Imagine you want to track every time a user logs into a specific server.
[SERVICE]
Flush 1
Daemon off
Log_Level info
Parsers_File parsers.conf
[INPUT]
Name winlog
Tag winlog.security
Channels Security
Interval 1000
[OUTPUT]
Name es
Match winlog.security
Host localhost
Port 9200
Logstash_Format On
Replace_Dots On
Retry_Limit False
This config tells Fluent Bit to:
- Run in the foreground (
Daemon off) with a 1-second flush interval. - Use
parsers.conf(which we’ll define later) to make sense of the logs. - Listen to the
Securitychannel of the Windows Event Log (Name winlog,Channels Security). - Tag these entries with
winlog.security. - Send any
winlog.securitytagged logs to Elasticsearch onlocalhost:9200using the Logstash format.
Now, how do we make sense of these raw event logs? They’re not just simple text lines. They are structured data with fields like EventID, UserID, ComputerName, etc. This is where parsers come in.
Create a parsers.conf file in the same directory as your Fluent Bit configuration:
[PARSER]
Name winlog
Format kv
Regex ^(?<message>.*)$
Delimiter " "
Key_Value_Separator ":"
Trim_Key " "
Trim_Value " "
This parser is too simple for Windows Event Logs. It just treats the entire log line as a key-value pair, which will result in a single, messy field. The real power comes from Fluent Bit’s built-in winlog parser, which understands the Windows Event Log structure.
A more realistic setup would involve using the winlog parser directly within the INPUT plugin and then potentially another parser for downstream processing.
[SERVICE]
Flush 1
Daemon off
Log_Level info
Parsers_File parsers.conf
[INPUT]
Name winlog
Tag winlog.system
Channels System
Interval 1000
Parser winlog # Use the built-in winlog parser
[FILTER]
Name parser
Match winlog.system
Key_Name message
Parser regex # Example: further parse the message field if needed
Reserve_Data On
[OUTPUT]
Name stdout
Match winlog.system
Here, the INPUT plugin now explicitly uses the winlog parser. This means Fluent Bit will attempt to interpret the raw event log data into structured fields before it even gets to the output.
The FILTER section shows an optional step: if the winlog parser doesn’t give you exactly what you need in the message field, you can use another parser (like a regex parser) to further break it down. Reserve_Data On ensures that the original raw message isn’t discarded.
The OUTPUT is set to stdout for demonstration, so you’ll see the structured output directly in your terminal.
When you run Fluent Bit with this configuration, you’ll see output like this:
[0] winlog.system: [1678886400.123456789, {"EventID"=>"1000", "Level"=>"Information", "ProviderName"=>"Application Error", "ComputerName"=>"MYSERVER", "Message"=>"The application failed to start correctly.", "TaskCategory"=>"Application Hang", "Keyword"=>"Classic", "Opcode"=>"Info", "ProcessID"=>"1234", "ThreadID"=>"5678", "Channel"=>"Application", "RecordNumber"=>"98765", "TimeCreated"=>"2023-03-15 10:00:00 UTC", "ActivityID"=>"{...}"}]
Notice how Fluent Bit has already parsed out key fields like EventID, Level, ProviderName, and Message directly from the Windows Event Log entry. This is the magic of the winlog parser.
The core problem Fluent Bit solves here is bridging the gap between the proprietary Windows Event Log format and standard log aggregation systems. Without it, you’d be trying to parse binary event log files or wrestling with WMI scripts.
The mental model is that Fluent Bit acts as a universal translator. It has specific "language packs" (parsers) for different log sources. For Windows Event Logs, the winlog input plugin and its associated parser understand the Windows Event Log API and translate its structured records into a format Fluent Bit can then process and send elsewhere.
What most people don’t realize is that the winlog input plugin on Windows is not just reading files; it’s actively querying the Windows Event Log API. This means it can tap into real-time event streams and specific event channels (like Security, System, Application) without needing to constantly poll or manage log file rotations. It’s a much more efficient and robust mechanism than trying to tail log files that might not even exist in a traditional sense.
The next step is usually to configure a more robust output plugin like Elasticsearch or Splunk, and then define custom parsers for specific Event IDs you care about.