Skip to content

Commit 10ebdf9

Browse files
chore: deduplicate logging and clean up config (#10592)
* fix: remove redundant loggers + cleanup * style: ruff ruff (logging config) * chore: alphabetize loggers * refactor: modern suppression of DisallowedHost log * style: minor cleanup / comments * fix: roll back accidental commit * fix: django.request at ERROR level * fix: squelch other SuspiciousOperation mail
1 parent e5b037b commit 10ebdf9

File tree

1 file changed

+74
-114
lines changed

1 file changed

+74
-114
lines changed

ietf/settings.py

Lines changed: 74 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright The IETF Trust 2007-2025, All Rights Reserved
1+
# Copyright The IETF Trust 2007-2026, All Rights Reserved
22
# -*- coding: utf-8 -*-
33

44

@@ -13,6 +13,7 @@
1313
import warnings
1414
from hashlib import sha384
1515
from typing import Any, Dict, List, Tuple # pyflakes:ignore
16+
from django.http import UnreadablePostError
1617

1718
# DeprecationWarnings are suppressed by default, enable them
1819
warnings.simplefilter("always", DeprecationWarning)
@@ -236,153 +237,112 @@
236237

237238
FILE_UPLOAD_PERMISSIONS = 0o644
238239

239-
# ------------------------------------------------------------------------
240-
# Django/Python Logging Framework Modifications
241240

242-
# Filter out "Invalid HTTP_HOST" emails
243-
# Based on http://www.tiwoc.de/blog/2013/03/django-prevent-email-notification-on-suspiciousoperation/
244-
from django.core.exceptions import SuspiciousOperation
245-
def skip_suspicious_operations(record):
246-
if record.exc_info:
247-
exc_value = record.exc_info[1]
248-
if isinstance(exc_value, SuspiciousOperation):
249-
return False
250-
return True
241+
#
242+
# Logging config
243+
#
251244

252-
# Filter out UreadablePostError:
253-
from django.http import UnreadablePostError
245+
# Callback to filter out UnreadablePostError:
254246
def skip_unreadable_post(record):
255247
if record.exc_info:
256-
exc_type, exc_value = record.exc_info[:2] # pylint: disable=unused-variable
248+
exc_type, exc_value = record.exc_info[:2] # pylint: disable=unused-variable
257249
if isinstance(exc_value, UnreadablePostError):
258250
return False
259251
return True
260252

261-
# Copied from DEFAULT_LOGGING as of Django 1.10.5 on 22 Feb 2017, and modified
262-
# to incorporate html logging, invalid http_host filtering, and more.
263-
# Changes from the default has comments.
264-
265-
# The Python logging flow is as follows:
266-
# (see https://docs.python.org/2.7/howto/logging.html#logging-flow)
267-
#
268-
# Init: get a Logger: logger = logging.getLogger(name)
269-
#
270-
# Logging call, e.g. logger.error(level, msg, *args, exc_info=(...), extra={...})
271-
# --> Logger (discard if level too low for this logger)
272-
# (create log record from level, msg, args, exc_info, extra)
273-
# --> Filters (discard if any filter attach to logger rejects record)
274-
# --> Handlers (discard if level too low for handler)
275-
# --> Filters (discard if any filter attached to handler rejects record)
276-
# --> Formatter (format log record and emit)
277-
#
278-
279253
LOGGING = {
280-
'version': 1,
281-
'disable_existing_loggers': False,
282-
#
283-
'loggers': {
284-
'django': {
285-
'handlers': ['console', 'mail_admins'],
286-
'level': 'INFO',
287-
},
288-
'django.request': {
289-
'handlers': ['console'],
290-
'level': 'ERROR',
254+
"version": 1,
255+
"disable_existing_loggers": False,
256+
"loggers": {
257+
"celery": {
258+
"handlers": ["console"],
259+
"level": "INFO",
291260
},
292-
'django.server': {
293-
'handlers': ['django.server'],
294-
'level': 'INFO',
261+
"datatracker": {
262+
"handlers": ["console"],
263+
"level": "INFO",
295264
},
296-
'django.security': {
297-
'handlers': ['console', ],
298-
'level': 'INFO',
265+
"django": {
266+
"handlers": ["console", "mail_admins"],
267+
"level": "INFO",
299268
},
300-
'oidc_provider': {
301-
'handlers': ['console', ],
302-
'level': 'DEBUG',
269+
"django.request": {"level": "ERROR"}, # only log 5xx, ignore 4xx
270+
"django.security": {
271+
# SuspiciousOperation errors - log to console only
272+
"handlers": ["console"],
273+
"propagate": False, # no further handling please
303274
},
304-
'datatracker': {
305-
'handlers': ['console'],
306-
'level': 'INFO',
275+
"django.server": {
276+
# Only used by Django's runserver development server
277+
"handlers": ["django.server"],
278+
"level": "INFO",
307279
},
308-
'celery': {
309-
'handlers': ['console'],
310-
'level': 'INFO',
280+
"oidc_provider": {
281+
"handlers": ["console"],
282+
"level": "DEBUG",
311283
},
312284
},
313-
#
314-
# No logger filters
315-
#
316-
'handlers': {
317-
'console': {
318-
'level': 'DEBUG',
319-
'class': 'logging.StreamHandler',
320-
'formatter': 'plain',
285+
"handlers": {
286+
"console": {
287+
"level": "DEBUG",
288+
"class": "logging.StreamHandler",
289+
"formatter": "plain",
321290
},
322-
'debug_console': {
323-
# Active only when DEBUG=True
324-
'level': 'DEBUG',
325-
'filters': ['require_debug_true'],
326-
'class': 'logging.StreamHandler',
327-
'formatter': 'plain',
291+
"debug_console": {
292+
"level": "DEBUG",
293+
"filters": ["require_debug_true"],
294+
"class": "logging.StreamHandler",
295+
"formatter": "plain",
328296
},
329-
'django.server': {
330-
'level': 'INFO',
331-
'class': 'logging.StreamHandler',
332-
'formatter': 'django.server',
297+
"django.server": {
298+
"level": "INFO",
299+
"class": "logging.StreamHandler",
300+
"formatter": "django.server",
333301
},
334-
'mail_admins': {
335-
'level': 'ERROR',
336-
'filters': [
337-
'require_debug_false',
338-
'skip_suspicious_operations', # custom
339-
'skip_unreadable_posts', # custom
302+
"mail_admins": {
303+
"level": "ERROR",
304+
"filters": [
305+
"require_debug_false",
306+
"skip_unreadable_posts",
340307
],
341-
'class': 'django.utils.log.AdminEmailHandler',
342-
'include_html': True, # non-default
343-
}
308+
"class": "django.utils.log.AdminEmailHandler",
309+
"include_html": True,
310+
},
344311
},
345-
#
346312
# All these are used by handlers
347-
'filters': {
348-
'require_debug_false': {
349-
'()': 'django.utils.log.RequireDebugFalse',
350-
},
351-
'require_debug_true': {
352-
'()': 'django.utils.log.RequireDebugTrue',
313+
"filters": {
314+
"require_debug_false": {
315+
"()": "django.utils.log.RequireDebugFalse",
353316
},
354-
# custom filter, function defined above:
355-
'skip_suspicious_operations': {
356-
'()': 'django.utils.log.CallbackFilter',
357-
'callback': skip_suspicious_operations,
317+
"require_debug_true": {
318+
"()": "django.utils.log.RequireDebugTrue",
358319
},
359320
# custom filter, function defined above:
360-
'skip_unreadable_posts': {
361-
'()': 'django.utils.log.CallbackFilter',
362-
'callback': skip_unreadable_post,
321+
"skip_unreadable_posts": {
322+
"()": "django.utils.log.CallbackFilter",
323+
"callback": skip_unreadable_post,
363324
},
364325
},
365-
# And finally the formatters
366-
'formatters': {
367-
'django.server': {
368-
'()': 'django.utils.log.ServerFormatter',
369-
'format': '[%(server_time)s] %(message)s',
326+
"formatters": {
327+
"django.server": {
328+
"()": "django.utils.log.ServerFormatter",
329+
"format": "[%(server_time)s] %(message)s",
370330
},
371-
'plain': {
372-
'style': '{',
373-
'format': '{levelname}: {name}:{lineno}: {message}',
331+
"plain": {
332+
"style": "{",
333+
"format": "{levelname}: {name}:{lineno}: {message}",
374334
},
375-
'json' : {
335+
"json": {
376336
"class": "ietf.utils.jsonlogger.DatatrackerJsonFormatter",
377337
"style": "{",
378-
"format": "{asctime}{levelname}{message}{name}{pathname}{lineno}{funcName}{process}",
379-
}
338+
"format": (
339+
"{asctime}{levelname}{message}{name}{pathname}{lineno}{funcName}"
340+
"{process}{status_code}"
341+
),
342+
},
380343
},
381344
}
382345

383-
# End logging
384-
# ------------------------------------------------------------------------
385-
386346

387347
X_FRAME_OPTIONS = 'SAMEORIGIN'
388348
CSRF_TRUSTED_ORIGINS = [

0 commit comments

Comments
 (0)