4

A common functionality that I would like to write a decorator for is the following:

in a django view, I have following code:

def view(request):
    try:
       # do stuff and return success case view response
       return render_to_response(...)
    except:
       # log the exception stack trace and return error case view response
       logger.error('...')
       return render_to_response('user friendly error message etc.')

I would like to extract the "try" except block to a decorator. So I wrote something like the following:

import logging.config
logging.config.fileConfig(LOGGING_CONFIG_FILE)
logger = logging.getLogger(__name__)   

def decorator(view):
    def inner(*args, **kwargs):
        try:            
            return view(*args, **kwargs)
        except:
            exception_traceback = traceback.format_exc(5)
            error_message = 'Exception:%s' % exception_traceback
            print 'Unexpected error occurred: %s' %(exception_traceback)
            logger.error( 'Unexpected error occurred: %s' %(exception_traceback))
            return render_to_response('error.json',
                              {
                                'message': 'Unexpected system error occured - please contact system administrator'
                              },
                              mimetype='text/plain')
    return inner

Assume that normally I return a json in case of success as well.

For some reason my logging message does not show up in the file. The "print" message in the except clause shows up in the console. If I use a logging message in the view itself, it shows up so the logging configuration is ok. I must be missing something simple if anyone can point that out, would appreciate it!

Thanx!

Posting the logging config file:

[loggers]
keys=root

[logger_root]
handlers=screen,file
level=DEBUG

[formatters]
keys=simple,complex

[formatter_simple]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

[formatter_complex]
format=%(asctime)s - %(levelname)s - %(module)s : %(lineno)d - %(message)s

[handlers]
keys=file,screen

[handler_file]
class=handlers.RotatingFileHandler
formatter=complex
level=DEBUG
args=('/tmp/rule150/logs/rule150.log','a',1000000,5)

[handler_screen]
class=StreamHandler
formatter=simple
level=INFO
args=(sys.stdout,)
serverman
  • 1,314
  • 5
  • 22
  • 39
  • I assume that the view function/method is contained in a other module and therefore uses an other logger instance? – Nicola Coretti Aug 18 '11 at 21:42
  • yes - the view is in a different module. – serverman Aug 18 '11 at 21:44
  • So the handler setup etc. can be differnt please post your logger config. How is your logging organized? (e.g. only the root logger has handlers attached) – Nicola Coretti Aug 18 '11 at 21:48
  • Hi Nicoreti, the same logger is used in both cases. I have verified that the same logging config is being used in both cases. – serverman Aug 18 '11 at 21:56
  • It can't be the same logger because you used __name__ therfore two different loggers will be created. Is the logger __name__ for the module which contains the decorator configured in the LOGGING_CONFIG_FILE. I think it must be a problem of the logging set up. – Nicola Coretti Aug 18 '11 at 22:10
  • Using a [context manager](http://docs.python.org/dev/py3k/reference/datamodel.html?highlight=data%20model#with-statement-context-managers) is probably more appropriate. – Evpok Aug 18 '11 at 22:14
  • If you don't mind post the names of the modules which contains the mentioned functions/methods and your logging config file. – Nicola Coretti Aug 18 '11 at 22:14
  • finding it very hard to post the config file - the module names are views.py and util.py. If I move the decorator function into the views module where I was using it - then it works - so it definitely has to do with different loggers. When I said the loggers are same - I meant they are both pointing to the same config file. – serverman Aug 18 '11 at 22:36
  • posted the logging config file in the edited question – serverman Aug 18 '11 at 23:07

1 Answers1

1

Don't call fileConfig in your views: do this in settings.py, as recommended in my answer to another question. Your view code should only contain the code to define the logger (as you already have it) as well as the logging calls themselves. Post your findings once you've made this change.

Also, don't post comments to your own questions. You should be able to edit your question to e.g. add the logging config file, and be able to format it better than you can in a comment.

Community
  • 1
  • 1
Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
  • Thanx Vinay - yes your answer works as you say. I would also recommend trying @stefano's reply to the same question if you are using python 1.3 – serverman Aug 18 '11 at 23:19