Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python trace module - Trace lines as they are executed, but save to file, rather than stdout

I want to trace the lines of a python script as they are executed. However the programme I use needs to print things to stdout. The trace option to the python trace module prints them to stdout. Is there anwyay to tell it to not print them to stdout, but instead save them to a file? I tried setting the outfile parameter, but it doesn't stop the printing of trace lines.

like image 467
Amandasaurus Avatar asked Nov 26 '10 15:11

Amandasaurus


2 Answers

You could copy the trace module code, and make a few changes to get it to write its output to a file of your choosing. There are five print statements between lines 600 and 650 that are the ones you want to change. Since you don't need to make it too pretty, you can add this to the very end of the file:

my_out_file = open("/home/mytrace.txt", "w")

and change the print statements so this:

print "%s(%d): %s" % (bname, lineno,
                      linecache.getline(filename, lineno)),

becomes this:

print >>my_out_file, "%s(%d): %s" % (bname, lineno,
                      linecache.getline(filename, lineno)),
like image 135
Ned Batchelder Avatar answered Dec 13 '22 02:12

Ned Batchelder


As per the docs of trace module, the outfile is only used to write updated count information.

  • http://docs.python.org/library/trace.html

Trace module will continue to print the trace information to stdout.

For a manual tracing, if there is an entry function, I have used sys.settrace to do the work of tracing call flows. It can be extended to trace line by line execution. You can always file the information to a file rather than print it to stdout.

  • http://docs.python.org/library/sys.html

A simple structure is

import sys
import os
import linecache

trace_depth = 0

def trace(f):

    def globaltrace(frame, why, arg):
        global trace_depth
        if why == "call":
            # function call event , extract information
            .....
            pass

            trace_depth = trace_depth + 1
        return None

    def localtrace(frame, why, arg):
        global trace_depth
        if why == "line":
            # line execution event
            pass
        elif why == "return":
            trace_depth = trace_depth - 1
            # function return event
        return localtrace

    def _f(*args, **kwds):
        sys.settrace(globaltrace)
        result = f(*args, **kwds)
        sys.settrace(None)
        return result

    return _f

globaltrace and localtrace are callback functions that are called with the event - "why"

say for event when a function is called, you can extract the information from the frame details.

if why == "call":
    # Parent frame details
    p_func = frame.f_back.f_code.co_name
    p_file = frame.f_back.f_code.co_filename
    p_lineinfo = frame.f_back.f_lineno

I have posted the full details here.

like image 33
pyfunc Avatar answered Dec 13 '22 01:12

pyfunc