atexit handlers - getting the return code

Mike Hull mikehulluk at googlemail.com
Tue Sep 27 15:37:10 CEST 2011


Hi Giampaolo,
Sorry, I didn't explain very clearly.
I have a python file, 'simulation_logger.py', (given below).
Then, in my scripts, I add the following lines to the top,



#simulation1.py:
###################
from simulation_logger  import SimulationDecorator
SimulationDecorator.Init()

# Rest of the simulation script....

#####################

and at the end of the simulation, it should write the stdout/stderr,
the return code and any top level exception details into a database.
This is working except I can't work out how to get the return code
the script is going to return.
Any help would be gratefully appreciated,

Thanks!

Mike










# simulation_logger.py
########################

import atexit
import sys
import os
import cStringIO
import time
import traceback
import datetime
import inspect

class SimulationRunInfo(object):
 def __init__(self, script_name ):
    self.return_code = None
    self.time_taken = None
    self.time_out = None
    self.std_out = None
    self.std_err = None
    self.exception_details = None,None

    self.script_name = script_name



class IOStreamDistributor(object):
    def __init__(self, outputs):
        self.outputs = outputs

    def write(self,  *args, **kwargs):
        for op in self.outputs:
            op.write(*args, **kwargs)




class SimulationDecorator(object):

    start_time = None
    time_out = None
    is_initialised = False
    exception_details = None,None

    std_out = None
    std_err = None
    script_name = None





    @classmethod
    def exit_handler(cls, *args, **kwargs):
        print 'Exit Handler'
        print 'Args', args
        print 'KwArgs', kwargs

        info = SimulationRunInfo( cls.script_name)

        # Read and restore the StdOut/Err
        info.std_out = cls.std_out.getvalue()
        sys.stdout = sys.__stdout__
        info.std_err = cls.std_err.getvalue()
        sys.stderr = sys.__stderr__

        # Get the return value:
        info.return_code = 0

        # Get the timing:
        info.time_taken = int( time.time() - cls.start_time )

        # Has thier been an exception?
        info.exception_details = cls.exception_details
        if info.exception_details != (None,None):
          print 'Exception details', info.exception_details
          info.return_code = -1

        # Write to SimulationDataBase

        # Save the information to a database:
        SimulationDBWriter.write_to_database(info)


    @classmethod
    def top_level_exception_handler(cls, exception_type, exception,
traceback, *args):
        print 'TopLevel Exception Handler'
        cls.exception_details  = exception_type, exception, traceback

    @classmethod
    def Init(cls, time_out=None):
        assert not cls.is_initialised

        if 'MF_TIMEOUT' in os.environ:
            timeout = int( os.environ['MF_TIMEOUT'] )


        # Filename of the Simulation script
        cwd = os.getcwd()
        cls.script_name = os.path.join( cwd, traceback.extract_stack()
[0][0] )
        #cls.script_name = traceback.extract_stack()[0][2].
        #cls.script_name = inspect.stack()[-1][1]

        #Intercept StdOut and StdErr:
        cls.std_out = cStringIO.StringIO()
        sys.stdout = IOStreamDistributor( [cls.std_out, sys.stdout] )
        cls.std_err = cStringIO.StringIO()
        sys.stderr = IOStreamDistributor( [cls.std_err, sys.stderr] )

        # Set an exit handler and a top level exception-handler
        # Set a top level exception handler:
        atexit.register( cls.exit_handler )
        sys.excepthook = cls.top_level_exception_handler


        # Set a time-out alarm
        cls.start_time = time.time()
        cls.time_out = time_out




More information about the Python-list mailing list