Verbose to super verbose python Trace Debugging

Sometimes, verbose just isn't enough. There are a couple options:

1st level:

In your nuke home dir (assuming you haven't changed it, ~/.nuke on OSX and Linux - I don't know Windows), add or modify the init.py file by adding the line:

import callbacksTrace

This prints out every callback nuke makes. There are a lot of them!

 

2nd level (super verbose):

If you want to get tons more information that you'll probably ever need, but might just help you find or discover that one stupid thing that's been breaking everything, you can use this code to turn things up a notch:

In code below, in the doc section of traceit(), there are some env variables you can add before you launch nuke. Any one of these will do:

    setenv NUKE_TRACE_DEBUG call
setenv NUKE_TRACE_DEBUG line
setenv NUKE_TRACE_DEBUG return
setenv NUKE_TRACE_DEBUG exception
setenv NUKE_TRACE_DEBUG c_call
setenv NUKE_TRACE_DEBUG c_return
setenv NUKE_TRACE_DEBUG c_exception

Depending on what you set NUKE_TRACE_DEBUG to, python will return different amounts of information from the actual line of code to the call made, the return, or any exceptions.

 

To make all this debug relevant to Nuke, I've added the line: 

   if 'nuke' in name.lower():

to only capture nuke related processes. SInce all the code in our studio is in a package with "nuke" also in the package name, the trace also prints our internal python. Add or modify the 'if' at that stage to allow it to return more relevant information at your facility. It's waaaay too verbose otherwise, telling you every raw python call your code accesses.

To turn it back off, remove the env variable with 

unsetenv NUKE_TRACE_DEBUG
import os, sys

def traceit(frame, event, arg):
    """
    used by sys.settrace() to provide trace dumps for python apps
    from Andrew Dalke's blog at http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html
    Modified to only return 'nuke' specific code, else all things python would be spit out.
    This env var NUKE_TRACE_DEBUG can take on the values defined in
    http://docs.python.org/lib/debugger-hooks.html, ie: 
    'call', 'line', 'return', 'exception', 'c_call', 'c_return' and 'c_exception'. 
    Copy one of the below lines and paste into the shell you are launching nuke from:
    setenv NUKE_TRACE_DEBUG call
    setenv NUKE_TRACE_DEBUG line
    setenv NUKE_TRACE_DEBUG return
    setenv NUKE_TRACE_DEBUG exception
    setenv NUKE_TRACE_DEBUG c_call
    setenv NUKE_TRACE_DEBUG c_return
    setenv NUKE_TRACE_DEBUG c_exception
    unsetenv NUKE_TRACE_DEBUG  # to stop printing
    """
    if event == os.environ['NUKE_TRACE_DEBUG']:
        lineno = frame.f_lineno
        filename = ''
        if frame.f_globals.has_key("__file__"):
            filename = frame.f_globals["__file__"]
        if (filename.endswith(".pyc") or
            filename.endswith(".pyo")):
            filename = filename[:-1]
        name = frame.f_globals["__name__"]
        line = linecache.getline(filename, lineno)
        if 'nuke' in name.lower():
            sys.stderr.write("%s:%s: %s\n" % (name, lineno, line.rstrip()))
    sys.stderr.flush()
    return traceit
 
 
if os.environ.has_key('NUKE_TRACE_DEBUG'):
    import linecache
    if os.environ['NUKE_TRACE_DEBUG'] == '':
        os.environ['NUKE_TRACE_DEBUG'] = 'call'
    sys.settrace(traceit)