ECS Logging for Python
ecs-logging-python provides logging formatters for Python's standard `logging` module and `structlog`, enabling applications to produce logs compliant with the Elastic Common Schema (ECS). It helps in standardizing log formats for easier ingestion and analysis in Elastic Stack products like Elasticsearch and Kibana. The library is currently at version 2.3.0 and is actively maintained, with a focus on adding new features and supporting recent Python versions.
Warnings
- breaking Python 2 support was removed in version 2.0.0. Ensure your projects are running on Python 3.
- breaking Python 3.5 support was removed in version 1.1.0.
- gotcha When using `StdlibFormatter`, additional ECS fields must be passed via the `extra` dictionary argument to logging calls. Keys with dot notation (e.g., `user.name`) will automatically be de-dotted and nested in the output JSON.
- gotcha If using `structlog`, the `ecs_logging.StructlogFormatter` must be the *last* processor in your `structlog.configure` processor list, as it handles the final JSON conversion and ECS field enrichment.
- gotcha The `ensure_ascii` parameter for `StdlibFormatter` and `StructlogFormatter` (introduced in v2.3.0) controls whether non-ASCII characters in log messages are escaped to `\uXXXX` sequences. It defaults to `True`.
- gotcha Prior to v1.0.2, `StdlibFormatter` had a signature mismatch with `logging.Formatter` that could cause issues in frameworks like Django and Gunicorn.
Install
-
pip install ecs-logging
Imports
- StdlibFormatter
from ecs_logging import StdlibFormatter
- StructlogFormatter
from ecs_logging import StructlogFormatter
Quickstart
import logging
import ecs_logging
import sys
# Get the Logger
logger = logging.getLogger('app')
logger.setLevel(logging.DEBUG)
# Add an ECS formatter to the Handler
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(ecs_logging.StdlibFormatter())
logger.addHandler(handler)
# Emit a log!
logger.debug('Example message!', extra={'http.request.method': 'get', 'user.name': 'john.doe'})
try:
1 / 0
except ZeroDivisionError:
logger.error('An error occurred!', exc_info=True)