Fluent Logger for Python
fluent-logger-python is a Python library used to record events from Python applications to Fluentd or Fluent Bit. It provides both an event-based interface (`FluentSender`) and a standard Python `logging.Handler` (`FluentHandler`) for structured logging. The current version is 0.11.1 and it is actively maintained with regular releases.
Warnings
- breaking Version 0.11.0 dropped official support for Python 3.5 and 3.6. The library now requires Python 3.7 or newer.
- gotcha The `event.Event()` API does not provide a mechanism to check for success or failure of log delivery, unlike directly using `FluentSender.emit()` which returns a boolean.
- breaking In v0.11.0, `FluentSender` introduced a new `forward_packet_error` option. When set to `True` (default behavior in previous versions was to catch), the sender will no longer catch exceptions during event serialization (e.g., if `msgpack` fails), allowing errors to propagate.
- gotcha When using `FluentRecordFormatter`, how Python's `extra` dictionary for log records is processed can be non-obvious. It might either be merged directly into the top-level record or nested under an 'extra' key, potentially leading to unexpected field names or data structure in Fluentd.
- gotcha `FluentSender.setup()` creates a global singleton sender instance. While convenient for simple applications, this can be problematic in complex applications requiring multiple distinct Fluentd connections or different root tags, especially in multi-threaded environments or when testing.
Install
-
pip install fluent-logger
Imports
- FluentSender
from fluent import sender logger = sender.FluentSender('app_tag', host='localhost', port=24224) - FluentHandler
from fluent import handler fluent_handler = handler.FluentHandler('app.tag') - FluentRecordFormatter
from fluent import handler formatter = handler.FluentRecordFormatter({'host': '%(hostname)s', 'where': '%(module)s.%(funcName)s'})
Quickstart
import logging
from fluent import handler
import os
# Configure Fluentd to listen on 0.0.0.0:24224 (default)
# For a quick test, you can run Fluentd with:
# <source>
# @type forward
# port 24224
# bind 0.0.0.0
# </source>
# <match app.**>
# @type stdout
# </match>
# Set up a Python logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.INFO)
# Configure FluentHandler
fluent_host = os.environ.get('FLUENTD_HOST', 'localhost')
fluent_port = int(os.environ.get('FLUENTD_PORT', 24224))
# The tag 'app.follow' will be used in Fluentd configuration to route logs
h = handler.FluentHandler('app.follow', host=fluent_host, port=fluent_port)
# Optional: Configure a formatter for structured logs
# The dictionary keys are the output field names in Fluentd
custom_format = {
'host': '%(hostname)s',
'where': '%(module)s.%(funcName)s',
'type': '%(levelname)s',
'message': '%(message)s',
'stack_trace': '%(exc_text)s'
}
formatter = handler.FluentRecordFormatter(custom_format)
h.setFormatter(formatter)
# Add the FluentHandler to the logger
logger.addHandler(h)
try:
logger.info('This is an info message from Python!', extra={'user_id': 123, 'action': 'login'})
raise ValueError("Something went wrong here!")
except ValueError as e:
logger.error('An error occurred.', exc_info=True, extra={'error_code': 500})
print(f"Logs sent to Fluentd at {fluent_host}:{fluent_port} with tag 'app.follow'")
print("Check your Fluentd/Fluent Bit output.")