SlideShare a Scribd company logo
1 of 47
Download to read offline
What the heck
 went wrong?


    Andy McKay
      andym on #django
    clearwind consulting
     andy@clearwind.ca
            @clearwind
debugging django
reporting errors
not a question of if...
development → production
development


use the dev. server
    python manage.py runserver
development


turn on debug
    DEBUG = True
development


assert False
development


      a print
 print "some debugging statement"
development


     a print
print "some debugging statement"
       print some_variable
    print type(some_variable)
there's a problem
development


           mod_wsgi
    IOError: sys.stdout access restricted by mod_wsgi

                 WSGIRestrictStdout Off
http://code.google.com/p/modwsgi/wiki/ApplicationIssues
logging


   http://www.flickr.com/photos/astro-dudes/1492818224/
development

http://docs.python.org/library/logging.html


import logging
logging.basicConfig(
  level = logging.DEBUG,
  format = '%(asctime)s %(levelname)s %(message)s',
)
development


import logging
log.debug("My brilliant debug message")
import logging
                  development
import logging.handlers



if getattr(settings, "LOG_FILENAME", None):

  logger = logging.getLogger("django")

  handler = logging.handlers.RotatingFileHandler(settings.LOG_FILENAME)

  formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")

  handler.setFormatter(formatter)

  logger.addHandler(handler)

else:

  # so that if you don't have LOG_FILENAME defined, don't blow up

  class NullHandler(logging.Handler):

    def emit(self, record):

        pass

  logging.getLogger("django").addHandler(NullHandler())
development


             pdb
http://docs.python.org/library/pdb.html
development
import pdb; pdb.set_trace()
Django version 1.2 pre-alpha, using settings 'test_profiler.settings'
Development server is running at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
> /mnt/hgfs/sandboxes/test_profiler/profiler/middleware.py(12)
process_response()
-> url = request.get_full_path()
(Pdb)
development

l: shows lines of code at your current point
n: execute the next line
s: step into
c: continue
q: quit
locals(): see what's in your current scope
development


pdb is essential
there's a problem
development


leave pdb in and your site...
development


werkzeug debugger
                     easy_install Werkzeug
 http://dev.pocoo.org/projects/werkzeug/wiki/UsingDebuggerWithDjango
development
#!/usr/bin/env python

from werkzeug import run_simple, DebuggedApplication
from django.core.handlers.wsgi import WSGIHandler

# This is only needed for Django versions < [7537]:
def null_technical_500_response(request, exc_type, exc_value, tb):
  raise exc_type, exc_value, tb

from django.views import debug
debug.technical_500_response = null_technical_500_response

if __name__ == '__main__':
   run_simple('localhost', 8080,
     DebuggedApplication(WSGIHandler(), True))
development
development


 unit tests
development


django-debug-toolbar
 http://github.com/robhudson/django-debug-toolbar/tree/master
development


  rocks!
development
MIDDLEWARE_CLASSES = (
[...snip]
   'debug_toolbar.middleware.DebugToolbarMiddleware',
)


INSTALLED_APPS = (
[...snip]
   'debug_toolbar'
)


INTERNAL_IPS = ('127.0.0.1',)
development
development


cheaper and easier
staging


continuous integration
 e.g: Teamcity, Integrity, buildbot, Tinderbox ... others are available
staging


   custom test runner
TeamCity: http://bit.ly/geAA

[..snip]
if hasTeamcity and underTeamcity():
   result = TeamcityTestRunner().run(suite)
else:
   result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
staging
production


       varies upon server
mod_wsgi → http://code.google.com/p/modwsgi/wiki/DebuggingTechniques

mod_python → http://yenaer.com/blog/2008/jan/12/debugging-modpython-scripts-apache-and-pdb
production


                    errors
http://docs.djangoproject.com/en/dev/howto/error-reporting/
production


               404 and 500
(has to be in root url.conf)
handler404 = 'mysite.views.custom_404'
handler500 = 'mysite.views.custom_500'


http://docs.djangoproject.com/en/dev/topics/http/views/
production


                     emailed
DEBUG = False
ADMIN = ( ('Andy', 'andy@clearwind.ca'), )
production
Traceback (most recent call last):

 File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py", line 86, in get_response
   response = callback(request, *callback_args, **callback_kwargs)

 File "/usr/lib/python2.5/site-packages/django/contrib/admin/sites.py", line 154, in root
   return shortcut(request, *url.split('/')[1:])

 File "/usr/lib/python2.5/site-packages/django/contrib/contenttypes/views.py", line 57, in shortcut
   object_domain = Site.objects.get_current().domain

 File "/usr/lib/python2.5/site-packages/django/contrib/sites/models.py", line 22, in get_current
   current_site = self.get(pk=sid)

 File "/usr/lib/python2.5/site-packages/django/db/models/manager.py", line 93, in get
   return self.get_query_set().get(*args, **kwargs)

 File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 298, in get
   num = len(clone)

 File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 154, in __len__
   self._result_cache = list(self.iterator())

 File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 269, in iterator
   for row in self.query.results_iter():

 File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py", line 206, in results_iter
   for rows in self.execute_sql(MULTI):

 File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py", line 1723, in execute_sql
   cursor.execute(sql, params)

ProgrammingError: relation "django_site" does not exist



<WSGIRequest
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{'__utma': '90285002.4337325975145378300.1232037035.1233126418.1233185854.12',
'__utmb': '90285002.2.10.1233185854',
'__utmc': '90285002',
'__utmz': '90285002.1232037035.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
'sessionid': 'b139e8d00ed433fb5e6dff50a3956036'},
META:{'DOCUMENT_ROOT': '/htdocs',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
'HTTP_ACCEPT_LANGUAGE': 'en-us',
'HTTP_CONNECTION': 'keep-alive',
'HTTP_COOKIE': '__utmz=90285002.1232037035.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=90285002.4337325975145378300.1232037035.1233126418.1233185854.12; __utmc=90285002;
__utmb=90285002.2.10.1233185854; sessionid=b139e8d00ed433fb5e6dff50a3956036',
'HTTP_HOST': 'www.areciboapp.com',
'HTTP_REFERER': 'http://www.areciboapp.com/arecibo-admin/singleblog/post/7/',
'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1',
'PATH': '/usr/local/bin:/usr/bin:/bin',
'PATH_INFO': u'/arecibo-admin/r/18/7/',
'PATH_TRANSLATED': '/var/www/arecibo/django.wsgi/arecibo-admin/r/18/7/',
'QUERY_STRING': '',
'REMOTE_ADDR': '70.79.161.59',
'REMOTE_PORT': '63593',
'REQUEST_METHOD': 'GET',
'REQUEST_URI': '/arecibo-admin/r/18/7/',
'SCRIPT_FILENAME': '/var/www/arecibo/django.wsgi',
'SCRIPT_NAME': u'',
'SERVER_ADDR': '216.139.224.26',
'SERVER_ADMIN': '[no address given]',
'SERVER_NAME': 'www.areciboapp.com',
'SERVER_PORT': '80',
'SERVER_PROTOCOL': 'HTTP/1.1',
'SERVER_SIGNATURE': '<address>Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.4.6 mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_wsgi/1.3 Server at www.areciboapp.com Port 80</address>n',
'SERVER_SOFTWARE': 'Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.4.6 mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_wsgi/1.3',
'mod_wsgi.application_group': 'areciboapp.com|',
'mod_wsgi.callable_object': 'application',
'mod_wsgi.case_sensitivity': '1',
'mod_wsgi.listener_host': '',
'mod_wsgi.listener_port': '80',
'mod_wsgi.output_buffering': '0',
'mod_wsgi.process_group': 'www-data',
'mod_wsgi.reload_mechanism': '0',
'mod_wsgi.script_reloading': '1',
'wsgi.errors': <mod_wsgi.Log object at 0x8c0d620>,
'wsgi.input': <mod_wsgi.Input object at 0xb469958>,
'wsgi.multiprocess': True,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)}>
production


           arecibo
          http://www.areciboapp.com/
http://www.areciboapp.com/listener/docs/django/
production


                 get account
Install Arecibo library
ARECIBO_PUBLIC_ACCOUNT_NUMBER = "xxxx"
production


   add to error
from arecibo.wrapper import post

def application_error(request):
  t = loader.get_template('500.html')
  uid = post(request, 500)
  c = RequestContext(request, {"uid": uid})
  return HttpResponse(t.render(c), status=500)
production
honourable mentions


   django-db-log
      http://code.google.com/p/django-db-log/
  "Logs Django exceptions to your database handler."
honourable mentions


 django-sql-profiler
       http://code.google.com/p/django-sql-profiler

 "Records every SQL query in Django in the database so that
           you can find slow queries in your site."
