32
Best Practices for Django 1.6 TWO SCOOPS OF DJANGO Ch. 24: Logging: What's It For, Anyway? Ch. 25: Signals: Use Cases and Avoidance Techniques Michelle Leu @flywindy 2015/04/21

Django best practices for logging and signals

Embed Size (px)

Citation preview

Best Practices for Django 1.6

TWO SCOOPS OF DJANGO

Ch. 24: Logging: What's It For, Anyway? Ch. 25: Signals: Use Cases and Avoidance Techniques

Michelle Leu @flywindy 2015/04/21

ABOUT THIS BOOK• Best practices

• Django 1.6

• Not really for new comer

• Author:

• Daniel Greenfeld & Audrey Roy

• Django Packages 2

What's It For, Anyway?

CH. 24: LOGGING

3

LOGGING• Django uses Python’s builtin logging module to

perform system logging.

• Application Logs vs. Other Logs

• App logs: any log file containing data logged from your Python web application

• Why Bother With Logging?

• debug, tracking, security…

4

Log Catastrophes With CRITICAL

LOG LEVEL

Use the CRITICAL log level only when something catastrophic occurs that

requires urgent attention.

5

Log Production Errors With ERROR

LOG LEVEL

Use the ERROR log level whenever you need to log an error that is

worthy of being emailed to you or your site admins.

6

Log Production Errors With ERROR

LOG LEVEL

7

logger.error("Internal  Server  Error:  %s",            request.path,            exc_info=exc_info,            extra={                    "status_code":  500,                    "request":  request            }    )  

Log Lower-Priority Problems With WARNING

LOG LEVEL

This level is good for logging events that are unusual and potentially bad,

but not as bad as ERROR-level events.

8

Log Lower-Priority Problems With WARNING

LOG LEVEL

9

logger.warning("Forbidden  (%s):  %s",                                  REASON_NO_CSRF_COOKIE,                                  request.path,            extra={                    "status_code":  403,                    "request":  request,            }    )  

Log Useful State Information With INFO

LOG LEVEL

Use this level to log any details that may be particularly important when

analysis is needed.

10

Log Debug-Related Messages to DEBUG

LOG LEVEL

In development, we recommend using DEBUG and occasionally INFO

level logging wherever you’d consider throwing a print statement

into your code for debugging

11

LOG TRACEBACKS• Python’s logging module supports this:

• Logger.exception() automatically includes the traceback and logs at ERROR level.

• For other log levels, use the optional exc_info keyword argument.

12

ONE LOGGER PER MODULE• Whenever you use logging in another module,

don’t import and reuse a logger from elsewhere. Instead, define a new logger specific to the module.

• What this gives you is the ability to turn on and off only the specific loggers that you currently need.

13

LOG LOCALLY• Default settings file is configured to email ERROR

and higher log messages to whomever you list in ADMINS.

• Writing logs of level INFO and higher to rotating log files on disk.

14

Sentry

THIRD-PARTY TOOLS

Sentry is a modern error logging and aggregation platform.

The primary implementation is in Python, but it contains a full API for sending events from

any language, in any application.

15

SENTRY1. pip install raven

2. Django configuration

3. python manage.py raven test~demo~

16

#  settings.py  #  ...  

#  Set  your  DSN  value  RAVEN_CONFIG  =  {          'dsn':  'SENTRY_DSN',  }  

#  Add  raven  to  the  list  of  installed  apps  INSTALLED_APPS  =  INSTALLED_APPS  +  (          #  ...          'raven.contrib.django.raven_compat',  )

OTHER TIPS• Colorizing your log output helps you spot

important messages at a glance. Ex: logutils

• loggly.com (http://loggly.com/) simplifies log management and provides excellent query tools.

• PagerDuty (http://www.pagerduty.com/) alert you and your team repeatedly until you’ve taken action.

17

Don’t wait until it’s too late to add logging.

SUMMARY

You’ll be grateful for your logs if and when your site fails.

18

Use Cases and Avoidance Techniques

CH. 25: SIGNALS

19

DO NOT USE SIGNALS

20

DO NOT USE SIGNALS

21

Use signals as a last resort.

WHAT IS SIGNALS• Django includes a “signal dispatcher” which helps

allow decoupled applications get notified when actions occur elsewhere in the framework.

22

SenderReceiver

ReceiverReceiver

!

WHAT IS SIGNALS• Django provides a set of built-in signals. These

include some useful notifications: • django.db.models.signals.pre_save &

django.db.models.signals.post_save

• django.db.models.signals.m2m_changed

• django.core.signals.request_started & django.core.signals.request_finished

23

Use signals as a last resort.

WHY NOT?

• Signals are being dispatched everywhere and hopefully getting received somewhere.

• Not like Celery, Signals are synchronous and blocking.

24

WHEN TO USE• Your signal receiver needs to make changes to

more than one model.

• You want to dispatch the same signal from multiple apps and have them handled the same way by a common receiver.

• You want to invalidate a cache after a model save.

• You have an unusual scenario that needs a callback, and there’s no other way to handle it besides using a signal.

25

WHEN TO AVOID• The signal relates to one particular model and can

be moved into one of that model’s methods, possibly called by save().

• The signal can be replaced with a custom model manager method.

• The signal relates to a particular view and can be moved into that view.

26

AVOIDANCE TECHNIQUES

27

Using Custom Model Manager Methods Instead of Signals

Create Event

AVOIDANCE TECHNIQUES

28

Using Custom Model Manager Methods Instead of Signals

Create Event

\

29

#  events/managers.py    from  django.db  import  models        class  EventManager(models.Manager):                def  create_event(self,                            title,                            start,                            end,                            creator):                    event  =  self.model(title=title,                                            start=start,                                            end=end,                                            creator=creator)                    event.notify_admins()                    return  event

#  events/models.py    #  ...  from  model_utils.models  import  TimeStampedModel    from  .managers  import  EventManager        MSG  =  "{user}  submitted  a  new  event!"        class  Event(TimeStampedModel):                      #  ...          title  =  models.CharField(max_length=100)            #  ...                objects  =  EventManager()    

       def  notify_admins(self):                    #  create  the  subject                    creator  =  self.creator                    subject  =  MSG.format(user=creator.get_full_name())                        #  create  the  message                    message  =  """TITLE:  {title}                    START:  {start}                    END:  {end}""".format(title=self.title,                                                            start=self.start,                                                            end=self.end)                        #  Send  to  the  admins!                    mail_admins(subject=subject,                            message=message,                            fail_silently=False)

Instead of calling create(), we call a

create_event() method.

AVOIDANCE TECHNIQUES

30

• Validate Your Model Elsewhere

• If validating through a ModelForm, try overriding your model’s clean() method instead.

• Override Your Model’s Save or Delete Method Instead

REFERENCE• http://twoscoopspress.org/products/two-scoops-of-django-1-6

• https://docs.djangoproject.com/en/1.8/topics/logging/

• https://docs.python.org/3/library/logging.html

• https://app.getsentry.com/docs/platforms/django/

• http://raven.readthedocs.org/en/latest/integrations/django.html

• https://docs.djangoproject.com/en/1.8/topics/signals/

31

THANKS FOR YOUR LISTENING