Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Logging in Django
Search
Jakh Daven
March 21, 2013
Programming
15k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Logging in Django
Jakh Daven
March 21, 2013
More Decks by Jakh Daven
See All by Jakh Daven
Developing Ubuntu Apps for fun and profit
tuxcanfly
0
110
Other Decks in Programming
See All in Programming
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
33
14k
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
120
Are APIs Still Relevant in the AI Era?
soyuka
0
400
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
270
Webの地図
yosuke_furukawa
PRO
6
5k
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
390
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
AWSに止められる覚悟してますか?
morizo_1984
2
500
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
150
速習iPhone Duo対応
yuukiw00w
2
930
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
130
Featured
See All Featured
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
550
Code Review Best Practice
trishagee
74
20k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
310
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
560
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
260
Color Theory Basics | Prateek | Gurzu
gurzu
1
480
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
450
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Utilizing Notion as your number one productivity tool
mfonobong
4
610
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
410
ラッコキーワード サービス紹介資料
rakko
1
5.1M
Transcript
Logging in Django Javed Khan @tuxcanfly
Why bother • Archive of events • Hints for debugging
• Reproducing errors • Statistical Analysis
To log or not to log • Convenient message •
State variables • logger.debug(“details, details”) • logger.info(“Something wonderful is about to happen...”) • logger.warn(“I have a bad feeling about this”) • logger.error(“oops!”) • logger.critical(“oh no!”)
Teh codez from django.utils.log import getLogger logger = getLogger('django.request') if
request.method not in request_method_list: logger.warning('Method Not Allowed (%s): %s', request. method, request.path, extra={ 'status_code': 405, 'request': request } )
Terminology • formatters • filters • handlers • loggers
Log levels • debug • info • warning • error
• critical Other methods: • logger.log • logger.exception
Configuration - Dictconfig { 'version': 1, 'disable_existing_loggers': False, 'formatters': {
'standard': { 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s' }, }, 'handlers': { 'default': { 'level':'INFO', 'class':'logging.StreamHandler', }, }, 'loggers': { '': { 'handlers': ['default'], 'level': 'INFO', 'propagate': True }, 'django.request': { 'handlers': ['default'], 'level': 'WARN', 'propagate': False }, } }
Configuration - Dictconfig formatters: 'formatters': { 'verbose': { 'format': '%(levelname)s
%(asctime)s %(module)s % (process)d %(thread)d %(message)s' }, 'simple': { 'format': '%(levelname)s %(message)s' }, }, asctime - 'Sun Jun 20 23:21:05 1993'.
Configuration - Dictconfig filters: 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse',
} }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' } }, class RequireDebugFalse(logging.Filter): def filter(self, record): return not settings.DEBUG
Configuration - Dictconfig handlers: 'handlers': { 'null': { 'level': 'DEBUG',
'class': 'django.utils.log.NullHandler', }, 'console':{ 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'filters': ['special'] } },
Configuration - Dictconfig handlers: • logging.handlers.RotatingFileHandler • logging.handlers.TimedRotatingFileHandler • logging.handlers.SMTPHandler
• logging.handlers.HTTPHandler
Configuration - Dictconfig loggers: 'loggers': { 'django': { 'handlers': ['null'],
'level': 'INFO', }, 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, 'foo.bar: { 'handlers': ['console', 'mail_admins'], 'level': 'INFO', 'filters': ['special'] } }
Common uses - debug sql 'handlers': { 'console': { 'level':
'DEBUG', 'class': 'logging.StreamHandler' } }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': True, }, }
Common uses - filter sql 'filters': { 'sql_inserts': { '()':
'django.utils.log.CallbackFilter', 'callback': lambda x: 'INSERT' in x.msg } }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': True, 'filters': ['sql_inserts'], }, }
Bonus Custom log levels: APOCALYPSE = 55 logging.addLevelName(APOCALYPSE, "APOCALYPSE") logger.log(APOCALYPSE,
"The end.")
Gotchas Circular import in Django < 1.5 settings.py: ... 'handlers':
{ 'default': { 'level':'INFO', 'class':'foo.bar.FooBarHandler', }, }, ... foo/bar.py: from django.conf import settings class FooBarHandler(object): ...
Gotchas Exception handler leaks secrets from django.views.decorators.debug import sensitive_variables, sensitive_post_parameters
@sensitive_post_parameters('password', 'credit_card_number') @sensitive_variables('password', 'credit_card_number') def my_super_secret_view(request): password = request.POST['password'] credit_card_number = request.POST['credit_card_number'] ... ---------- DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter' SafeExceptionReporterFilter HIDDEN_SETTINGS = re.compile ('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATURE')