{"id":2514,"library":"fluent-logger","title":"Fluent Logger for Python","description":"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.","status":"active","version":"0.11.1","language":"en","source_language":"en","source_url":"https://github.com/fluent/fluent-logger-python","tags":["logging","fluentd","fluent-bit","observability","structured-logging"],"install":[{"cmd":"pip install fluent-logger","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for serializing logs into MessagePack format for Fluentd/Fluent Bit communication.","package":"msgpack","optional":false}],"imports":[{"note":"The top-level package for imports is `fluent`, not `fluent_logger` or `fluent-logger`.","wrong":"from fluent_logger import sender","symbol":"FluentSender","correct":"from fluent import sender\nlogger = sender.FluentSender('app_tag', host='localhost', port=24224)"},{"note":"The top-level package for imports is `fluent`, not `fluent_logger` or `fluent-logger`.","wrong":"from fluent_logger import handler","symbol":"FluentHandler","correct":"from fluent import handler\nfluent_handler = handler.FluentHandler('app.tag')"},{"note":"The top-level package for imports is `fluent`, not `fluent_logger` or `fluent-logger`.","wrong":"from fluent_logger import handler","symbol":"FluentRecordFormatter","correct":"from fluent import handler\nformatter = handler.FluentRecordFormatter({'host': '%(hostname)s', 'where': '%(module)s.%(funcName)s'})"}],"quickstart":{"code":"import logging\nfrom fluent import handler\nimport os\n\n# Configure Fluentd to listen on 0.0.0.0:24224 (default)\n# For a quick test, you can run Fluentd with:\n# <source>\n#   @type forward\n#   port 24224\n#   bind 0.0.0.0\n# </source>\n# <match app.**>\n#   @type stdout\n# </match>\n\n# Set up a Python logger\nlogger = logging.getLogger('my_app')\nlogger.setLevel(logging.INFO)\n\n# Configure FluentHandler\nfluent_host = os.environ.get('FLUENTD_HOST', 'localhost')\nfluent_port = int(os.environ.get('FLUENTD_PORT', 24224))\n\n# The tag 'app.follow' will be used in Fluentd configuration to route logs\nh = handler.FluentHandler('app.follow', host=fluent_host, port=fluent_port)\n\n# Optional: Configure a formatter for structured logs\n# The dictionary keys are the output field names in Fluentd\ncustom_format = {\n    'host': '%(hostname)s',\n    'where': '%(module)s.%(funcName)s',\n    'type': '%(levelname)s',\n    'message': '%(message)s',\n    'stack_trace': '%(exc_text)s'\n}\nformatter = handler.FluentRecordFormatter(custom_format)\nh.setFormatter(formatter)\n\n# Add the FluentHandler to the logger\nlogger.addHandler(h)\n\ntry:\n    logger.info('This is an info message from Python!', extra={'user_id': 123, 'action': 'login'})\n    raise ValueError(\"Something went wrong here!\")\nexcept ValueError as e:\n    logger.error('An error occurred.', exc_info=True, extra={'error_code': 500})\n\nprint(f\"Logs sent to Fluentd at {fluent_host}:{fluent_port} with tag 'app.follow'\")\nprint(\"Check your Fluentd/Fluent Bit output.\")","lang":"python","description":"This quickstart demonstrates how to configure the standard Python `logging` module to send structured logs to Fluentd using `FluentHandler` and `FluentRecordFormatter`. It includes capturing extra contextual data and exception tracebacks."},"warnings":[{"fix":"Upgrade your Python environment to 3.7+ before upgrading fluent-logger to v0.11.0 or newer.","message":"Version 0.11.0 dropped official support for Python 3.5 and 3.6. The library now requires Python 3.7 or newer.","severity":"breaking","affected_versions":">=0.11.0"},{"fix":"For critical logging paths requiring delivery confirmation, consider using `fluent.sender.FluentSender` directly and calling its `emit()` method, which returns `True` on success or `False` on error. You can then use `logger.last_error()` to retrieve error details.","message":"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.","severity":"gotcha","affected_versions":"<0.11.1"},{"fix":"If you relied on silent error suppression during serialization, you might need to adjust your error handling logic or explicitly set `forward_packet_error=False` when initializing `FluentSender` or `FluentHandler` (if supported directly). It's generally recommended to handle these exceptions for robustness.","message":"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.","severity":"breaking","affected_versions":">=0.11.0"},{"fix":"Explicitly define all desired fields in your `FluentRecordFormatter`'s `fmt` dictionary. For dynamic `extra` fields, configure `FluentRecordFormatter` with `exclude_attrs` to control which default `LogRecord` attributes are logged, or handle the merging in a custom formatter or `buffer_overflow_handler` if the default behavior is not suitable. Ensure your Fluentd configuration expects the structure sent by the formatter.","message":"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.","severity":"gotcha","affected_versions":"All"},{"fix":"For more control, instantiate `FluentSender` objects directly. `FluentSender` now supports `None` as a root tag, allowing multiple root tags within a single connection. This provides greater flexibility and isolation between loggers.","message":"`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.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}