Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Logging in Django
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
100
Other Decks in Programming
See All in Programming
SlackアプリとLambdaの 連携を構築した話
pawn_4_s
1
110
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
900
プロポーザルを書いてもらう
pvcresin
0
480
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
320
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
400
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
210
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
380
Lean は証明の正しさを確認するためだけのツールって思ってませんか?
inoueasei
1
150
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
250
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
790
React本体のコードリーディング
high_g_engineer
1
140
Featured
See All Featured
Between Models and Reality
mayunak
4
390
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
390
The World Runs on Bad Software
bkeepers
PRO
72
12k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
Claude Code のすすめ
schroneko
67
230k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
410
Being A Developer After 40
akosma
91
590k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
560
Making the Leap to Tech Lead
cromwellryan
135
10k
How to make the Groovebox
asonas
2
2.3k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
It's Worth the Effort
3n
188
29k
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')