The error message is the Truth.
The error message is God.
James Bennett, earlier today.


                                                     Andy McKay
                                                        clearwind consulting
                                                         andy@clearwind.ca
                                                                  @clearwind
                                slides will be going on http://djangozen.com

More Related Content

What's hot

td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
tutorialsruby
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at Nackademin
Robert Nyman
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
Michelangelo van Dam
 

What's hot (20)

Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
 
Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
 
¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at Nackademin
 
Ant build tool2
Ant   build tool2Ant   build tool2
Ant build tool2
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
OpenCms Days 2014 - User Generated Content in OpenCms 9.5
OpenCms Days 2014 - User Generated Content in OpenCms 9.5OpenCms Days 2014 - User Generated Content in OpenCms 9.5
OpenCms Days 2014 - User Generated Content in OpenCms 9.5
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
jQuery Internals + Cool Stuff
jQuery Internals + Cool StuffjQuery Internals + Cool Stuff
jQuery Internals + Cool Stuff
 
Visual Component Testing -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
Visual Component Testing  -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...Visual Component Testing  -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
Visual Component Testing -- w/ Gil Tayar (Applitools) and Gleb Bahmutov (Cyp...
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
YUI 3
YUI 3YUI 3
YUI 3
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
Moustamera
MoustameraMoustamera
Moustamera
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Groovy And Grails JUG Padova
Groovy And Grails JUG PadovaGroovy And Grails JUG Padova
Groovy And Grails JUG Padova
 
Making your Angular.js Application accessible
Making your Angular.js Application accessibleMaking your Angular.js Application accessible
Making your Angular.js Application accessible
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 

Viewers also liked (10)

DJH Update 22.april 2010
DJH Update 22.april 2010DJH Update 22.april 2010
DJH Update 22.april 2010
 
You've done the Django Tutorial, what next?
You've done the Django Tutorial, what next?You've done the Django Tutorial, what next?
You've done the Django Tutorial, what next?
 
Sociale medier - DJH Update 291010
Sociale medier - DJH Update  291010Sociale medier - DJH Update  291010
Sociale medier - DJH Update 291010
 
Update 231110
Update   231110Update   231110
Update 231110
 
Headstart 191109
Headstart 191109Headstart 191109
Headstart 191109
 
26exp Group
26exp Group26exp Group
26exp Group
 
It forum 130111
It forum 130111It forum 130111
It forum 130111
 
Fighting Malnutrition with SMS and Django
Fighting Malnutrition with SMS and DjangoFighting Malnutrition with SMS and Django
Fighting Malnutrition with SMS and Django
 
Anatomy of a Large Django site
Anatomy of a Large Django siteAnatomy of a Large Django site
Anatomy of a Large Django site
 
Twitter Whitepaper
Twitter   WhitepaperTwitter   Whitepaper
Twitter Whitepaper
 

Similar to What the heck went wrong?

gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
George Nguyen
 
gDayX - Advanced angularjs
gDayX - Advanced angularjsgDayX - Advanced angularjs
gDayX - Advanced angularjs
gdgvietnam
 

Similar to What the heck went wrong? (20)

End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
 
gDayX - Advanced angularjs
gDayX - Advanced angularjsgDayX - Advanced angularjs
gDayX - Advanced angularjs
 
Nicolas Embleton, Advanced Angular JS
Nicolas Embleton, Advanced Angular JSNicolas Embleton, Advanced Angular JS
Nicolas Embleton, Advanced Angular JS
 
Continuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukContinuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin Stachniuk
 
20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final20141002 delapsley-socalangularjs-final
20141002 delapsley-socalangularjs-final
 
Aug penguin16
Aug penguin16Aug penguin16
Aug penguin16
 
Django - Know Your Namespace: Middleware
Django - Know Your Namespace: MiddlewareDjango - Know Your Namespace: Middleware
Django - Know Your Namespace: Middleware
 
Advanced debugging  techniques in different environments
Advanced debugging  techniques in different environmentsAdvanced debugging  techniques in different environments
Advanced debugging  techniques in different environments
 
“warpdrive”, making Python web application deployment magically easy.
“warpdrive”, making Python web application deployment magically easy.“warpdrive”, making Python web application deployment magically easy.
“warpdrive”, making Python web application deployment magically easy.
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
React django
React djangoReact django
React django
 
Dgeni documentation generator
Dgeni   documentation generatorDgeni   documentation generator
Dgeni documentation generator
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
 
How to Webpack your Django!
How to Webpack your Django!How to Webpack your Django!
How to Webpack your Django!
 
Application Security from the Inside - OWASP
Application Security from the Inside - OWASPApplication Security from the Inside - OWASP
Application Security from the Inside - OWASP
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Advanced iOS Debbuging (Reloaded)
Advanced iOS Debbuging (Reloaded)Advanced iOS Debbuging (Reloaded)
Advanced iOS Debbuging (Reloaded)
 
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFGStHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
StHack 2014 - Mario "@0x6D6172696F" Heiderich - JSMVCOMFG
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 

What the heck went wrong?

  • 1. What the heck went wrong? Andy McKay andym on #django clearwind consulting andy@clearwind.ca @clearwind
  • 4. not a question of if...
  • 6. development use the dev. server python manage.py runserver
  • 9. development a print print "some debugging statement"
  • 10. development a print print "some debugging statement" print some_variable print type(some_variable)
  • 12. development mod_wsgi IOError: sys.stdout access restricted by mod_wsgi WSGIRestrictStdout Off http://code.google.com/p/modwsgi/wiki/ApplicationIssues
  • 13. logging http://www.flickr.com/photos/astro-dudes/1492818224/
  • 14. development http://docs.python.org/library/logging.html import logging logging.basicConfig( level = logging.DEBUG, format = '%(asctime)s %(levelname)s %(message)s', )
  • 16. import logging development import logging.handlers if getattr(settings, "LOG_FILENAME", None): logger = logging.getLogger("django") handler = logging.handlers.RotatingFileHandler(settings.LOG_FILENAME) formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) else: # so that if you don't have LOG_FILENAME defined, don't blow up class NullHandler(logging.Handler): def emit(self, record): pass logging.getLogger("django").addHandler(NullHandler())
  • 17. development pdb http://docs.python.org/library/pdb.html
  • 18. development import pdb; pdb.set_trace() Django version 1.2 pre-alpha, using settings 'test_profiler.settings' Development server is running at http://0.0.0.0:8000/ Quit the server with CONTROL-C. > /mnt/hgfs/sandboxes/test_profiler/profiler/middleware.py(12) process_response() -> url = request.get_full_path() (Pdb)
  • 19. development l: shows lines of code at your current point n: execute the next line s: step into c: continue q: quit locals(): see what's in your current scope
  • 22. development leave pdb in and your site...
  • 23.
  • 24. development werkzeug debugger easy_install Werkzeug http://dev.pocoo.org/projects/werkzeug/wiki/UsingDebuggerWithDjango
  • 25. development #!/usr/bin/env python from werkzeug import run_simple, DebuggedApplication from django.core.handlers.wsgi import WSGIHandler # This is only needed for Django versions < [7537]: def null_technical_500_response(request, exc_type, exc_value, tb): raise exc_type, exc_value, tb from django.views import debug debug.technical_500_response = null_technical_500_response if __name__ == '__main__': run_simple('localhost', 8080, DebuggedApplication(WSGIHandler(), True))
  • 30. development MIDDLEWARE_CLASSES = ( [...snip] 'debug_toolbar.middleware.DebugToolbarMiddleware', ) INSTALLED_APPS = ( [...snip] 'debug_toolbar' ) INTERNAL_IPS = ('127.0.0.1',)
  • 33. staging continuous integration e.g: Teamcity, Integrity, buildbot, Tinderbox ... others are available
  • 34. staging custom test runner TeamCity: http://bit.ly/geAA [..snip] if hasTeamcity and underTeamcity(): result = TeamcityTestRunner().run(suite) else: result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
  • 36. production varies upon server mod_wsgi → http://code.google.com/p/modwsgi/wiki/DebuggingTechniques mod_python → http://yenaer.com/blog/2008/jan/12/debugging-modpython-scripts-apache-and-pdb
  • 37. production errors http://docs.djangoproject.com/en/dev/howto/error-reporting/
  • 38. production 404 and 500 (has to be in root url.conf) handler404 = 'mysite.views.custom_404' handler500 = 'mysite.views.custom_500' http://docs.djangoproject.com/en/dev/topics/http/views/
  • 39. production emailed DEBUG = False ADMIN = ( ('Andy', 'andy@clearwind.ca'), )
  • 40. production Traceback (most recent call last):  File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py", line 86, in get_response    response = callback(request, *callback_args, **callback_kwargs)  File "/usr/lib/python2.5/site-packages/django/contrib/admin/sites.py", line 154, in root    return shortcut(request, *url.split('/')[1:])  File "/usr/lib/python2.5/site-packages/django/contrib/contenttypes/views.py", line 57, in shortcut    object_domain = Site.objects.get_current().domain  File "/usr/lib/python2.5/site-packages/django/contrib/sites/models.py", line 22, in get_current    current_site = self.get(pk=sid)  File "/usr/lib/python2.5/site-packages/django/db/models/manager.py", line 93, in get    return self.get_query_set().get(*args, **kwargs)  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 298, in get    num = len(clone)  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 154, in __len__    self._result_cache = list(self.iterator())  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 269, in iterator    for row in self.query.results_iter():  File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py", line 206, in results_iter    for rows in self.execute_sql(MULTI):  File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py", line 1723, in execute_sql    cursor.execute(sql, params) ProgrammingError: relation "django_site" does not exist <WSGIRequest GET:<QueryDict: {}>, POST:<QueryDict: {}>, COOKIES:{'__utma': '90285002.4337325975145378300.1232037035.1233126418.1233185854.12', '__utmb': '90285002.2.10.1233185854', '__utmc': '90285002', '__utmz': '90285002.1232037035.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)', 'sessionid': 'b139e8d00ed433fb5e6dff50a3956036'}, META:{'DOCUMENT_ROOT': '/htdocs', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTP_ACCEPT': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-us', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': '__utmz=90285002.1232037035.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=90285002.4337325975145378300.1232037035.1233126418.1233185854.12; __utmc=90285002; __utmb=90285002.2.10.1233185854; sessionid=b139e8d00ed433fb5e6dff50a3956036', 'HTTP_HOST': 'www.areciboapp.com', 'HTTP_REFERER': 'http://www.areciboapp.com/arecibo-admin/singleblog/post/7/', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1', 'PATH': '/usr/local/bin:/usr/bin:/bin', 'PATH_INFO': u'/arecibo-admin/r/18/7/', 'PATH_TRANSLATED': '/var/www/arecibo/django.wsgi/arecibo-admin/r/18/7/', 'QUERY_STRING': '', 'REMOTE_ADDR': '70.79.161.59', 'REMOTE_PORT': '63593', 'REQUEST_METHOD': 'GET', 'REQUEST_URI': '/arecibo-admin/r/18/7/', 'SCRIPT_FILENAME': '/var/www/arecibo/django.wsgi', 'SCRIPT_NAME': u'', 'SERVER_ADDR': '216.139.224.26', 'SERVER_ADMIN': '[no address given]', 'SERVER_NAME': 'www.areciboapp.com', 'SERVER_PORT': '80', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SIGNATURE': '<address>Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.4.6 mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_wsgi/1.3 Server at www.areciboapp.com Port 80</address>n', 'SERVER_SOFTWARE': 'Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.4.6 mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_wsgi/1.3', 'mod_wsgi.application_group': 'areciboapp.com|', 'mod_wsgi.callable_object': 'application', 'mod_wsgi.case_sensitivity': '1', 'mod_wsgi.listener_host': '', 'mod_wsgi.listener_port': '80', 'mod_wsgi.output_buffering': '0', 'mod_wsgi.process_group': 'www-data', 'mod_wsgi.reload_mechanism': '0', 'mod_wsgi.script_reloading': '1', 'wsgi.errors': <mod_wsgi.Log object at 0x8c0d620>, 'wsgi.input': <mod_wsgi.Input object at 0xb469958>, 'wsgi.multiprocess': True, 'wsgi.multithread': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.version': (1, 0)}>
  • 41. production arecibo http://www.areciboapp.com/ http://www.areciboapp.com/listener/docs/django/
  • 42. production get account Install Arecibo library ARECIBO_PUBLIC_ACCOUNT_NUMBER = "xxxx"
  • 43. production add to error from arecibo.wrapper import post def application_error(request): t = loader.get_template('500.html') uid = post(request, 500) c = RequestContext(request, {"uid": uid}) return HttpResponse(t.render(c), status=500)
  • 45. honourable mentions django-db-log http://code.google.com/p/django-db-log/ "Logs Django exceptions to your database handler."
  • 46. honourable mentions django-sql-profiler http://code.google.com/p/django-sql-profiler "Records every SQL query in Django in the database so that you can find slow queries in your site."
  • 47. The error message is the Truth. The error message is God. James Bennett, earlier today. Andy McKay clearwind consulting andy@clearwind.ca @clearwind slides will be going on http://djangozen.com