5. THE BASICS
THE BASICS
import logging
logger = logging.getLogger(__name__)
user = "cooper"
town = "Twin Peaks"
logger.info("%s entering %s", user, town,
extra={"user": {"name": user}})
6
6. Automatic Extra Data
Automatic Extra Data
log = LoggerAdapter(
logger, extra={"user": {"name": user}}
)
logger.info("%s entering %s", user, town)
7
7. Global Extra Data
Global Extra Data
# utils/logs.py
local = threading.local()
def set_user(user: dict) -> None:
local.user = user
class ExtraDataFilter(logging.Filter):
"""
Adds global extra data to all log records
"""
def filter(self, record):
if user := getattr(local, "user", None):
record.user = user
8
10. BEST PRACTISES
BEST PRACTISES
Be careful of Sensitive Information
Log relevant events *
Consider the reader. *
Let the logging library construct the message *
11
12. BEST PRACTISES
BEST PRACTISES
LOG RELEVANT EVENTS
LOG RELEVANT EVENTS
Log on changes
Log on strangeness
Business events and decisions
Network calls
Decision rationale
HTTP world: POST PUT DELETE.
HTTP world: POST PUT DELETE.
13
14. BEST PRACTISES
BEST PRACTISES
CONSIDER THE READER
CONSIDER THE READER
Logs are read in multitues.
Logs are read in multitues.
Keep them Short.
Keep them Self-contained.
Keep them Consistent.
Add the necessary data.
15
15. BEST PRACTISES
BEST PRACTISES
FORMATTING
FORMATTING
Do let the logging library construct the message.
Do let the logging library construct the message.
Do use time in seconds, unless otherwise specified.
Do use time in seconds, unless otherwise specified.
logger.info("%s entering %s", user, town)
16
16. BEST PRACTISES
BEST PRACTISES
FORMATTING
FORMATTING
Do add global contextual information, e.g. tracing IDs.
Do add global contextual information, e.g. tracing IDs.
Do rename and filter the default
Do rename and filter the default extra
extra data for
data for
better readability.
better readability.
Do define your
Do define your extra
extra schema,
schema,
with
with !
!
Elastic Common Schema
Elastic Common Schema
17